Adding support for OMA-WAP Provisioning OTA

Paul Bagyenda <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Attached are some diffs to implement OMA-style sending of OTA settings. 
Refer to OMA-WAP-ProvCont-v1_1-20021112-C (at 
http://www.openmobilealliance.org/tech/docs/) for details on how this 
works.

The changes include all (most) the HMAC computation stuff required for 
authentication. What I've done is modified the ota_compiler.c and 
ota_prov.c files to detect oma-style settings and build the WBXML file 
differently.

  I've checked its output against samples provided in the docs and 
against samples provided by SonyEricsson, Nokia & Motorola. Looks ok. 
Alas my phone seems to be having issues so I haven't received anything 
there yet. If someone out there can test and confirm, then we have a 
new addition to kannel!


Thanks.

P.



-----------------------------
Paul A. Bagyenda
Digital Solutions
P.O.Box 23833
58 Bukoto Str.
Kampala, UGANDA

Tel: +256-31-262117
Mob: +256-77-507743
Email: [email protected]
Web: http://www.dsmagic.com
-----------------------------
ota.diff (application/octet-stream, 28.7 KB)
Index: gateway/gw/ota_compiler.c
===================================================================
RCS file: /home/cvs/gateway/gw/ota_compiler.c,v
retrieving revision 1.4
diff -u -r1.4 ota_compiler.c
--- gateway/gw/ota_compiler.c	15 Nov 2003 13:14:23 -0000	1.4
+++ gateway/gw/ota_compiler.c	13 Feb 2004 14:50:22 -0000
@@ -91,9 +91,10 @@
  * chapter 8.2.
  */
 struct ota_3table_t {
-    char *name;
-    char *value;
-    unsigned char token;
+     char *name;
+     char *value;
+     unsigned char token;
+     unsigned char code_page; 
 };
 
 typedef struct ota_3table_t ota_3table_t;
@@ -103,9 +104,10 @@
  */
 
 static ota_2table_t ota_elements[] = {
-    { "CHARACTERISTIC-LIST", 0x05 },
-    { "CHARACTERISTIC", 0x06 },
-    { "PARM", 0x07 }
+     { "wap-provisioningdoc", 0x05},
+     { "CHARACTERISTIC-LIST", 0x05 },
+     { "CHARACTERISTIC", 0x06 },
+     { "PARM", 0x07 }
 };
 
 #define NUMBER_OF_ELEMENTS sizeof(ota_elements)/sizeof(ota_elements[0])
@@ -178,6 +180,174 @@
 
 #define NUMBER_OF_ATTRIBUTES sizeof(ota_attributes)/sizeof(ota_attributes[0])
 
+static ota_3table_t oma_ota_attributes[] = {
+     {"version", "1.0", 0x46},
+     {"version", "INLINE", 0x45},
+     {"type", "PXLOGICAL", 0x51},
+     {"type", "PXPHYSICAL", 0x52},
+     {"type", "PORT", 0x53},
+     {"type", "VALIDITY", 0x54},
+     {"type", "NAPDEF", 0x55},
+     {"type", "BOOTSTRAP", 0x56},
+     {"type", "VENDORCONFIG", 0x57},
+     {"type", "PXAUTHINFO", 0x59},
+     {"type", "NAPAUTHINFO", 0x5A},
+     {"type", "ACCESS", 0x5B},
+     {"type", "CLIENTIDENTITY", 0x58},
+     {"type", "APPLICATION", 0x55,1},
+     {"type", "APPADDR", 0x56,1},
+     {"type", "APPAUTH", 0x57,1},
+     {"type", "RESOURCE", 0x59,1},
+     {"type", "INLINE", 0x50},
+     {"name", "NAME", 0x7},
+     {"name", "NAP-ADDRESS", 0x8},
+     {"name", "NAP-ADDRTYPE", 0x9},
+     {"name", "CALLTYPE", 0xA},
+     {"name", "VALIDUNTIL", 0xB},
+     {"name", "AUTHTYPE", 0xC},
+     {"name", "AUTHNAME", 0xD},
+     {"name", "AUTHSECRET", 0xE},
+     {"name", "LINGER", 0xF},
+     {"name", "BEARER", 0x10},
+     {"name", "NAPID", 0x11},
+     {"name", "COUNTRY", 0x12},
+     {"name", "NETWORK", 0x13},
+     {"name", "INTERNET", 0x14},
+     {"name", "PROXY-ID", 0x15},
+     {"name", "PROXY-PROVIDER-ID", 0x16},
+     {"name", "DOMAIN", 0x17},
+     {"name", "PROVURL", 0x18},
+     {"name", "PXAUTH-TYPE", 0x19},
+     {"name", "PXAUTH-ID", 0x1A},
+     {"name", "PXAUTH-PW", 0x1B},
+     {"name", "STARTPAGE", 0x1C},
+     {"name", "BASAUTH-ID", 0x1D},
+     {"name", "BASAUTH-PW", 0x1E},
+     {"name", "PUSHENABLED", 0x1F},
+     {"name", "PXADDR", 0x20},
+     {"name", "PXADDRTYPE", 0x21},
+     {"name", "PORTNBR", 0x23},
+     {"name", "SERVICE", 0x24},
+     {"name", "LINKSPEED", 0x25},
+     {"name", "DNLINKSPEED", 0x26},
+     {"name", "LOCAL-ADDR", 0x27},
+     {"name", "LOCAL-ADDRTYPE", 0x28},
+     {"name", "CONTEXT-ALLOW", 0x29},
+     {"name", "TRUST", 0x2A},
+     {"name", "MASTER", 0x2B},
+     {"name", "SID", 0x2C},
+     {"name", "SOC", 0x2D},
+     {"name", "WSP-VERSION", 0x2E},
+     {"name", "PHYSICAL-PROXY-ID", 0x2F},
+     {"name", "CLIENT-ID", 0x30},
+     {"name", "DELIVERY-ERR-SDU", 0x31},
+     {"name", "DELIVERY-ORDER", 0x32},
+     {"name", "TRAFFIC-CLASS", 0x33},
+     {"name", "MAX-SDU-SIZE", 0x34},
+     {"name", "MAX-BITRATE-UPLINK", 0x35},
+     {"name", "MAX-BITRATE-DNLINK", 0x36},
+     {"name", "RESIDUAL-BER", 0x37},
+     {"name", "SDU-ERROR-RATIO", 0x38},
+     {"name", "TRAFFIC-HANDL-PRIO", 0x39},
+     {"name", "TRANSFER-DELAY", 0x3A},
+     {"name", "GUARANTEED-BITRATE-UPLINK", 0x3B},
+     {"name", "GUARANTEED-BITRATE-DNLINK", 0x3C},
+     {"name", "PXADDR-FQDN", 0x3D},
+     {"name", "PROXY-PW", 0x3E},
+     {"name", "PPGAUTH-TYPE", 0x3F},
+     {"name", "PULLENABLED", 0x47},
+     {"name", "DNS-ADDR", 0x48},
+     {"name", "MAX-NUM-RETRY", 0x49},
+     {"name", "FIRST-RETRY-TIMEOUT", 0x4A},
+     {"name", "REREG-THRESHOLD", 0x4B},
+     {"name", "T-BIT", 0x4C},
+     {"name", "AUTH-ENTITY", 0x4E},
+     {"name", "SPI", 0x4F},
+     {"name", "TO-NAPID", 0x22},
+     {"name", "AACCEPT", 0x2E,1},
+     {"name", "AAUTHDATA", 0x2F,1},
+     {"name", "AAUTHLEVEL", 0x30,1},
+     {"name", "AAUTHNAME", 0x31,1},
+     {"name", "AAUTHSECRET", 0x32,1},
+     {"name", "AAUTHTYPE", 0x33,1},
+     {"name", "ADDR", 0x34,1},
+     {"name", "ADDRTYPE", 0x35,1},
+     {"name", "APPID", 0x36,1},
+     {"name", "APROTOCOL", 0x37,1},
+     {"name", "PROVIDER-ID", 0x38,1},
+     {"name", "TO-PROXY", 0x39,1},
+     {"name", "URI", 0x3A,1},
+     {"name", "RULE", 0x3B,1},
+     {"name", "INLINE", 0x5},
+     {"value", "IPV4", 0x85},
+     {"value", "IPV6", 0x86},
+     {"value", "E164", 0x87},
+     {"value", "ALPHA", 0x88},
+     {"value", "APN", 0x89},
+     {"value", "SCODE", 0x8A},
+     {"value", "TETRA-ITSI", 0x8B},
+     {"value", "APPSRV", 0x8D,1},
+     {"value", "OBEX", 0x8E,1},
+     {"value", "MAN", 0x8C},
+     {"value", "ANALOG-MODEM", 0x90},
+     {"value", "V.120", 0x91},
+     {"value", "V.110", 0x92},
+     {"value", "X.31", 0x93},
+     {"value", "BIT-TRANSPARENT", 0x94},
+     {"value", "DIRECT-ASYNCHRONOUS-DATA-SERVICE", 0x95},
+     {"value", "PAP", 0x9A},
+     {"value", "CHAP", 0x9B},
+     {"value", "HTTP-BASIC", 0x9C},
+     {"value", "HTTP-DIGEST", 0x9D},
+     {"value", "WTLS-SS", 0x9E},
+     {"value", "MD5", 0x9F},
+     {"value", "GSM-USSD", 0xA2},
+     {"value", "GSM-SMS", 0xA3},
+     {"value", "ANSI-136-GUTS", 0xA4},
+     {"value", "IS-95-CDMA-SMS", 0xA5},
+     {"value", "IS-95-CDMA-CSD", 0xA6},
+     {"value", "IS-95-CDMA-PACKET", 0xA7},
+     {"value", "ANSI-136-CSD", 0xA8},
+     {"value", "ANSI-136-GPRS", 0xA9},
+     {"value", "GSM-CSD", 0xAA},
+     {"value", "GSM-GPRS", 0xAB},
+     {"value", "AMPS-CDPD", 0xAC},
+     {"value", "PDC-CSD", 0xAD},
+     {"value", "PDC-PACKET", 0xAE},
+     {"value", "IDEN-SMS", 0xAF},
+     {"value", "IDEN-CSD", 0xB0},
+     {"value", "IDEN-PACKET", 0xB1},
+     {"value", "FLEX/REFLEX", 0xB2},
+     {"value", "PHS-SMS", 0xB3},
+     {"value", "PHS-CSD", 0xB4},
+     {"value", "TETRA-SDS", 0xB5},
+     {"value", "TETRA-PACKET", 0xB6},
+     {"value", "ANSI-136-GHOST", 0xB7},
+     {"value", "MOBITEX-MPAK", 0xB8},
+     {"value", "CDMA2000-1X-SIMPLE-IP", 0xB9},
+     {"value", "CDMA2000-1X-MOBILE-IP", 0xBA},
+     {"value", "AUTOBAUDING", 0xC5},
+     {"value", "CL-WSP", 0xCA},
+     {"value", "CO-WSP", 0xCB},
+     {"value", "CL-SEC-WSP", 0xCC},
+     {"value", "CO-SEC-WSP", 0xCD},
+     {"value", "CL-SEC-WTA", 0xCE},
+     {"value", "CO-SEC-WTA", 0xCF},
+     {"value", "OTA-HTTP-TO", 0xD0},
+     {"value", "OTA-HTTP-TLS-TO", 0xD1},
+     {"value", "OTA-HTTP-PO", 0xD2},
+     {"value", "OTA-HTTP-TLS-PO", 0xD3},
+     {"value", ",", 0x80,1},
+     {"value", "HTTP-", 0x81,1},
+     {"value", "BASIC", 0x82},
+     {"value", "DIGEST", 0x83},
+     {"value", "AAA", 0xE0},
+     {"value", "HA", 0xE1},
+     {"value", "INLINE", 0x6}     
+};
+
+#define OMA_VALUE_TAG 0x06
+#define NUMBER_OF_OMA_ATTRIBUTES sizeof(oma_ota_attributes)/sizeof(oma_ota_attributes[0])
 #include "xml_definitions.h"
 
 /****************************************************************************
@@ -187,9 +357,9 @@
 
 static int parse_document(xmlDocPtr document, Octstr *charset, 
 			  simple_binary_t **ota_binary);
-static int parse_node(xmlNodePtr node, simple_binary_t **otabxml);    
-static int parse_element(xmlNodePtr node, simple_binary_t **otabxml);
-static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml); 
+static int parse_node(xmlNodePtr node, simple_binary_t **otabxml, int is_oma);    
+static int parse_element(xmlNodePtr node, simple_binary_t **otabxml, int is_oma);
+static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml, int is_oma); 
 static int use_inline_string(Octstr *valueos);      
 
 /***************************************************************************
@@ -246,16 +416,25 @@
                           simple_binary_t **otabxml)
 {
     xmlNodePtr node;
-
-    (*otabxml)->wbxml_version = 0x01; /* WBXML Version number 1.1  */
-    (*otabxml)->public_id = 0x01; /* Public id for an unknown document type */
+    int is_oma;
     
+    if (document->intSubset && 
+	strcmp(document->intSubset->ExternalID, "-//WAPFORUM//DTD PROV 1.0//EN") == 0) {
+	 is_oma = 1;
+	 (*otabxml)->wbxml_version = 0x03; /* WBXML Version number 1.3  */
+	 (*otabxml)->public_id = 0x0B; /* Public id for this kind of doc */	 
+    } else {
+	 (*otabxml)->wbxml_version = 0x01; /* WBXML Version number 1.1  */
+	 (*otabxml)->public_id = 0x01; /* Public id for an unknown document type */
+	 is_oma = 0;
+    }
+    (*otabxml)->code_page = 0;
     charset = octstr_create("UTF-8");
     (*otabxml)->charset = parse_charset(charset);
     octstr_destroy(charset);
-
+    
     node = xmlDocGetRootElement(document);
-    return parse_node(node, otabxml);
+    return parse_node(node, otabxml, is_oma);
 }
 
 /*
@@ -265,14 +444,14 @@
  * after that calls itself for the next child on the list.
  */
 
-static int parse_node(xmlNodePtr node, simple_binary_t **otabxml)
+static int parse_node(xmlNodePtr node, simple_binary_t **otabxml, int is_oma)
 {
     int status = 0;
     
     /* Call for the parser function of the node type. */
     switch (node->type) {
     case XML_ELEMENT_NODE:
-	status = parse_element(node, otabxml);
+	status = parse_element(node, otabxml,is_oma);
 	break;
     case XML_TEXT_NODE:
     case XML_COMMENT_NODE:
@@ -297,12 +476,12 @@
     case 0:
 
 	if (node->children != NULL)
-	    if (parse_node(node->children, otabxml) == -1)
+	    if (parse_node(node->children, otabxml,is_oma) == -1)
 		return -1;
 	break;
     case 1:
 	if (node->children != NULL)
-	    if (parse_node(node->children, otabxml) == -1)
+	    if (parse_node(node->children, otabxml,is_oma) == -1)
 		return -1;
 	parse_end(otabxml);
 	break;
@@ -316,7 +495,7 @@
     }
 
     if (node->next != NULL)
-	if (parse_node(node->next, otabxml) == -1)
+	if (parse_node(node->next, otabxml,is_oma) == -1)
 	    return -1;
 
     return 0;
@@ -330,7 +509,7 @@
  *               0, do not add an end tag (it has children)
  *              -1, an error occurred
  */
-static int parse_element(xmlNodePtr node, simple_binary_t **otabxml)
+static int parse_element(xmlNodePtr node, simple_binary_t **otabxml, int is_oma)
 {
     Octstr *name;
     size_t i;
@@ -347,7 +526,7 @@
 
     i = 0;
     while (i < NUMBER_OF_ELEMENTS) {
-        if (octstr_compare(name, octstr_imm(ota_elements[i].name)) == 0)
+        if (octstr_case_compare(name, octstr_imm(ota_elements[i].name)) == 0)
             break;
         ++i;
     }
@@ -382,7 +561,7 @@
     if (node->properties != NULL) {
 	attribute = node->properties;
 	while (attribute != NULL) {
-	    parse_attribute(attribute, otabxml);
+	    parse_attribute(attribute, otabxml,is_oma);
 	    attribute = attribute->next;
 	}
 	parse_end(otabxml);
@@ -398,15 +577,16 @@
  * chapters 8.1 and 8.2. 
  * Returns 0 when success, -1 when error.
  */
-static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml)
+static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml, int is_oma)
 {
     Octstr *name,
            *value,
            *valueos,
            *nameos;
     unsigned char ota_hex;
-    size_t i;
-
+    size_t i, lim;
+    ota_3table_t *alist;
+    
     name = octstr_create(attr->name);
 
     if (attr->children != NULL)
@@ -417,16 +597,24 @@
     if (value == NULL)
         goto error;
 
+    if (is_oma) { /* Pick right one. */
+	 alist = oma_ota_attributes;
+	 lim = NUMBER_OF_OMA_ATTRIBUTES;
+    } else {
+	 alist = ota_attributes;
+	 lim = NUMBER_OF_ATTRIBUTES;
+    }
+
     i = 0;
     valueos = NULL;
     nameos = NULL;
-    while (i < NUMBER_OF_ATTRIBUTES) {
-	nameos = octstr_imm(ota_attributes[i].name);
-        if (octstr_compare(name, nameos) == 0) {
-	    if (ota_attributes[i].value != NULL) {
-                valueos = octstr_imm(ota_attributes[i].value);
+    while (i < lim) {
+	nameos = octstr_imm(alist[i].name);
+        if (octstr_case_compare(name, nameos) == 0) {
+	    if (alist[i].value != NULL) {
+                valueos = octstr_imm(alist[i].value);
             }
-            if (octstr_compare(value, valueos) == 0) {
+            if (octstr_case_compare(value, valueos) == 0) {
 	        break;
             }
             if (octstr_compare(valueos, octstr_imm("INLINE")) == 0) {
@@ -436,15 +624,22 @@
        ++i;
     }
 
-    if (i == NUMBER_OF_ATTRIBUTES) {
+    if (i == lim) {
         warning(0, "unknown attribute %s in OTA source", 
                 octstr_get_cstr(name));
         warning(0, "its value being %s", octstr_get_cstr(value));
         goto error;
     }
 
-    ota_hex = ota_attributes[i].token;
+    ota_hex = alist[i].token;
     if (!use_inline_string(valueos)) {
+	 if (alist[i].code_page != (*otabxml)->code_page) { /* Switch code page. */
+	      output_char(0, otabxml);
+	      output_char(alist[i].code_page, otabxml);
+	      (*otabxml)->code_page = alist[i].code_page;
+	 }
+	 if (is_oma && name && octstr_case_compare(name, octstr_imm("value")) == 0)
+	      output_char(OMA_VALUE_TAG, otabxml);
         output_char(ota_hex, otabxml);
     } else {
         output_char(ota_hex, otabxml);
Index: gateway/gw/ota_prov.c
===================================================================
RCS file: /home/cvs/gateway/gw/ota_prov.c,v
retrieving revision 1.7
diff -u -r1.7 ota_prov.c
--- gateway/gw/ota_prov.c	15 Nov 2003 13:14:23 -0000	1.7
+++ gateway/gw/ota_prov.c	13 Feb 2004 14:50:26 -0000
@@ -70,12 +70,16 @@
 
 #include "gwlib/gwlib.h"
 
+#ifdef HAVE_LIBSSL
+#include <openssl/hmac.h>
+#endif
+
 #include "msg.h"
 #include "sms.h"
 #include "ota_prov.h"
 #include "ota_prov_attr.h"
 #include "ota_compiler.h"
-
+#include "wap/wsp_headers.h"
 
 /***************************************************************************
  *
@@ -87,17 +91,20 @@
  * UDH here - SAR UDH is added when (or if) we split the message. This is our
  * *specific* WDP layer.
  */
-static void ota_pack_udh(Msg **msg)
+static void ota_pack_udh(Msg **msg, Octstr *doc_type)
 {
     (*msg)->sms.udhdata = octstr_create("");
-    octstr_append_from_hex((*msg)->sms.udhdata, "060504C34FC002");
+    if (octstr_case_compare(doc_type, octstr_imm("oma-settings")) == 0) 
+      octstr_append_from_hex((*msg)->sms.udhdata, "0605040B840B84");    
+    else 
+      octstr_append_from_hex((*msg)->sms.udhdata, "060504C34FC002");    
 }
 
 
 /*
  * Our WSP headers: Push Id, PDU type, headers, charset.
  */
-static int ota_pack_push_headers(Msg **msg, Octstr *mime_type)
+static int ota_pack_push_headers(Msg **msg, Octstr *mime_type, Octstr *sec, Octstr *pin, Octstr *ota_binary)
 {    
     (*msg)->sms.msgdata = octstr_create("");
     if (octstr_case_compare(mime_type, octstr_imm("settings")) == 0) {
@@ -107,6 +114,10 @@
         octstr_format_append((*msg)->sms.msgdata, "%s", 
                              "application/x-wap-prov.browser-settings");
         octstr_append_from_hex((*msg)->sms.msgdata, "00");
+
+	/* charset UTF-8 */
+	octstr_append_from_hex((*msg)->sms.msgdata, "81EA");
+    
     } else if (octstr_case_compare(mime_type, octstr_imm("bookmarks")) == 0) {
         /* PUSH ID, PDU type, header length, value length */
         octstr_append_from_hex((*msg)->sms.msgdata, "01062D1F2B");
@@ -114,13 +125,64 @@
         octstr_format_append((*msg)->sms.msgdata, "%s", 
                              "application/x-wap-prov.browser-bookmarks");
         octstr_append_from_hex((*msg)->sms.msgdata, "00");
+	/* charset UTF-8 */
+	octstr_append_from_hex((*msg)->sms.msgdata, "81EA");
+
+    } else if (octstr_case_compare(mime_type, octstr_imm("oma-settings")) == 0) {
+	 Octstr *hdr = octstr_create(""), *mac; 
+	 unsigned char macbuf[EVP_MAX_MD_SIZE], *p;
+	 int mac_len;
+#ifdef HAVE_LIBSSL
+	 HMAC_CTX ctx;
+#endif
+	 /* PUSH ID, PDU type, header length, value length */
+	 octstr_append_from_hex((*msg)->sms.msgdata, "0106");
+	 
+	 octstr_append_from_hex(hdr, "1f2db6"); /* Content type + other type + sec param */
+	 wsp_pack_short_integer(hdr, 0x11);
+	 if (octstr_case_compare(sec, octstr_imm("netwpin")) == 0)
+	      wsp_pack_short_integer(hdr, 0x0);	      
+	 else if (octstr_case_compare(sec, octstr_imm("userpin")) == 0)
+	      wsp_pack_short_integer(hdr, 0x01);	      
+	 else if (octstr_case_compare(sec, octstr_imm("usernetwpin")) == 0)
+	      wsp_pack_short_integer(hdr, 0x02);	      
+	 else if (octstr_case_compare(sec, octstr_imm("userpinmac")) == 0)
+	      wsp_pack_short_integer(hdr, 0x03); /* XXXX Although not quite supported now.*/	      
+	 else {
+	      warning(0, "Unknown SEC pin type '%s'.", octstr_get_cstr(sec));
+	      wsp_pack_short_integer(hdr, 0x01);	      
+	 }
+	 wsp_pack_short_integer(hdr, 0x12); /* MAC */
+
+#ifdef HAVE_LIBSSL
+	 HMAC_Init(&ctx, octstr_get_cstr(pin), octstr_len(pin), EVP_sha1());
+	 p = HMAC(EVP_sha1(), octstr_get_cstr(pin), octstr_len(pin), 
+	      octstr_get_cstr(ota_binary), octstr_len(ota_binary), 
+	      macbuf, &mac_len);
+	 HMAC_CTX_cleanup(&ctx);
+#else
+	 macbuf[0] = 0;
+	 mac_len = 0;
+	 p = macbuf;
+	 warning(0, "No SSL Support, '%s' not supported!", octstr_get_cstr(mime_type));
+#endif
+	 mac = octstr_create_from_data(p, mac_len);
+	 octstr_binary_to_hex(mac,0);
+	 
+	 octstr_append(hdr,mac);
+	 octstr_append_from_hex(hdr, "00");
+	 
+	 octstr_append_uintvar((*msg)->sms.msgdata, octstr_len(hdr));
+	 octstr_append((*msg)->sms.msgdata, hdr);
+	 
+	 octstr_destroy(hdr);
+	 octstr_destroy(mac);
+	 
     } else {
         warning(0, "Unknown MIME type in OTA request, type '%s' is unsupported.", 
                 octstr_get_cstr(mime_type));
         return 0;
     }
-    /* charset UTF-8 */
-    octstr_append_from_hex((*msg)->sms.msgdata, "81EA");
 
     return 1;
 }
@@ -132,17 +194,19 @@
  */
 
 int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type, 
-                     Octstr *from, Octstr *phone_number)
+                     Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin)
 {
     Octstr *ota_binary;
 
     *msg = msg_create(sms);
     (*msg)->sms.sms_type = mt_push;
-    ota_pack_udh(msg);
-    if (!ota_pack_push_headers(msg, doc_type))
-        goto herror;
+    ota_pack_udh(msg,doc_type);
+
     if (ota_compile(ota_doc, octstr_imm("UTF-8"), &ota_binary) == -1)
         goto cerror;
+
+    if (!ota_pack_push_headers(msg, doc_type, sec, pin, ota_binary))
+        goto herror;
     octstr_format_append((*msg)->sms.msgdata, "%S", ota_binary);
     (*msg)->sms.sender = octstr_duplicate(from);
     (*msg)->sms.receiver = octstr_duplicate(phone_number);
@@ -156,18 +220,25 @@
     octstr_destroy(ota_doc);
     octstr_destroy(doc_type);
     octstr_destroy(from);
+    octstr_destroy(sec);
+    octstr_destroy(pin);
     return 0;
 
 herror:
+    octstr_destroy(ota_binary);
     octstr_destroy(ota_doc);
     octstr_destroy(doc_type);
     octstr_destroy(from);
+    octstr_destroy(sec);
+    octstr_destroy(pin);
     return -2;
 
 cerror:
     octstr_destroy(ota_doc);
     octstr_destroy(doc_type);
     octstr_destroy(from);
+    octstr_destroy(sec);
+    octstr_destroy(pin);
     return -1;
 }
 
Index: gateway/gw/ota_prov.h
===================================================================
RCS file: /home/cvs/gateway/gw/ota_prov.h,v
retrieving revision 1.3
diff -u -r1.3 ota_prov.h
--- gateway/gw/ota_prov.h	15 Nov 2003 13:14:23 -0000	1.3
+++ gateway/gw/ota_prov.h	13 Feb 2004 14:50:27 -0000
@@ -77,7 +77,7 @@
  * Return -2 when header error, -1 when compile error, 0 when no error
  */
 int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type, 
-                     Octstr *from, Octstr *phone_number);
+                     Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin);
 
 /*
  * Tokenizes a given 'ota-setting' group (without using the xml compiler) to
Index: gateway/gw/smsbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsbox.c,v
retrieving revision 1.240
diff -u -r1.240 smsbox.c
--- gateway/gw/smsbox.c	8 Dec 2003 11:25:44 -0000	1.240
+++ gateway/gw/smsbox.c	13 Feb 2004 14:51:00 -0000
@@ -2643,7 +2643,7 @@
         
     /* check does we have an external XML source for configuration */
     if ((ota_doc = http_cgi_variable(list, "text")) != NULL) {
-        
+	 Octstr *sec, *pin;
         /*
          * We are doing the XML OTA compiler mode for this request
          */
@@ -2654,9 +2654,12 @@
         } else {
 	    doc_type = octstr_duplicate(doc_type);
         }
-
+	if ((sec = http_cgi_variable(list, "sec")) == NULL)
+	     sec = octstr_imm("USERPIN");
+	if ((pin = http_cgi_variable(list, "pin")) == NULL)
+	     pin = octstr_imm("12345");
         if ((ret = ota_pack_message(&msg, ota_doc, doc_type, from, 
-                                phonenumber)) < 0) {
+                                phonenumber, sec, pin)) < 0) {
             *status = HTTP_BAD_REQUEST;
             msg_destroy(msg);
             if (ret == -2)
@@ -2770,7 +2773,7 @@
 {
     Octstr *name, *val, *ret;
     Octstr *from, *to, *id, *user, *pass, *smsc;
-    Octstr *type, *charset, *doc_type, *ota_doc;
+    Octstr *type, *charset, *doc_type, *ota_doc, *sec = NULL, *pin = NULL;
     URLTranslation *t;
     Msg *msg;
     long l;
@@ -2809,110 +2812,124 @@
 		smsc = octstr_duplicate(val);
 		octstr_strip_blanks(smsc);
 	}
+	else if (octstr_case_compare(name, octstr_imm("X-Kannel-SEC")) == 0) {
+		sec = octstr_duplicate(val);
+		octstr_strip_blanks(sec);
+	}
+	else if (octstr_case_compare(name, octstr_imm("X-Kannel-PIN")) == 0) {
+		pin = octstr_duplicate(val);
+		octstr_strip_blanks(pin);
+	}
     }
 
     /* check the username and password */
     t = authorise_username(user, pass, client_ip);
     if (t == NULL) {
-	   *status = HTTP_FORBIDDEN;
-	   ret = octstr_create("Authorization failed for sendota");
+	 *status = HTTP_FORBIDDEN;
+	 ret = octstr_create("Authorization failed for sendota");
     }
     /* let's see if we have at least a target msisdn */
     else if (to == NULL) {
-	   error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
-	   *status = HTTP_BAD_REQUEST;
-       ret = octstr_create("Wrong sendota args.");
+	 error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
+	 *status = HTTP_BAD_REQUEST;
+	 ret = octstr_create("Wrong sendota args.");
     } else {
-
-    if (urltrans_faked_sender(t) != NULL) {
-        from = octstr_duplicate(urltrans_faked_sender(t));
-    } else if (from != NULL && octstr_len(from) > 0) {
-    } else if (urltrans_default_sender(t) != NULL) {
-        from = octstr_duplicate(urltrans_default_sender(t));
-    } else if (global_sender != NULL) {
-        from = octstr_duplicate(global_sender);
-    } else {
-        *status = HTTP_BAD_REQUEST;
-        ret = octstr_create("Sender missing and no global set, rejected");
-        goto error;
-    }
-
-    /*
-     * get the content-type of the body document 
-     */
-    http_header_get_content_type(headers, &type, &charset);
-
-	if (octstr_case_compare(type, 
-        octstr_imm("application/x-wap-prov.browser-settings")) == 0) {
-        doc_type = octstr_format("%s", "settings");
-    } 
-    else if (octstr_case_compare(type, 
-             octstr_imm("application/x-wap-prov.browser-bookmarks")) == 0) {
-	    doc_type = octstr_format("%s", "bookmarks");
-    }
-
-    if (doc_type == NULL) {
-	    error(0, "%s got weird content type %s", octstr_get_cstr(sendota_url),
-              octstr_get_cstr(type));
-	    *status = HTTP_UNSUPPORTED_MEDIA_TYPE;
-	    ret = octstr_create("Unsupported content-type, rejected");
-	} else {
-
-        /* 
-         * ok, this is want we expect
-         * now lets compile the whole thing 
-         */
-        ota_doc = octstr_duplicate(body);
-
-        if ((r = ota_pack_message(&msg, ota_doc, doc_type, from, to)) < 0) {
-            *status = HTTP_BAD_REQUEST;
-            msg_destroy(msg);
-            if (r == -2) {
-                ret = octstr_create("Erroneous document type, cannot"
-                                     " compile\n");
-                goto error;
-            }
-            else if (r == -1) {
-	           ret = octstr_create("Erroneous ota source, cannot compile\n");
-               goto error;
-            }
-        }
-
-        /* we still need to check if smsc is forced for this */
-        if (urltrans_forced_smsc(t)) {
-            msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
-            if (smsc)
-                info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
-                     octstr_get_cstr(urltrans_forced_smsc(t)));
-        } else if (smsc) {
-            msg->sms.smsc_id = octstr_duplicate(smsc);
-        } else if (urltrans_default_smsc(t)) {
-            msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
-        } else
-            msg->sms.smsc_id = NULL;
-
-        info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url), 
-             id ? octstr_get_cstr(id) : "XML", octstr_get_cstr(to));
-    
-        r = send_message(t, msg); 
-        msg_destroy(msg);
-
-        if (r == -1) {
-            error(0, "sendota_request: failed");
-            *status = HTTP_INTERNAL_SERVER_ERROR;
-            ret = octstr_create("Sending failed.");
-        }
-
-        *status = HTTP_ACCEPTED;
-        ret = octstr_create("Sent.");
-    }
+	 
+	 if (urltrans_faked_sender(t) != NULL) {
+	      from = octstr_duplicate(urltrans_faked_sender(t));
+	 } else if (from != NULL && octstr_len(from) > 0) {
+	 } else if (urltrans_default_sender(t) != NULL) {
+	      from = octstr_duplicate(urltrans_default_sender(t));
+	 } else if (global_sender != NULL) {
+	      from = octstr_duplicate(global_sender);
+	 } else {
+	      *status = HTTP_BAD_REQUEST;
+	      ret = octstr_create("Sender missing and no global set, rejected");
+	      goto error;
+	 }
+	 
+	 /*
+	  * get the content-type of the body document 
+	  */
+	 http_header_get_content_type(headers, &type, &charset);
+	 
+	 if (octstr_case_compare(type, 
+				 octstr_imm("application/x-wap-prov.browser-settings")) == 0) {
+	      doc_type = octstr_format("%s", "settings");
+	 } 
+	 else if (octstr_case_compare(type, 
+				      octstr_imm("application/x-wap-prov.browser-bookmarks")) == 0) {
+	      doc_type = octstr_format("%s", "bookmarks");
+	 }
+	 else if (octstr_case_compare(type, 
+				      octstr_imm("text/vnd.wap.connectivity-xml")) == 0) {
+	      doc_type = octstr_format("%s", "oma-settings");
+	 }
+	 
+	 if (doc_type == NULL) {
+	      error(0, "%s got weird content type %s", octstr_get_cstr(sendota_url),
+		    octstr_get_cstr(type));
+	      *status = HTTP_UNSUPPORTED_MEDIA_TYPE;
+	      ret = octstr_create("Unsupported content-type, rejected");
+	 } else {
+	      
+	      /* 
+	       * ok, this is want we expect
+	       * now lets compile the whole thing 
+	       */
+	      ota_doc = octstr_duplicate(body);
+	      
+	      if ((r = ota_pack_message(&msg, ota_doc, doc_type, from, to, 
+					sec ? sec : octstr_imm("USERPIN"), 
+					pin ? pin : octstr_imm("1234"))) < 0) {
+		   *status = HTTP_BAD_REQUEST;
+		   msg_destroy(msg);
+		   if (r == -2) {
+			ret = octstr_create("Erroneous document type, cannot"
+					    " compile\n");
+			goto error;
+		   }
+		   else if (r == -1) {
+			ret = octstr_create("Erroneous ota source, cannot compile\n");
+			goto error;
+		   }
+	      }
+	      
+	      /* we still need to check if smsc is forced for this */
+	      if (urltrans_forced_smsc(t)) {
+		   msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
+		   if (smsc)
+			info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
+			     octstr_get_cstr(urltrans_forced_smsc(t)));
+	      } else if (smsc) {
+		   msg->sms.smsc_id = octstr_duplicate(smsc);
+	      } else if (urltrans_default_smsc(t)) {
+		   msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
+	      } else
+		   msg->sms.smsc_id = NULL;
+	      
+	      info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url), 
+		   id ? octstr_get_cstr(id) : "XML", octstr_get_cstr(to));
+	      
+	      r = send_message(t, msg); 
+	      msg_destroy(msg);
+	      
+	      if (r == -1) {
+		   error(0, "sendota_request: failed");
+		   *status = HTTP_INTERNAL_SERVER_ERROR;
+		   ret = octstr_create("Sending failed.");
+	      }
+	      
+	      *status = HTTP_ACCEPTED;
+	      ret = octstr_create("Sent.");
+	 }
     }    
     
-error:
+ error:
     octstr_destroy(user);
     octstr_destroy(pass);
     octstr_destroy(smsc);
-
+    
     return ret;
 }
  
Index: gateway/gw/xml_shared.h
===================================================================
RCS file: /home/cvs/gateway/gw/xml_shared.h,v
retrieving revision 1.6
diff -u -r1.6 xml_shared.h
--- gateway/gw/xml_shared.h	15 Nov 2003 13:14:23 -0000	1.6
+++ gateway/gw/xml_shared.h	13 Feb 2004 14:51:06 -0000
@@ -82,10 +82,11 @@
  * XML binary type not containing a string table. This is used for SI and SL.
  */
 struct simple_binary_t {
-    unsigned char wbxml_version;
-    unsigned char public_id;
-    unsigned long charset;
-    Octstr *binary;
+     unsigned char wbxml_version;
+     unsigned char public_id;
+     unsigned long charset;
+     Octstr *binary;
+     int code_page;
 };
 
 /*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.