1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 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 /*
58  * ota_prov.c: OTA settings and bookmarks provisioning routines
59  *
60  * This module contains routines for the SMS OTA (auto configuration) message
61  * creation and manipulation for the sendota HTTP interface.
62  *
63  * Official Nokia and Ericsson WAP OTA configuration settings coded
64  * by Stipe Tolj <stolj@kannel.org>, Wapme Systems AG.
65  *
66  * Officual OMA ProvCont OTA provisioning coded
67  * by Paul Bagyenda, digital solutions Ltd.
68  *
69  * XML compiler by Aarno Syv�nen <aarno@wiral.com>, Wiral Ltd.
70  */
71 
72 #include <string.h>
73 
74 #include "gwlib/gwlib.h"
75 
76 #ifdef HAVE_LIBSSL
77 #include <openssl/hmac.h>
78 #endif
79 
80 #include "msg.h"
81 #include "sms.h"
82 #include "ota_prov.h"
83 #include "ota_prov_attr.h"
84 #include "ota_compiler.h"
85 
86 #include "wap/wsp_headers.h"
87 
88 
89 /***************************************************************************
90  *
91  * Implementation of the internal function
92  */
93 
94 /*
95  * Append the User Data Header (UDH) including the length (UDHL). Only ports
96  * UDH here - SAR UDH is added when (or if) we split the message. This is our
97  * *specific* WDP layer.
98  */
ota_pack_udh(Msg ** msg,Octstr * doc_type)99 static void ota_pack_udh(Msg **msg, Octstr *doc_type)
100 {
101     (*msg)->sms.udhdata = octstr_create("");
102     if (octstr_case_compare(doc_type, octstr_imm("oma-settings")) == 0)
103         octstr_append_from_hex((*msg)->sms.udhdata, "0605040B840B84");
104     else if (octstr_case_compare(doc_type, octstr_imm("syncsettings")) == 0) {
105         octstr_append_from_hex((*msg)->sms.udhdata, "060504C34CC002");
106     } else
107         octstr_append_from_hex((*msg)->sms.udhdata, "060504C34FC002");
108  }
109 
110 
111 /*
112  * Our WSP headers: Push Id, PDU type, headers, charset.
113  */
ota_pack_push_headers(Msg ** msg,Octstr * mime_type,Octstr * sec,Octstr * pin,Octstr * ota_binary)114 static int ota_pack_push_headers(Msg **msg, Octstr *mime_type, Octstr *sec,
115                                  Octstr *pin, Octstr *ota_binary)
116 {
117     (*msg)->sms.msgdata = octstr_create("");
118     if (octstr_case_compare(mime_type, octstr_imm("settings")) == 0) {
119 
120         /* PUSH ID, PDU type, header length, value length */
121         octstr_append_from_hex((*msg)->sms.msgdata, "01062C1F2A");
122         /* MIME type for settings */
123         octstr_format_append((*msg)->sms.msgdata, "%s",
124                              "application/x-wap-prov.browser-settings");
125         octstr_append_from_hex((*msg)->sms.msgdata, "00");
126         /* charset UTF-8 */
127         octstr_append_from_hex((*msg)->sms.msgdata, "81EA");
128 
129     } else if (octstr_case_compare(mime_type, octstr_imm("bookmarks")) == 0) {
130 
131         /* PUSH ID, PDU type, header length, value length */
132         octstr_append_from_hex((*msg)->sms.msgdata, "01062D1F2B");
133         /* MIME type for bookmarks */
134         octstr_format_append((*msg)->sms.msgdata, "%s",
135                              "application/x-wap-prov.browser-bookmarks");
136         octstr_append_from_hex((*msg)->sms.msgdata, "00");
137         /* charset UTF-8 */
138         octstr_append_from_hex((*msg)->sms.msgdata, "81EA");
139 
140     } else if (octstr_case_compare(mime_type, octstr_imm("syncsettings")) == 0) {
141 
142         octstr_append_from_hex((*msg)->sms.msgdata, "3406060502020b81EA");
143 
144     } else if (octstr_case_compare(mime_type, octstr_imm("oma-settings")) == 0) {
145         Octstr *hdr = octstr_create(""), *mac;
146         unsigned char *p;
147         unsigned int mac_len;
148 #ifdef HAVE_LIBSSL
149         unsigned char macbuf[EVP_MAX_MD_SIZE];
150 #endif
151 
152         /* PUSH ID, PDU type, header length, value length */
153         octstr_append_from_hex((*msg)->sms.msgdata, "0106");
154 
155         octstr_append_from_hex(hdr, "1f2db6"); /* Content type + other type + sec param */
156         wsp_pack_short_integer(hdr, 0x11);
157         if (octstr_case_compare(sec, octstr_imm("netwpin")) == 0)
158             wsp_pack_short_integer(hdr, 0x0);
159         else if (octstr_case_compare(sec, octstr_imm("userpin")) == 0)
160             wsp_pack_short_integer(hdr, 0x01);
161         else if (octstr_case_compare(sec, octstr_imm("usernetwpin")) == 0)
162             wsp_pack_short_integer(hdr, 0x02);
163         else if (octstr_case_compare(sec, octstr_imm("userpinmac")) == 0)
164             wsp_pack_short_integer(hdr, 0x03); /* XXXX Although not quite supported now.*/
165         else {
166             warning(0, "OMA ProvCont: Unknown SEC pin type '%s'.", octstr_get_cstr(sec));
167             wsp_pack_short_integer(hdr, 0x01);
168         }
169         wsp_pack_short_integer(hdr, 0x12); /* MAC */
170 
171 #ifdef HAVE_LIBSSL
172         p = HMAC(EVP_sha1(), octstr_get_cstr(pin), octstr_len(pin),
173                  (unsigned char *)octstr_get_cstr(ota_binary), octstr_len(ota_binary),
174                  macbuf, &mac_len);
175 #else
176         mac_len = 0;
177         p = "";
178         warning(0, "OMA ProvCont: No SSL Support, '%s' not supported!", octstr_get_cstr(mime_type));
179 #endif
180         mac = octstr_create_from_data((char *)p, mac_len);
181         octstr_binary_to_hex(mac, 1);
182 
183         octstr_append(hdr, mac);
184         octstr_append_from_hex(hdr, "00");
185 
186         octstr_append_uintvar((*msg)->sms.msgdata, octstr_len(hdr));
187         octstr_append((*msg)->sms.msgdata, hdr);
188 
189         octstr_destroy(hdr);
190         octstr_destroy(mac);
191 
192     } else {
193         warning(0, "Unknown MIME type in OTA request, type '%s' is unsupported.",
194                 octstr_get_cstr(mime_type));
195         return 0;
196     }
197 
198     return 1;
199 }
200 
201 
202 /***************************************************************************
203  *
204  * Implementation of the external function
205  */
206 
ota_pack_message(Msg ** msg,Octstr * ota_doc,Octstr * doc_type,Octstr * from,Octstr * phone_number,Octstr * sec,Octstr * pin)207 int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type,
208                      Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin)
209 {
210     Octstr *ota_binary;
211 
212     *msg = msg_create(sms);
213     (*msg)->sms.sms_type = mt_push;
214 
215     ota_pack_udh(msg, doc_type);
216 
217     if (ota_compile(ota_doc, octstr_imm("UTF-8"), &ota_binary) == -1)
218         goto cerror;
219 
220     if (!ota_pack_push_headers(msg, doc_type, sec, pin, ota_binary))
221         goto herror;
222 
223     octstr_format_append((*msg)->sms.msgdata, "%S", ota_binary);
224     (*msg)->sms.sender = octstr_duplicate(from);
225     (*msg)->sms.receiver = octstr_duplicate(phone_number);
226     (*msg)->sms.coding = DC_8BIT;
227     (*msg)->sms.time = time(NULL);
228 
229     octstr_dump((*msg)->sms.msgdata, 0);
230     info(0, "/cgi-bin/sendota: XML request for target <%s>", octstr_get_cstr(phone_number));
231 
232     octstr_destroy(ota_binary);
233     octstr_destroy(ota_doc);
234     octstr_destroy(doc_type);
235     octstr_destroy(from);
236     octstr_destroy(sec);
237     octstr_destroy(pin);
238     return 0;
239 
240 herror:
241     octstr_destroy(ota_binary);
242     octstr_destroy(ota_doc);
243     octstr_destroy(doc_type);
244     octstr_destroy(from);
245     octstr_destroy(sec);
246     octstr_destroy(pin);
247     return -2;
248 
249 cerror:
250     octstr_destroy(ota_doc);
251     octstr_destroy(doc_type);
252     octstr_destroy(from);
253     octstr_destroy(sec);
254     octstr_destroy(pin);
255     return -1;
256 }
257 
258 
ota_tokenize_settings(CfgGroup * grp,Octstr * from,Octstr * receiver)259 Msg *ota_tokenize_settings(CfgGroup *grp, Octstr *from, Octstr *receiver)
260 {
261     Octstr *url, *desc, *ipaddr, *phonenum, *username, *passwd;
262     int speed, bearer, calltype, connection, security, authent;
263     Msg *msg;
264     Octstr *p;
265 
266     url = NULL;
267     desc = NULL;
268     ipaddr = NULL;
269     phonenum = NULL;
270     username = NULL;
271     passwd = NULL;
272     bearer = -1;
273     calltype =  WBXML_TOK_VALUE_CONN_ISDN;
274     connection = WBXML_TOK_VALUE_PORT_9201;
275     security = 0;
276     authent = WBXML_TOK_VALUE_AUTH_PAP;
277 
278     url = cfg_get(grp, octstr_imm("location"));
279     desc = cfg_get(grp, octstr_imm("service"));
280     ipaddr = cfg_get(grp, octstr_imm("ipaddress"));
281     phonenum = cfg_get(grp, octstr_imm("phonenumber"));
282     p = cfg_get(grp, octstr_imm("bearer"));
283     if (p != NULL) {
284         if (strcasecmp(octstr_get_cstr(p), "data") == 0)
285             bearer = WBXML_TOK_VALUE_GSM_CSD;
286         else
287             bearer = -1;
288         octstr_destroy(p);
289     }
290     p = cfg_get(grp, octstr_imm("calltype"));
291     if (p != NULL) {
292         if (strcasecmp(octstr_get_cstr(p), "analog") == 0)
293             calltype = WBXML_TOK_VALUE_CONN_ANALOGUE;
294         else
295             calltype =  WBXML_TOK_VALUE_CONN_ISDN;
296         octstr_destroy(p);
297     }
298 
299     speed = WBXML_TOK_VALUE_SPEED_9600;
300     p = cfg_get(grp, octstr_imm("speed"));
301     if (p != NULL) {
302         if (octstr_compare(p, octstr_imm("14400")) == 0)
303             speed = WBXML_TOK_VALUE_SPEED_14400;
304         octstr_destroy(p);
305     }
306 
307     /* connection mode: UDP (port 9200) or TCP (port 9201)*/
308     p = cfg_get(grp, octstr_imm("connection"));
309     if (p != NULL) {
310         if (strcasecmp(octstr_get_cstr(p), "temp") == 0)
311             connection = WBXML_TOK_VALUE_PORT_9200;
312         else
313             connection = WBXML_TOK_VALUE_PORT_9201;
314         octstr_destroy(p);
315     }
316 
317     /* dial in security: CHAP or PAP */
318     p = cfg_get(grp, octstr_imm("pppsecurity"));
319     if (p != NULL) {
320         if (strcasecmp(octstr_get_cstr(p), "on") == 0)
321             authent = WBXML_TOK_VALUE_AUTH_CHAP;
322         else
323             authent = WBXML_TOK_VALUE_AUTH_PAP;
324         octstr_destroy(p);
325     }
326 
327     /* WTLS: for UDP (port 9202) or TCP (port 9203) */
328     p = cfg_get(grp, octstr_imm("authentication"));
329     if (p != NULL) {
330         if (strcasecmp(octstr_get_cstr(p), "secure") == 0)
331             security = 1;
332         else
333             security = WBXML_TOK_VALUE_PORT_9201;
334         octstr_destroy(p);
335     }
336     if (security == 1)
337         connection = (connection == WBXML_TOK_VALUE_PORT_9201)?
338             WBXML_TOK_VALUE_PORT_9203 : WBXML_TOK_VALUE_PORT_9202;
339 
340     username = cfg_get(grp, octstr_imm("login"));
341     passwd = cfg_get(grp, octstr_imm("secret"));
342 
343     msg = msg_create(sms);
344 
345     /*
346      * Append the User Data Header (UDH) including the length (UDHL)
347      * WDP layer (start WDP headers)
348      */
349 
350     msg->sms.sms_type = mt_push;
351     msg->sms.udhdata = octstr_create("");
352 
353     /*
354      * Within OTA spec this is "0B0504C34FC0020003040201", but it works
355      * with the following too?!
356      */
357     octstr_append_from_hex(msg->sms.udhdata, "060504C34FC002");
358     /* WDP layer (end WDP headers) */
359 
360     /*
361      * WSP layer (start WSP headers)
362      */
363 
364     msg->sms.msgdata = octstr_create("");
365     /* PUSH ID, PDU type, header length, value length */
366     octstr_append_from_hex(msg->sms.msgdata, "01062C1F2A");
367     /* MIME-type: application/x-wap-prov.browser-settings */
368     octstr_format_append(msg->sms.msgdata, "%s",
369                          "application/x-wap-prov.browser-settings");
370     octstr_append_from_hex(msg->sms.msgdata, "00");
371     /* charset UTF-8 */
372     octstr_append_from_hex(msg->sms.msgdata, "81EA");
373     /* WSP layer (end WSP headers) */
374 
375     /*
376      * WSP layer (start WSP data field)
377      */
378 
379     /* WBXML version 1.1 */
380     octstr_append_from_hex(msg->sms.msgdata, "0101");
381     /* charset UTF-8 */
382     octstr_append_from_hex(msg->sms.msgdata, "6A00");
383 
384     /* CHARACTERISTIC_LIST */
385     octstr_append_from_hex(msg->sms.msgdata, "45");
386     /* CHARACTERISTIC with content and attributes */
387     octstr_append_from_hex(msg->sms.msgdata, "C6");
388     /* TYPE=ADDRESS */
389     octstr_append_char(msg->sms.msgdata, WBXML_TOK_TYPE_ADDRESS);
390     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
391 
392     /* bearer type */
393     if (bearer != -1) {
394         /* PARM with attributes */
395         octstr_append_from_hex(msg->sms.msgdata, "87");
396         /* NAME=BEARER, VALUE=GSM_CSD */
397         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_BEARER);
398         octstr_append_char(msg->sms.msgdata, bearer);
399         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
400     }
401     /* IP address */
402     if (ipaddr != NULL) {
403         /* PARM with attributes */
404         octstr_append_from_hex(msg->sms.msgdata, "87");
405         /* NAME=PROXY, VALUE, inline string */
406         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_PROXY);
407         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
408         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
409         octstr_append(msg->sms.msgdata, octstr_duplicate(ipaddr));
410         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
411         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
412     }
413     /* connection type */
414     if (connection != -1) {
415         /* PARM with attributes */
416         octstr_append_from_hex(msg->sms.msgdata, "87");
417         /* NAME=PORT, VALUE */
418         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_PORT);
419         octstr_append_char(msg->sms.msgdata, connection);
420         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
421     }
422     /* phone number */
423     if (phonenum != NULL) {
424         /* PARM with attributes */
425         octstr_append_from_hex(msg->sms.msgdata, "87");
426         /* NAME=CSD_DIALSTRING, VALUE, inline string */
427         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_CSD_DIALSTRING);
428         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
429         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
430         octstr_append(msg->sms.msgdata, octstr_duplicate(phonenum));
431         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
432         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
433     }
434     /* authentication */
435     /* PARM with attributes */
436     octstr_append_from_hex(msg->sms.msgdata, "87");
437      /* NAME=PPP_AUTHTYPE, VALUE */
438     octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_PPP_AUTHTYPE);
439     octstr_append_char(msg->sms.msgdata, authent);
440     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
441     /* user name */
442     if (username != NULL) {
443         /* PARM with attributes */
444         octstr_append_from_hex(msg->sms.msgdata, "87");
445         /* NAME=PPP_AUTHNAME, VALUE, inline string */
446         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_PPP_AUTHNAME);
447         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
448         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
449         octstr_append(msg->sms.msgdata, octstr_duplicate(username));
450         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
451         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
452     }
453     /* password */
454     if (passwd != NULL) {
455         /* PARM with attributes */
456         octstr_append_from_hex(msg->sms.msgdata, "87");
457         /* NAME=PPP_AUTHSECRET, VALUE, inline string */
458         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_PPP_AUTHSECRET);
459         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
460         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
461         octstr_append(msg->sms.msgdata, octstr_duplicate(passwd));
462         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
463         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
464     }
465     /* data call type */
466     if (calltype != -1) {
467         /* PARM with attributes */
468         octstr_append_from_hex(msg->sms.msgdata, "87");
469         /* NAME=CSD_CALLTYPE, VALUE */
470         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_CSD_CALLTYPE);
471         octstr_append_char(msg->sms.msgdata, calltype);
472         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
473     }
474     /* speed */
475     /* PARM with attributes */
476     octstr_append_from_hex(msg->sms.msgdata, "87");
477     /* NAME=CSD_CALLSPEED, VALUE */
478     octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_CSD_CALLSPEED);
479     octstr_append_char(msg->sms.msgdata, speed);
480     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
481 
482     /* end CHARACTERISTIC TYPE=ADDRESS */
483     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
484 
485     /* homepage */
486     if (url != NULL) {
487         /* CHARACTERISTIC with attributes */
488         octstr_append_from_hex(msg->sms.msgdata, "86");
489         /* TYPE=URL */
490         octstr_append_char(msg->sms.msgdata, WBXML_TOK_TYPE_URL);
491         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
492         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
493         octstr_append(msg->sms.msgdata, url);
494         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
495         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
496     }
497 
498     /* CHARACTERISTIC with content and attributes */
499     octstr_append_from_hex(msg->sms.msgdata, "C6");
500     /* TYPE=NAME */
501     octstr_append_char(msg->sms.msgdata, WBXML_TOK_TYPE_NAME);
502     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
503 
504     /* service description */
505     if (desc != NULL) {
506         /* PARAM with attributes */
507         octstr_append_from_hex(msg->sms.msgdata, "87");
508         /* NAME=NAME, VALUE, inline */
509         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_NAME);
510         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
511         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
512         octstr_append(msg->sms.msgdata, desc);
513         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
514         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
515     }
516 
517     /* end of CHARACTERISTIC */
518     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
519     /* end of CHARACTERISTIC-LIST */
520     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
521     /* WSP layer (end WSP data field) */
522 
523     msg->sms.sender = from;
524     msg->sms.receiver = octstr_duplicate(receiver);
525     msg->sms.coding = DC_8BIT;
526 
527     msg->sms.time = time(NULL);
528 
529     octstr_destroy(url);
530     octstr_destroy(desc);
531     octstr_destroy(ipaddr);
532     octstr_destroy(phonenum);
533     octstr_destroy(username);
534     octstr_destroy(passwd);
535 
536     return msg;
537 }
538 
539 
ota_tokenize_bookmarks(CfgGroup * grp,Octstr * from,Octstr * receiver)540 Msg *ota_tokenize_bookmarks(CfgGroup *grp, Octstr *from, Octstr *receiver)
541 {
542     Octstr *url, *name;
543     Msg *msg;
544 
545     url = NULL;
546     name = NULL;
547 
548     url = cfg_get(grp, octstr_imm("url"));
549     name = cfg_get(grp, octstr_imm("name"));
550 
551     msg = msg_create(sms);
552 
553     /*
554      * Append the User Data Header (UDH) including the length (UDHL)
555      * WDP layer (start WDP headers)
556      */
557 
558     msg->sms.sms_type = mt_push;
559     msg->sms.udhdata = octstr_create("");
560 
561     octstr_append_from_hex(msg->sms.udhdata, "060504C34FC002");
562     /* WDP layer (end WDP headers) */
563 
564     /*
565      * WSP layer (start WSP headers)
566      */
567 
568     msg->sms.msgdata = octstr_create("");
569     /* PUSH ID, PDU type, header length, value length */
570     octstr_append_from_hex(msg->sms.msgdata, "01062D1F2B");
571     /* MIME-type: application/x-wap-prov.browser-bookmarks */
572     octstr_format_append(msg->sms.msgdata, "%s",
573                          "application/x-wap-prov.browser-bookmarks");
574     octstr_append_from_hex(msg->sms.msgdata, "00");
575     /* charset UTF-8 */
576     octstr_append_from_hex(msg->sms.msgdata, "81EA");
577     /* WSP layer (end WSP headers) */
578 
579     /*
580      * WSP layer (start WSP data field)
581      */
582 
583     /* WBXML version 1.1 */
584     octstr_append_from_hex(msg->sms.msgdata, "0101");
585     /* charset UTF-8 */
586     octstr_append_from_hex(msg->sms.msgdata, "6A00");
587 
588     /* CHARACTERISTIC_LIST */
589     octstr_append_from_hex(msg->sms.msgdata, "45");
590     /* CHARACTERISTIC with content and attributes */
591     octstr_append_from_hex(msg->sms.msgdata, "C6");
592     /* TYPE=BOOKMARK */
593     octstr_append_char(msg->sms.msgdata, WBXML_TOK_TYPE_BOOKMARK);
594     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
595 
596     /* name */
597     if (name != NULL) {
598         /* PARM with attributes */
599         octstr_append_from_hex(msg->sms.msgdata, "87");
600         /* NAME=PROXY, VALUE, inline string */
601         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_NAME);
602         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
603         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
604         octstr_append(msg->sms.msgdata, octstr_duplicate(name));
605         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
606         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
607     }
608     /* URL */
609     if (url != NULL) {
610         /* PARM with attributes */
611         octstr_append_from_hex(msg->sms.msgdata, "87");
612         /* NAME=PROXY, VALUE, inline string */
613         octstr_append_char(msg->sms.msgdata, WBXML_TOK_NAME_URL);
614         octstr_append_char(msg->sms.msgdata, WBXML_TOK_VALUE);
615         octstr_append_char(msg->sms.msgdata, WBXML_TOK_STR_I);
616         octstr_append(msg->sms.msgdata, octstr_duplicate(url));
617         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END_STR_I);
618         octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
619     }
620 
621     /* end of CHARACTERISTIC */
622     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
623     /* end of CHARACTERISTIC-LIST */
624     octstr_append_char(msg->sms.msgdata, WBXML_TOK_END);
625     /* WSP layer (end WSP data field) */
626 
627     msg->sms.sender = from;
628     msg->sms.receiver = octstr_duplicate(receiver);
629     msg->sms.coding = DC_8BIT;
630 
631     msg->sms.time = time(NULL);
632 
633     octstr_destroy(name);
634     octstr_destroy(url);
635 
636     return msg;
637 }
638 
639