wsp_caps.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:6k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /* wsp_caps.c - implement interface to WSP capability negotiation
  2.  *
  3.  * Richard Braakman
  4.  */
  5. #include "gwlib/gwlib.h"
  6. #include "wsp_caps.h"
  7. static void wsp_cap_destroy_item(void *cap) {
  8. wsp_cap_destroy(cap);
  9. }
  10. Capability *wsp_cap_create(int id, Octstr *name, Octstr *data) {
  11. Capability *new_cap;
  12. new_cap = gw_malloc(sizeof(*new_cap));
  13. new_cap->id = id;
  14. new_cap->name = name;
  15. new_cap->data = data;
  16. new_cap->accept = 0;
  17. return new_cap;
  18. }
  19. void wsp_cap_destroy(Capability *cap) {
  20. if (cap == NULL)
  21. return;
  22. octstr_destroy(cap->name);
  23. octstr_destroy(cap->data);
  24. gw_free(cap);
  25. }
  26. void wsp_cap_dump(Capability *cap) {
  27. debug("wsp", 0, "Dumping capability at %p:", cap);
  28. if (cap) {
  29. debug("wsp", 0, " id = %d", cap->id);
  30. debug("wsp", 0, " name:");
  31. octstr_dump(cap->name, 1);
  32. debug("wsp", 0, " data:");
  33. octstr_dump(cap->data, 1);
  34. if (cap->data == NULL)
  35. debug("wsp", 0, " accept: %d", cap->accept);
  36. }
  37. debug("wsp", 0, "Capability dump ends.");
  38. }
  39. void wsp_cap_dump_list(List *caps_list) {
  40. long i;
  41. if (caps_list == NULL) {
  42. debug("wsp", 0, "NULL capability list");
  43. return;
  44. }
  45. debug("wsp", 0, "Dumping capability list at %p, length %ld",
  46. caps_list, list_len(caps_list));
  47. for (i = 0; i < list_len(caps_list); i++) {
  48. wsp_cap_dump(list_get(caps_list, i));
  49. }
  50. debug("wsp", 0, "End of capability list dump");
  51. }
  52. void wsp_cap_destroy_list(List *caps_list) {
  53. list_destroy(caps_list, wsp_cap_destroy_item);
  54. }
  55. List *wsp_cap_duplicate_list(List *caps_list) {
  56. Capability *cap;
  57. List *new_list;
  58. long i;
  59. new_list = list_create();
  60. if (caps_list == NULL)
  61. return new_list;
  62. for (i = 0; i < list_len(caps_list); i++) {
  63. cap = list_get(caps_list, i);
  64. list_append(new_list, wsp_cap_duplicate(cap));
  65. }
  66. return new_list;
  67. };
  68. Capability *wsp_cap_duplicate(Capability *cap) {
  69. Capability *new_cap;
  70. if (!cap)
  71. return NULL;
  72. new_cap = wsp_cap_create(cap->id,
  73. octstr_duplicate(cap->name),
  74. octstr_duplicate(cap->data));
  75. new_cap->accept = cap->accept;
  76. return new_cap;
  77. }
  78. List *wsp_cap_unpack_list(Octstr *caps) {
  79. List *caps_list;
  80. long pos, capslen;
  81. caps_list = list_create();
  82. if (caps == NULL)
  83. return caps_list;
  84. capslen = octstr_len(caps);
  85. pos = 0;
  86. while (pos < capslen) {
  87. unsigned long length;
  88. int id;
  89. Octstr *name;
  90. Octstr *data;
  91. pos = octstr_extract_uintvar(caps, &length, pos);
  92. if (pos < 0 || length == 0)
  93. goto error;
  94. id = octstr_get_char(caps, pos);
  95. if (id >= 0x80) {
  96. id &= 0x7f; /* It's encoded as a short-integer */
  97. name = NULL;
  98. data = octstr_copy(caps, pos + 1, length - 1);
  99. } else {
  100. long nullpos;
  101. id = -1;  /* It's encoded as token-text */
  102. nullpos = octstr_search_char(caps, 0, pos);
  103. if (nullpos < 0)
  104. goto error;
  105. name = octstr_copy(caps, pos, nullpos - pos);
  106. data = octstr_copy(caps, nullpos + 1,
  107. length - (nullpos + 1 - pos));
  108. }
  109. list_append(caps_list, wsp_cap_create(id, name, data));
  110. pos += length;
  111. }
  112. return caps_list;
  113. error:
  114. warning(0, "WSP: Error unpacking capabilities");
  115. return caps_list;
  116. }
  117. Octstr *wsp_cap_pack_list(List *caps_list) {
  118. Octstr *result;
  119. Capability *cap;
  120. long i, len;
  121. result = octstr_create("");
  122. len = list_len(caps_list);
  123. for (i = 0; i < len; i++) {
  124. long datalen;
  125. cap = list_get(caps_list, i);
  126. datalen = 0;
  127. if (cap->data)
  128. datalen = octstr_len(cap->data);
  129. if (datalen == 0 && cap->accept)
  130. continue;
  131. if (cap->name) {
  132. if (octstr_get_char(cap->name, 0) >= 0x80 ||
  133.     octstr_search_char(cap->name, 0, 0) >= 0) {
  134. error(0, "WSP: Bad capability.");
  135. wsp_cap_dump(cap);
  136. continue;
  137. }
  138. /* Add length */
  139. octstr_append_uintvar(result,
  140. octstr_len(cap->name) + 1 + datalen);
  141. /* Add identifier */
  142. octstr_append(result, cap->name);
  143. octstr_append_char(result, 0);
  144. } else {
  145. if (cap->id >= 0x80 || cap->id < 0) {
  146. error(0, "WSP: Bad capability.");
  147. wsp_cap_dump(cap);
  148. continue;
  149. }
  150. /* Add length */
  151. octstr_append_uintvar(result, 1 + datalen);
  152. /* Add identifier */
  153. octstr_append_char(result, 0x80 | cap->id);
  154. }
  155. /* Add payload, if any */
  156. if (cap->data) {
  157. octstr_append(result, cap->data);
  158. }
  159. }
  160. return result;
  161. }
  162. static int wsp_cap_get_data(List *caps_list, int id, Octstr *name,
  163. Octstr **data) {
  164. long i, len;
  165. Capability *cap;
  166. int found;
  167. len = list_len(caps_list);
  168. found = 0;
  169. *data = NULL;
  170. for (i = 0; i < len; i++) {
  171. cap = list_get(caps_list, i);
  172. if ((name && cap->name 
  173.      && octstr_compare(name, cap->name) == 0)
  174.     || (!name && cap->id == id)) {
  175. if (!found)
  176. *data = cap->data;
  177. found++;
  178. }
  179. }
  180. return found;
  181. }
  182. int wsp_cap_count(List *caps_list, int id, Octstr *name) {
  183. Octstr *data;
  184. return wsp_cap_get_data(caps_list, id, name, &data);
  185. }
  186. int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu) {
  187. Octstr *data;
  188. int found;
  189. found = wsp_cap_get_data(caps_list, WSP_CAPS_CLIENT_SDU_SIZE,
  190. NULL, &data);
  191. if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
  192. return -1;
  193. return found;
  194. }
  195. int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu) {
  196. Octstr *data;
  197. int found;
  198. found = wsp_cap_get_data(caps_list, WSP_CAPS_SERVER_SDU_SIZE,
  199. NULL, &data);
  200. if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
  201. return -1;
  202. return found;
  203. }
  204. int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor) {
  205. Octstr *data;
  206. int found;
  207. int c;
  208. found = wsp_cap_get_data(caps_list, WSP_CAPS_METHOD_MOR, NULL, &data);
  209. if (found > 0) {
  210. c = octstr_get_char(data, 0);
  211. if (c < 0)
  212. return -1;
  213. *mor = c;
  214. }
  215. return found;
  216. }
  217. int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor) {
  218. Octstr *data;
  219. int found;
  220. int c;
  221. found = wsp_cap_get_data(caps_list, WSP_CAPS_PUSH_MOR, NULL, &data);
  222. if (found > 0) {
  223. c = octstr_get_char(data, 0);
  224. if (c < 0)
  225. return -1;
  226. *mor = c;
  227. }
  228. return found;
  229. }