00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "gwlib/gwlib.h"
00063 #include "wsp_caps.h"
00064
00065
00066 static void wsp_cap_destroy_item(void *cap) {
00067 wsp_cap_destroy(cap);
00068 }
00069
00070
00071 Capability *wsp_cap_create(int id, Octstr *name, Octstr *data) {
00072 Capability *new_cap;
00073
00074 new_cap = gw_malloc(sizeof(*new_cap));
00075 new_cap->id = id;
00076 new_cap->name = name;
00077 new_cap->data = data;
00078 new_cap->accept = 0;
00079
00080 return new_cap;
00081 }
00082
00083 void wsp_cap_destroy(Capability *cap) {
00084 if (cap == NULL)
00085 return;
00086
00087 octstr_destroy(cap->name);
00088 octstr_destroy(cap->data);
00089 gw_free(cap);
00090 }
00091
00092 void wsp_cap_dump(Capability *cap) {
00093 debug("wsp", 0, "Dumping capability at %p:", cap);
00094 if (cap) {
00095 debug("wsp", 0, " id = %d", cap->id);
00096 debug("wsp", 0, " name:");
00097 octstr_dump(cap->name, 1);
00098 debug("wsp", 0, " data:");
00099 octstr_dump(cap->data, 1);
00100 if (cap->data == NULL)
00101 debug("wsp", 0, " accept: %d", cap->accept);
00102 }
00103 debug("wsp", 0, "Capability dump ends.");
00104 }
00105
00106 void wsp_cap_dump_list(List *caps_list) {
00107 long i;
00108
00109 if (caps_list == NULL) {
00110 debug("wsp", 0, "NULL capability list");
00111 return;
00112 }
00113 debug("wsp", 0, "Dumping capability list at %p, length %ld",
00114 caps_list, gwlist_len(caps_list));
00115 for (i = 0; i < gwlist_len(caps_list); i++) {
00116 wsp_cap_dump(gwlist_get(caps_list, i));
00117 }
00118 debug("wsp", 0, "End of capability list dump");
00119 }
00120
00121 void wsp_cap_destroy_list(List *caps_list) {
00122 gwlist_destroy(caps_list, wsp_cap_destroy_item);
00123 }
00124
00125 List *wsp_cap_duplicate_list(List *caps_list) {
00126 Capability *cap;
00127 List *new_list;
00128 long i;
00129
00130 new_list = gwlist_create();
00131
00132 if (caps_list == NULL)
00133 return new_list;
00134
00135 for (i = 0; i < gwlist_len(caps_list); i++) {
00136 cap = gwlist_get(caps_list, i);
00137 gwlist_append(new_list, wsp_cap_duplicate(cap));
00138 }
00139 return new_list;
00140 };
00141
00142 Capability *wsp_cap_duplicate(Capability *cap) {
00143 Capability *new_cap;
00144
00145 if (!cap)
00146 return NULL;
00147
00148 new_cap = wsp_cap_create(cap->id,
00149 octstr_duplicate(cap->name),
00150 octstr_duplicate(cap->data));
00151 new_cap->accept = cap->accept;
00152 return new_cap;
00153 }
00154
00155 List *wsp_cap_unpack_list(Octstr *caps) {
00156 List *caps_list;
00157 long pos, capslen;
00158
00159 caps_list = gwlist_create();
00160 if (caps == NULL)
00161 return caps_list;
00162
00163 capslen = octstr_len(caps);
00164 pos = 0;
00165 while (pos < capslen) {
00166 unsigned long length;
00167 int id;
00168 Octstr *name;
00169 Octstr *data;
00170
00171 pos = octstr_extract_uintvar(caps, &length, pos);
00172 if (pos < 0 || length == 0)
00173 goto error;
00174
00175 id = octstr_get_char(caps, pos);
00176 if (id >= 0x80) {
00177 id &= 0x7f;
00178 name = NULL;
00179 data = octstr_copy(caps, pos + 1, length - 1);
00180 } else {
00181 long nullpos;
00182 id = -1;
00183 nullpos = octstr_search_char(caps, 0, pos);
00184 if (nullpos < 0)
00185 goto error;
00186
00187
00188
00189
00190 if (length < (nullpos + 1 - pos))
00191 goto error;
00192 name = octstr_copy(caps, pos, nullpos - pos);
00193 data = octstr_copy(caps, nullpos + 1,
00194 length - (nullpos + 1 - pos));
00195 }
00196 gwlist_append(caps_list, wsp_cap_create(id, name, data));
00197 pos += length;
00198 }
00199
00200 return caps_list;
00201
00202 error:
00203 warning(0, "WSP: Error unpacking capabilities");
00204 return caps_list;
00205 }
00206
00207 Octstr *wsp_cap_pack_list(List *caps_list) {
00208 Octstr *result;
00209 Capability *cap;
00210 long i, len;
00211
00212 result = octstr_create("");
00213 len = gwlist_len(caps_list);
00214 for (i = 0; i < len; i++) {
00215 long datalen;
00216
00217 cap = gwlist_get(caps_list, i);
00218
00219 datalen = 0;
00220 if (cap->data)
00221 datalen = octstr_len(cap->data);
00222
00223 if (datalen == 0 && cap->accept)
00224 continue;
00225
00226 if (cap->name) {
00227 if (octstr_get_char(cap->name, 0) >= 0x80 ||
00228 octstr_search_char(cap->name, 0, 0) >= 0) {
00229 error(0, "WSP: Bad capability.");
00230 wsp_cap_dump(cap);
00231 continue;
00232 }
00233
00234 octstr_append_uintvar(result,
00235 octstr_len(cap->name) + 1 + datalen);
00236
00237 octstr_append(result, cap->name);
00238 octstr_append_char(result, 0);
00239 } else {
00240 if (cap->id >= 0x80 || cap->id < 0) {
00241 error(0, "WSP: Bad capability.");
00242 wsp_cap_dump(cap);
00243 continue;
00244 }
00245
00246 octstr_append_uintvar(result, 1 + datalen);
00247
00248 octstr_append_char(result, 0x80 | cap->id);
00249 }
00250
00251 if (cap->data) {
00252 octstr_append(result, cap->data);
00253 }
00254 }
00255
00256 return result;
00257 }
00258
00259 static int wsp_cap_get_data(List *caps_list, int id, Octstr *name,
00260 Octstr **data) {
00261 long i, len;
00262 Capability *cap;
00263 int found;
00264
00265 len = gwlist_len(caps_list);
00266 found = 0;
00267 *data = NULL;
00268 for (i = 0; i < len; i++) {
00269 cap = gwlist_get(caps_list, i);
00270 if ((name && cap->name
00271 && octstr_compare(name, cap->name) == 0)
00272 || (!name && cap->id == id)) {
00273 if (!found)
00274 *data = cap->data;
00275 found++;
00276 }
00277 }
00278
00279 return found;
00280 }
00281
00282 int wsp_cap_count(List *caps_list, int id, Octstr *name) {
00283 Octstr *data;
00284
00285 return wsp_cap_get_data(caps_list, id, name, &data);
00286 }
00287
00288 int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu) {
00289 Octstr *data;
00290 int found;
00291
00292 found = wsp_cap_get_data(caps_list, WSP_CAPS_CLIENT_SDU_SIZE,
00293 NULL, &data);
00294 if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
00295 return -1;
00296
00297 return found;
00298 }
00299
00300 int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu) {
00301 Octstr *data;
00302 int found;
00303
00304 found = wsp_cap_get_data(caps_list, WSP_CAPS_SERVER_SDU_SIZE,
00305 NULL, &data);
00306 if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
00307 return -1;
00308
00309 return found;
00310 }
00311
00312 int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor) {
00313 Octstr *data;
00314 int found;
00315 int c;
00316
00317 found = wsp_cap_get_data(caps_list, WSP_CAPS_METHOD_MOR, NULL, &data);
00318 if (found > 0) {
00319 c = octstr_get_char(data, 0);
00320 if (c < 0)
00321 return -1;
00322 *mor = c;
00323 }
00324
00325 return found;
00326 }
00327
00328 int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor) {
00329 Octstr *data;
00330 int found;
00331 int c;
00332
00333 found = wsp_cap_get_data(caps_list, WSP_CAPS_PUSH_MOR, NULL, &data);
00334 if (found > 0) {
00335 c = octstr_get_char(data, 0);
00336 if (c < 0)
00337 return -1;
00338 *mor = c;
00339 }
00340
00341 return found;
00342 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.