Kannel: Open Source WAP and SMS gateway  svn-r5335
wsp_caps.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /* wsp_caps.c - implement interface to WSP capability negotiation
58  *
59  * Richard Braakman
60  */
61 
62 #include "gwlib/gwlib.h"
63 #include "wsp_caps.h"
64 
65 
66 static void wsp_cap_destroy_item(void *cap) {
67  wsp_cap_destroy(cap);
68 }
69 
70 
72  Capability *new_cap;
73 
74  new_cap = gw_malloc(sizeof(*new_cap));
75  new_cap->id = id;
76  new_cap->name = name;
77  new_cap->data = data;
78  new_cap->accept = 0;
79 
80  return new_cap;
81 }
82 
84  if (cap == NULL)
85  return;
86 
87  octstr_destroy(cap->name);
88  octstr_destroy(cap->data);
89  gw_free(cap);
90 }
91 
93  debug("wsp", 0, "Dumping capability at %p:", cap);
94  if (cap) {
95  debug("wsp", 0, " id = %d", cap->id);
96  debug("wsp", 0, " name:");
97  octstr_dump(cap->name, 1);
98  debug("wsp", 0, " data:");
99  octstr_dump(cap->data, 1);
100  if (cap->data == NULL)
101  debug("wsp", 0, " accept: %d", cap->accept);
102  }
103  debug("wsp", 0, "Capability dump ends.");
104 }
105 
106 void wsp_cap_dump_list(List *caps_list) {
107  long i;
108 
109  if (caps_list == NULL) {
110  debug("wsp", 0, "NULL capability list");
111  return;
112  }
113  debug("wsp", 0, "Dumping capability list at %p, length %ld",
114  caps_list, gwlist_len(caps_list));
115  for (i = 0; i < gwlist_len(caps_list); i++) {
116  wsp_cap_dump(gwlist_get(caps_list, i));
117  }
118  debug("wsp", 0, "End of capability list dump");
119 }
120 
121 void wsp_cap_destroy_list(List *caps_list) {
123 }
124 
126  Capability *cap;
127  List *new_list;
128  long i;
129 
130  new_list = gwlist_create();
131 
132  if (caps_list == NULL)
133  return new_list;
134 
135  for (i = 0; i < gwlist_len(caps_list); i++) {
136  cap = gwlist_get(caps_list, i);
137  gwlist_append(new_list, wsp_cap_duplicate(cap));
138  }
139  return new_list;
140 };
141 
143  Capability *new_cap;
144 
145  if (!cap)
146  return NULL;
147 
148  new_cap = wsp_cap_create(cap->id,
149  octstr_duplicate(cap->name),
150  octstr_duplicate(cap->data));
151  new_cap->accept = cap->accept;
152  return new_cap;
153 }
154 
156  List *caps_list;
157  long pos, capslen;
158 
159  caps_list = gwlist_create();
160  if (caps == NULL)
161  return caps_list;
162 
163  capslen = octstr_len(caps);
164  pos = 0;
165  while (pos < capslen) {
166  unsigned long length;
167  int id;
168  Octstr *name;
169  Octstr *data;
170 
171  pos = octstr_extract_uintvar(caps, &length, pos);
172  if (pos < 0 || length == 0)
173  goto error;
174 
175  id = octstr_get_char(caps, pos);
176  if (id >= 0x80) {
177  id &= 0x7f; /* It's encoded as a short-integer */
178  name = NULL;
179  data = octstr_copy(caps, pos + 1, length - 1);
180  } else {
181  long nullpos;
182  id = -1; /* It's encoded as token-text */
183  nullpos = octstr_search_char(caps, 0, pos);
184  if (nullpos < 0)
185  goto error;
186  /* check length
187  * FIXME: If it's not allowed that data is empty then change check
188  * to <= .
189  */
190  if (length < (nullpos + 1 - pos))
191  goto error;
192  name = octstr_copy(caps, pos, nullpos - pos);
193  data = octstr_copy(caps, nullpos + 1,
194  length - (nullpos + 1 - pos));
195  }
196  gwlist_append(caps_list, wsp_cap_create(id, name, data));
197  pos += length;
198  }
199 
200  return caps_list;
201 
202 error:
203  warning(0, "WSP: Error unpacking capabilities");
204  return caps_list;
205 }
206 
208  Octstr *result;
209  Capability *cap;
210  long i, len;
211 
212  result = octstr_create("");
213  len = gwlist_len(caps_list);
214  for (i = 0; i < len; i++) {
215  long datalen;
216 
217  cap = gwlist_get(caps_list, i);
218 
219  datalen = 0;
220  if (cap->data)
221  datalen = octstr_len(cap->data);
222 
223  if (datalen == 0 && cap->accept)
224  continue;
225 
226  if (cap->name) {
227  if (octstr_get_char(cap->name, 0) >= 0x80 ||
228  octstr_search_char(cap->name, 0, 0) >= 0) {
229  error(0, "WSP: Bad capability.");
230  wsp_cap_dump(cap);
231  continue;
232  }
233  /* Add length */
234  octstr_append_uintvar(result,
235  octstr_len(cap->name) + 1 + datalen);
236  /* Add identifier */
237  octstr_append(result, cap->name);
238  octstr_append_char(result, 0);
239  } else {
240  if (cap->id >= 0x80 || cap->id < 0) {
241  error(0, "WSP: Bad capability.");
242  wsp_cap_dump(cap);
243  continue;
244  }
245  /* Add length */
246  octstr_append_uintvar(result, 1 + datalen);
247  /* Add identifier */
248  octstr_append_char(result, 0x80 | cap->id);
249  }
250  /* Add payload, if any */
251  if (cap->data) {
252  octstr_append(result, cap->data);
253  }
254  }
255 
256  return result;
257 }
258 
259 static int wsp_cap_get_data(List *caps_list, int id, Octstr *name,
260  Octstr **data) {
261  long i, len;
262  Capability *cap;
263  int found;
264 
265  len = gwlist_len(caps_list);
266  found = 0;
267  *data = NULL;
268  for (i = 0; i < len; i++) {
269  cap = gwlist_get(caps_list, i);
270  if ((name && cap->name
271  && octstr_compare(name, cap->name) == 0)
272  || (!name && cap->id == id)) {
273  if (!found)
274  *data = cap->data;
275  found++;
276  }
277  }
278 
279  return found;
280 }
281 
282 int wsp_cap_count(List *caps_list, int id, Octstr *name) {
283  Octstr *data;
284 
285  return wsp_cap_get_data(caps_list, id, name, &data);
286 }
287 
288 int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu) {
289  Octstr *data;
290  int found;
291 
293  NULL, &data);
294  if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
295  return -1;
296 
297  return found;
298 }
299 
300 int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu) {
301  Octstr *data;
302  int found;
303 
305  NULL, &data);
306  if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
307  return -1;
308 
309  return found;
310 }
311 
312 int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor) {
313  Octstr *data;
314  int found;
315  int c;
316 
317  found = wsp_cap_get_data(caps_list, WSP_CAPS_METHOD_MOR, NULL, &data);
318  if (found > 0) {
319  c = octstr_get_char(data, 0);
320  if (c < 0)
321  return -1;
322  *mor = c;
323  }
324 
325  return found;
326 }
327 
328 int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor) {
329  Octstr *data;
330  int found;
331  int c;
332 
333  found = wsp_cap_get_data(caps_list, WSP_CAPS_PUSH_MOR, NULL, &data);
334  if (found > 0) {
335  c = octstr_get_char(data, 0);
336  if (c < 0)
337  return -1;
338  *mor = c;
339  }
340 
341  return found;
342 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor)
Definition: wsp_caps.c:328
void wsp_cap_destroy_list(List *caps_list)
Definition: wsp_caps.c:121
int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu)
Definition: wsp_caps.c:300
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
int id
Definition: wsp_caps.h:72
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
Capability * wsp_cap_create(int id, Octstr *name, Octstr *data)
Definition: wsp_caps.c:71
void wsp_cap_dump(Capability *cap)
Definition: wsp_caps.c:92
static int wsp_cap_get_data(List *caps_list, int id, Octstr *name, Octstr **data)
Definition: wsp_caps.c:259
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
static struct pid_list * found
Octstr * data
Definition: wsp_caps.h:76
int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu)
Definition: wsp_caps.c:288
Capability * wsp_cap_duplicate(Capability *cap)
Definition: wsp_caps.c:142
List * wsp_cap_unpack_list(Octstr *caps)
Definition: wsp_caps.c:155
static void wsp_cap_destroy_item(void *cap)
Definition: wsp_caps.c:66
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor)
Definition: wsp_caps.c:312
char * name
Definition: smsc_cimd2.c:212
int wsp_cap_count(List *caps_list, int id, Octstr *name)
Definition: wsp_caps.c:282
void warning(int err, const char *fmt,...)
Definition: log.c:660
int accept
Definition: wsp_caps.h:80
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
Definition: octstr.c:118
void wsp_cap_dump_list(List *caps_list)
Definition: wsp_caps.c:106
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Octstr * name
Definition: wsp_caps.h:73
Octstr * wsp_cap_pack_list(List *caps_list)
Definition: wsp_caps.c:207
#define gwlist_create()
Definition: list.h:136
long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos)
Definition: octstr.c:1954
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
void wsp_cap_destroy(Capability *cap)
Definition: wsp_caps.c:83
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.