[FYI] Correction of some ppg bugs

Aarno Syvänen <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi List,

I add cvs diff to correct some ppg bugs (I could not reproduce some 
mentioned in the list,
with my Mac, that is).

Following ones are included:

a) do not add Push-Flag header when there are no flags
b) fix eternal loop when parsing transport padding. thanks to
     Zohar for pointing this.
c) remove Host header from push sms.
d) add configuration variables concatenation and max-messages to wapbox,
      for push sms. Default values are true and 10, so nobody should 
change
      anything.
e) Add all push id (both well known and reserved) mentioned in wina 
page.
f)  Smsc value in configuration file has now higher priority than one 
defined
      in a cgi variable. This makes using linked Kannels with different 
smscs
      possible.
g) Fixed a memory leak in gwlib/http.c
h) Added new command line options, Now sending binary content should be
      possible.
i) Tokenize only wsp 1.3 headers.
j) Handle Encoding.version as defined in the specs.

Comments ?
cvs.diff (application/octet-stream, 32.8 KB)
Index: gw/wap_push_ota.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_ota.c,v
retrieving revision 1.17
diff -b -B -u -r1.17 wap_push_ota.c
--- gw/wap_push_ota.c	13 Feb 2003 10:32:01 -0000	1.17
+++ gw/wap_push_ota.c	26 May 2003 08:29:01 -0000
@@ -332,7 +332,8 @@
 }
 
 /*
- * Add push flag into push headers. Push flag is defined in otaa, p. 17-18.
+ * Add push flag into push headers. Push flag is defined in ota, p. 17-18.
+ * If there is no flags set, no Push-Flag header is added.
  */
 static List *add_push_flag(WAPEvent *e)
 {
@@ -377,9 +378,11 @@
     push_flag = 0;
     push_flag = push_flag | authenticated | trusted | last;
     
+    if (push_flag) {
     buf = octstr_format("%d", push_flag);
     http_header_add(headers, "Push-Flag", octstr_get_cstr(buf)); 
     octstr_destroy(buf);
+    }
 
     return headers;
 }
Index: gw/wap_push_pap_compiler.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_pap_compiler.c,v
retrieving revision 1.28
diff -b -B -u -r1.28 wap_push_pap_compiler.c
--- gw/wap_push_pap_compiler.c	28 Mar 2003 13:03:49 -0000	1.28
+++ gw/wap_push_pap_compiler.c	26 May 2003 08:29:01 -0000
@@ -757,8 +757,9 @@
     }
 
     if (i == NUM_ELEMENTS) {
+        debug("wap.push.pap.compiler", 0, "PAP COMPILER: unknown element:");
+        octstr_dump(name, 0);
         octstr_destroy(name);
-        debug("wap.push.pap.compiler", 0, "PAP COMPILER: unknown element");
         return -2;
     }
 
Index: gw/wap_push_pap_mime.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_pap_mime.c,v
retrieving revision 1.5
diff -b -B -u -r1.5 wap_push_pap_mime.c
--- gw/wap_push_pap_mime.c	4 Sep 2002 09:05:06 -0000	1.5
+++ gw/wap_push_pap_mime.c	26 May 2003 08:29:01 -0000
@@ -200,7 +200,7 @@
 
 static long parse_transport_padding(Octstr *mime_content, long pos)
 {
-    while (islwspchar(octstr_get_char(mime_content, 0)))
+    while (islwspchar(octstr_get_char(mime_content, pos)))
         ++pos;
 
     return pos;
Index: gw/wap_push_ppg.c
===================================================================
RCS file: /home/cvs/gateway/gw/wap_push_ppg.c,v
retrieving revision 1.53
diff -b -B -u -r1.53 wap_push_ppg.c
--- gw/wap_push_ppg.c	20 Mar 2003 14:11:49 -0000	1.53
+++ gw/wap_push_ppg.c	26 May 2003 08:29:02 -0000
@@ -266,6 +266,7 @@
                              Octstr **boundary);
 static void change_header_value(List **push_headers, char *name, char *value);
 static void remove_mime_headers(List **push_headers);
+static void remove_link_headers(List **push_headers);
 
 /*
  * Communicating with pi.
@@ -374,6 +375,7 @@
          octstr_destroy(ppg_deny_ip);
          octstr_destroy(ppg_allow_ip);
          octstr_destroy(global_sender);
+         octstr_destroy(ppg_default_smsc);
 
          gwthread_join_every(http_read_thread);
 #ifdef HAVE_LIBSSL
@@ -745,6 +747,7 @@
         
         http_remove_hop_headers(push_headers);
         remove_mime_headers(&push_headers);
+        remove_link_headers(&push_headers);
 
         if (!headers_acceptable(push_headers, &content_header)) {
 	        warning(0,  "PPG: Unparsable push headers, the request"
@@ -2670,7 +2673,23 @@
     "wta.ua", 
     "mms.ua", 
     "push.syncml", 
-    "loc.ua" 
+    "loc.ua",
+    "syncml.dm",
+    "drm.ua",
+    "emn.ua",
+    "wv.ua",
+    "x-wap-microsoft:localcontent.ua",
+    "x-wap-microsoft:IMclient.ua",
+    "x-wap-docomo:imode.mail.ua",
+    "x-wap-docomo:imode.mr.ua",
+    "x-wap-docomo:imode.mf.ua",
+    "x-motorola:location.ua",
+    "x-motorola:now.ua",
+    "x-motorola:otaprov.ua",
+    "x-motorola:browser.ua",
+    "x-motorola:splash.ua",
+    "x-wap-nai:mvsw.command",
+    "x-wap-openwave:iota.ua" 
 };
 
 #define NUMBER_OF_WINA_URIS sizeof(wina_uri)/sizeof(wina_uri[0])
@@ -2680,14 +2699,9 @@
  * First check do we a header with an app-encoding field and a coded value. 
  * If not, try to find push application id from table of wina approved values.
  * Return coded value value of application id in question, or an error code:
- *        -1, error
+ *        -1, no coded value (but defaults may be applied)
  *         0, * (meaning any application acceptable)
- *         1, push.sia
- *         2, wml.ua
- *         3, wta.ua 
- *         4, mms.ua
- *         5, push.syncml 
- *         6, loc.ua 
+ *         greater or equal as 1: code for this application id 
  */
 static long parse_appid_header(Octstr **appid_content)
 {
@@ -2844,12 +2858,21 @@
 
 /*
  * Some application level protocols may use MIME headers. This may cause problems
- * to them. 
+ * to them. (MIME version is a mandatory header).
  */
 static void remove_mime_headers(List **push_headers)
 {
     http_header_remove_all(*push_headers, "MIME-Version");
 }
+
+/*
+ * There are headers used only for HTTP POST pi->ppg. (For debugging, mainly.)
+ */
+static void remove_link_headers(List **push_headers)
+{
+    http_header_remove_all(*push_headers, "Host");
+}
+
 
 /*
  * Badmessage-response element is redefined in pap, implementation note, 
Index: gw/wapbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/wapbox.c,v
retrieving revision 1.157
diff -b -B -u -r1.157 wapbox.c
--- gw/wapbox.c	27 Mar 2003 08:55:01 -0000	1.157
+++ gw/wapbox.c	26 May 2003 08:29:02 -0000
@@ -49,6 +49,10 @@
 int wsp_smart_errors = 0;
 Octstr *device_home = NULL;
 
+/* Controlling segmentation of sms messages sent by wapbox (push related).*/
+int concatenation = 0;
+long max_messages = 10;
+
 #ifdef HAVE_WTLS_OPENSSL
 RSA* private_key = NULL;
 X509* x509_cert = NULL;
@@ -176,6 +180,8 @@
      * error information instread of signaling using the HTTP reply codes
      */
     cfg_get_bool(&wsp_smart_errors, grp, octstr_imm("smart-errors"));
+    cfg_get_bool(&concatenation, grp, octstr_imm("concatenation"));
+    cfg_get_integer(&max_messages, grp, octstr_imm("max-messages"));
 
     /* configure the 'wtls' group */
 #if (HAVE_WTLS_OPENSSL)
@@ -396,13 +402,13 @@
         } else {
 	    msg = pack_sms_datagram(dgram);
             msg_sequence = counter_increase(sequence_counter) & 0xff;
-            msg_len = octstr_len(msg->sms.msgdata);
-            max_msgs = (msg_len / MAX_SMS_OCTETS) + 1; 
-            sms_datagrams = sms_split(msg, NULL, NULL, NULL, NULL, 1, 
-                                      msg_sequence, max_msgs, MAX_SMS_OCTETS);
-
-            while ((part = list_extract_first(sms_datagrams)) != NULL)
+            /*msg_len = octstr_len(msg->sms.msgdata);
+            max_msgs = (msg_len / MAX_SMS_OCTETS) + 1;*/ 
+            sms_datagrams = sms_split(msg, NULL, NULL, NULL, NULL, concatenation, 
+                                      msg_sequence, max_messages, MAX_SMS_OCTETS);
+            while ((part = list_extract_first(sms_datagrams)) != NULL) {
 	            write_to_bearerbox(part);
+            }
 
             list_destroy(sms_datagrams, NULL);
             msg_destroy(msg);
Index: gw/smsc/smsc_http.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_http.c,v
retrieving revision 1.18
diff -b -B -u -r1.18 smsc_http.c
--- gw/smsc/smsc_http.c	19 May 2003 07:35:58 -0000	1.18
+++ gw/smsc/smsc_http.c	26 May 2003 08:29:02 -0000
@@ -297,7 +297,8 @@
 	octstr_format_append(url, "&account=%E:%E", sms->sms.service, sms->sms.account);
     if (sms->sms.smsc_id) /* proxy the smsc-id to the next instance */
 	octstr_format_append(url, "&smsc=%S", sms->sms.smsc_id);
-
+    debug("", 0, "not url-encoded msg is");
+    msg_dump(sms, 0);
     headers = list_create();
     debug("smsc.http.kannel", 0, "HTTP[%s]: Start request",
           octstr_get_cstr(conn->id));
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.85
diff -b -B -u -r1.85 cfg.def
--- gwlib/cfg.def	3 Apr 2003 12:18:18 -0000	1.85
+++ gwlib/cfg.def	26 May 2003 08:29:02 -0000
@@ -77,6 +77,8 @@
     OCTSTR(syslog-level)
     OCTSTR(smart-errors)
     OCTSTR(access-log)
+    OCTSTR(concatenation)
+    OCTSTR(max-messages)
 )
 
 
@@ -245,6 +247,7 @@
     OCTSTR(notification-addr)
     OCTSTR(msg-id-type)
     OCTSTR(no-dlr)
+    OCTSTR(billing-information)
 )
 
 
Index: gwlib/http.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/http.c,v
retrieving revision 1.190
diff -b -B -u -r1.190 http.c
--- gwlib/http.c	3 Apr 2003 12:18:36 -0000	1.190
+++ gwlib/http.c	26 May 2003 08:29:02 -0000
@@ -2374,12 +2374,14 @@
         if (octstr_case_compare(current_name, name) == 0) {
             value = octstr_copy(os, colon + 1, octstr_len(os));
             octstr_strip_blanks(value);
+            octstr_destroy(current_name);
             return value;
         }
+        octstr_destroy(current_name);
         ++i;
     }
     
-    return value;
+    return NULL;
 }
 
 List *http_header_duplicate(List *headers)
Index: test/test_ppg.c
===================================================================
RCS file: /home/cvs/gateway/test/test_ppg.c,v
retrieving revision 1.23
diff -b -B -u -r1.23 test_ppg.c
--- test/test_ppg.c	19 May 2003 07:37:52 -0000	1.23
+++ test/test_ppg.c	26 May 2003 08:29:03 -0000
@@ -27,15 +27,20 @@
            num_urls = 0,
            wait = 0,
            use_headers = 0,
-           use_config = 0;
+           use_config = 0,
+           accept_binary = 0, 
+           use_numeric = 0,
+           use_string = 0;
 static double wait_seconds = 0.0;
 static Counter *counter = NULL;
 static char **push_data = NULL;
 static char *boundary = NULL;
 static Octstr *content_flag = NULL;
 static Octstr *appid_flag = NULL;
+static Octstr *appid_string = NULL;
 static Octstr *content_transfer_encoding = NULL;
 static Octstr *connection = NULL;
+static Octstr *delimiter = NULL;
 
 enum { SSL_CONNECTION_OFF = 0,
        DEFAULT_NUMBER_OF_RELOGS = 2};
@@ -90,43 +95,75 @@
     cfg_destroy(cfg);
 }
 
-static void add_push_application_id(List **push_headers, Octstr *appid_flag)
+static void add_delimiter(Octstr **content)
 {
-    if (octstr_compare(appid_flag, octstr_imm("any")) == 0)
+    if (octstr_compare(delimiter, octstr_imm("crlf")) == 0) {
+        octstr_format_append(*content, "%c", '\r');
+    }
+
+    octstr_format_append(*content, "%c", '\n');
+}
+
+static void add_push_application_id(List **push_headers, Octstr *appid_flag,
+                                    int use_string)
+{
+    if (use_string) {
+        http_header_add(*push_headers, "X-WAP-Application-Id", 
+                        octstr_get_cstr(appid_string));
+        return;
+    }
+
+    if (octstr_compare(appid_flag, octstr_imm("any")) == 0) {
+        if (!use_numeric)
         http_header_add(*push_headers, "X-WAP-Application-Id", 
                         "http://www.wiral.com:*");
-    else if (octstr_compare(appid_flag, octstr_imm("ua")) == 0)
+        else
+            http_header_add(*push_headers, "X-WAP-Application-Id", "0");
+    } else if (octstr_compare(appid_flag, octstr_imm("ua")) == 0) {
+        if (!use_numeric)
         http_header_add(*push_headers, "X-WAP-Application-Id", 
                         "http://www.wiral.com:wml.ua");
-    else if (octstr_compare(appid_flag, octstr_imm("mms")) == 0)
+        else
+            http_header_add(*push_headers, "X-WAP-Application-Id", "2");
+    } else if (octstr_compare(appid_flag, octstr_imm("mms")) == 0) {
+        if (!use_numeric)
         http_header_add(*push_headers, "X-WAP-Application-Id", 
                         "mms.ua");
-    else if (octstr_compare(appid_flag, octstr_imm("scrap")) == 0)
+        else
+            http_header_add(*push_headers, "X-WAP-Application-Id", "4");
+    } else if (octstr_compare(appid_flag, octstr_imm("scrap")) == 0) {
+        if (!use_numeric)
         http_header_add(*push_headers, "X-WAP-Application-Id", 
                         "no appid at all");
+        else
+            http_header_add(*push_headers, "X-WAP-Application-Id", 
+                            "this is not a numeric header");
+    }
 }
 
 static void add_content_type(Octstr *content_flag, Octstr **wap_content)
 {
     if (octstr_compare(content_flag, octstr_imm("wml")) == 0)
         *wap_content = octstr_format("%s", 
-            "Content-Type: text/vnd.wap.wml\r\n");
+            "Content-Type: text/vnd.wap.wml");
     else if (octstr_compare(content_flag, octstr_imm("si")) == 0)
 	    *wap_content = octstr_format("%s",
-            "Content-Type: text/vnd.wap.si\r\n");
+            "Content-Type: text/vnd.wap.si");
     else if (octstr_compare(content_flag, octstr_imm("sl")) == 0)
 	    *wap_content = octstr_format("%s",
-            "Content-Type: text/vnd.wap.sl\r\n");
+            "Content-Type: text/vnd.wap.sl");
     else if (octstr_compare(content_flag, octstr_imm("multipart")) == 0)
         *wap_content = octstr_format("%s",
             "Content-Type: multipart/related; boundary=fsahgwruijkfldsa\r\n");
     else if (octstr_compare(content_flag, octstr_imm("mms")) == 0) 
         *wap_content = octstr_format("%s", 
-            "Content-Type: application/vnd.wap.mms-message\r\n"); 
+            "Content-Type: application/vnd.wap.mms-message"); 
     else if (octstr_compare(content_flag, octstr_imm("scrap")) == 0)
-        *wap_content = octstr_format("%s", "no type at all\r\n"); 
+        *wap_content = octstr_format("%s", "no type at all"); 
     else if (octstr_compare(content_flag, octstr_imm("nil")) == 0)
         *wap_content = octstr_create("");
+    if (octstr_len(*wap_content) > 0)
+        add_delimiter(wap_content);
 }
 
 static void add_content_transfer_encoding_type(Octstr *content_flag, 
@@ -136,7 +173,9 @@
 	     return;
 
     if (octstr_compare(content_flag, octstr_imm("base64")) == 0)
-	    octstr_append_cstr(wap_content, "Content-transfer-encoding: base64\r\n");
+	octstr_append_cstr(wap_content, "Content-transfer-encoding: base64");
+
+    add_delimiter(&wap_content);
 }
 
 static void add_connection_header(Octstr *connection, Octstr *wap_content)
@@ -145,9 +184,11 @@
         return;
 
     if (octstr_compare(connection, octstr_imm("close")) == 0)
-        octstr_format_append(wap_content, "%s", "Connection: close\r\n");
+        octstr_format_append(wap_content, "%s", "Connection: close");
     else if (octstr_compare(connection, octstr_imm("keep-alive")) == 0) 
-        octstr_format_append(wap_content, "%s", "Connection: keep-alive\r\n");
+        octstr_format_append(wap_content, "%s", "Connection: keep-alive");
+
+    add_delimiter(&wap_content);
 }
 
 static void transfer_encode (Octstr *cte, Octstr *content)
@@ -180,12 +221,10 @@
     Octstr *part_delimiter;
 
     part_delimiter = octstr_create("");
-    octstr_format_append(part_delimiter, "%c", '\r');
-    octstr_format_append(part_delimiter, "%c", '\n');
+    add_delimiter(&part_delimiter);
     octstr_format_append(part_delimiter, "%s", "--");
     octstr_append(part_delimiter, boundary);
-    octstr_format_append(part_delimiter, "%c", '\r');
-    octstr_format_append(part_delimiter, "%c", '\n');
+    add_delimiter(&part_delimiter);
     
     return part_delimiter;
 }
@@ -195,14 +234,11 @@
     Octstr *close_delimiter;
 
     close_delimiter = octstr_create("");
-    octstr_format_append(close_delimiter, "%c", '\r');
-    octstr_format_append(close_delimiter, "%c", '\n');
+    add_delimiter(&close_delimiter);
     octstr_format_append(close_delimiter, "%s", "--");
     octstr_append(close_delimiter, boundary);
     octstr_format_append(close_delimiter, "%s", "--");
-    octstr_format_append(close_delimiter, "%c", '\r');
-    octstr_format_append(close_delimiter, "%c", '\n');
-    
+    add_delimiter(&close_delimiter);
 
     return close_delimiter;
 }
@@ -222,7 +258,7 @@
                         octstr_get_cstr(mos = make_multipart_value(boundary)));
     if (use_headers)
         http_add_basic_auth(push_headers, username, password);
-    add_push_application_id(&push_headers, appid_flag);
+    add_push_application_id(&push_headers, appid_flag, use_string);
 
     octstr_destroy(mos);
 
@@ -288,18 +324,30 @@
                                            wap_content);
         add_connection_header(connection, wap_content);
 
+        /* Read the content file. (To be pushed)*/
         if ((wap_file_content = 
                 octstr_read_file(octstr_get_cstr(content_file))) == NULL)
 	         panic(0, "Stopping");
+        if (accept_binary) {
+            octstr_delete_matching(wap_file_content, octstr_imm(" "));
+            octstr_delete_matching(wap_file_content, octstr_imm("\n"));
+            octstr_delete_matching(wap_file_content, octstr_imm("\r"));
+            if (!octstr_is_all_hex(wap_file_content))
+                panic(0, "non-hex chars in the content file, cannot continue");
+            octstr_hex_to_binary(wap_file_content);            
+        }
 
 	    transfer_encode (content_transfer_encoding, wap_file_content);
         octstr_append(wap_content, wap_file_content);
         octstr_destroy(wap_file_content);
 
-        pap_content = octstr_format("%s", "Content-Type: application/xml\r\n");
+        /* Read the control file. (To control pushing)*/
+        pap_content = octstr_format("%s", "Content-Type: application/xml");
+        add_delimiter(&pap_content);
         if ((pap_file_content = 
                 octstr_read_file(octstr_get_cstr(pap_file))) ==  NULL)
 	        panic(0, "Stopping");
+        
         octstr_append(pap_content, pap_file_content);
         octstr_destroy(pap_file_content);
 
@@ -309,6 +357,8 @@
         push_content = octstr_create("");
         octstr_append(push_content, 
             bpos = make_part_delimiter(octstr_imm(boundary)));
+        /*octstr_append(push_content, octstr_imm("\r\n"));*/ /* Do we accept an additional 
+                                                          * clrf ? */
         octstr_append(push_content, pap_content);
         octstr_append(push_content, bpos);
         octstr_destroy(bpos);
@@ -574,6 +624,13 @@
     info(0, "-a application id");
     info(0, "Define the client application that will handle the push. Any,"); 
     info(0, "ua, mms, nil and scrap accepted, default ua.");
+    info(0, "-n");
+    info(0, "if set, use numeric appid values instead of string ones. For");
+    info(0, "instance, '4' instead of 'mms.ua'. Default is off.");
+    info(0, "-s string");
+    info(0, "supply application id as a plain string. For instance"); 
+    info(0, "-s x-wap-application-id:mms.ua equals -a ua. Default is");
+    info(0, "x-wap-application-id:mms.ua.");
     info(0, "-b");
     info(0, "If true, send username/password in headers. Default false");
     info(0, "-v number");
@@ -598,6 +655,12 @@
     info(0, "Default: read components from files");
     info(0, "-t");
     info(0, "number of threads, maximum 1024, default 1");
+    info(0, "-B");
+    info(0, "accept binary push content. Default: off.");
+    info(0, "Binary content consist of hex numbers. In addition, crs, lfs and");
+    info(0, "spaces are accepted, and ignored.");
+    info(0, "-d value");
+    info(0, "set delimiter to be used. Accepted values crlf and lf. Default crlf.");
 }
 
 int main(int argc, char **argv)
@@ -614,7 +677,7 @@
     gwlib_init();
     num_threads = 1;
 
-    while ((opt = getopt(argc, argv, "Hhbv:qr:t:c:a:i:e:k:")) != EOF) {
+    while ((opt = getopt(argc, argv, "HhBbnv:qr:t:c:a:i:e:k:d:s:")) != EOF) {
         switch(opt) {
 	    case 'v':
 	        log_set_output_level(atoi(optarg));
@@ -652,7 +715,7 @@
                     octstr_compare(content_flag, octstr_imm("mms")) != 0 &&
                     octstr_compare(content_flag, octstr_imm("scrap")) != 0 &&
                     octstr_compare(content_flag, 
-                    octstr_imm("multipart")) != 0){
+                    octstr_imm("multipart")) != 0) {
 		        octstr_destroy(content_flag);
 		        error(0, "TEST_PPG: Content type not known");
 		        help();
@@ -674,14 +737,21 @@
            }
 	    break;
 
+            case 'n':
+                use_numeric = 1;
+            break;
+
+            case 's':
+                appid_string = octstr_create(optarg);
+                use_string = 1;
+            break;
+
 	    case 'e':
 		    content_transfer_encoding = octstr_create(optarg);
-            if (octstr_compare(content_transfer_encoding, 
-                               octstr_imm("base64")) != 0) {
+                if (octstr_compare(content_transfer_encoding, octstr_imm("base64")) != 0) {
 		        octstr_destroy(content_transfer_encoding);
 		        error(0, "TEST_PPG: unknown content transfer" 
-                      " encoding \"%s\"",
-			          octstr_get_cstr(content_transfer_encoding));
+                      " encoding \"%s\"", octstr_get_cstr(content_transfer_encoding));
 		        help();
                 exit(1);
 		    }
@@ -690,8 +760,7 @@
 	    case 'k':
 	        connection = octstr_create(optarg);
             if (octstr_compare(connection, octstr_imm("close")) != 0 && 
-                    octstr_compare(connection, 
-                        octstr_imm("keep-alive")) != 0) {
+                        octstr_compare(connection, octstr_imm("keep-alive")) != 0) {
 		        octstr_destroy(connection);
 		        error(0, "TEST_PPG: Connection-header unacceptable");
 		        help();
@@ -707,6 +776,21 @@
 	        use_headers = 1;
 	    break;
 
+            case 'B':
+                accept_binary = 1;
+            break;
+
+            case 'd':
+                delimiter = octstr_create(optarg);
+                if (octstr_compare(delimiter, octstr_imm("crlf")) != 0 &&
+                        octstr_compare(delimiter, octstr_imm("lf")) != 0) {
+                    octstr_destroy(delimiter);
+                    error(0, "illegal d value");
+                    help();
+                    exit(1);
+                }
+            break;
+
 	    case '?':
 	    default:
 	        error(0, "TEST_PPG: Invalid option %c", opt);
@@ -730,6 +814,12 @@
     if (appid_flag == NULL)
         appid_flag = octstr_imm("ua");
 
+    if (appid_string == NULL)
+        appid_string = octstr_imm("x-wap-application-id: wml.ua");
+
+    if (delimiter == NULL)
+        delimiter = octstr_imm("crlf");
+
     if (use_hardcoded) {
         username = octstr_imm("troo");
         password = octstr_imm("far");
@@ -792,6 +882,8 @@
     octstr_destroy(password);
     octstr_destroy(push_url);
     octstr_destroy(connection);
+    octstr_destroy(delimiter);
+    octstr_destroy(appid_string);
     counter_destroy(counter);
     gwlib_shutdown();
 
Index: wap/wsp_headers.c
===================================================================
RCS file: /home/cvs/gateway/wap/wsp_headers.c,v
retrieving revision 1.6
diff -b -B -u -r1.6 wsp_headers.c
--- wap/wsp_headers.c	19 Oct 2002 10:07:39 -0000	1.6
+++ wap/wsp_headers.c	26 May 2003 08:29:03 -0000
@@ -250,7 +250,8 @@
     return convert_q_value(c);
 }
 
-/* Version-value is defined in 8.4.2.3 */
+/* Version-value is defined in 8.4.2.3. Encoding-Version uses coding
+ * defined in this chapter, see 8.4.2.70.  */
 static Octstr *unpack_version_value(long value)
 {
     Octstr *result;
@@ -269,6 +270,19 @@
     return result;
 }
 
+static Octstr *unpack_encoding_version(ParseContext *context)
+{
+    int ch;
+
+    ch = parse_get_char(context);
+    if (ch < 128) {
+        warning(0, "WSP: bad Encoding-Version value");
+        return NULL;
+    }
+
+    return unpack_version_value(((long) ch) - 128);
+}
+
 /* Called with the parse limit set to the end of the parameter data,
  * and decoded containing the unpacked header line so far.
  * Parameter is defined in 8.4.2.4. */
@@ -1155,6 +1169,10 @@
             decoded = unpack_disposition(context);
             break;
 
+        case WSP_HEADER_ENCODING_VERSION:
+            decoded = unpack_encoding_version(context);
+            break;
+
         default:
             if (headername) {
                 warning(0, "Did not expect value-length with "
@@ -1331,6 +1349,7 @@
 static int pack_transfer_encoding(Octstr *packet, Octstr *value);
 static int pack_uri(Octstr *packet, Octstr *value);
 static int pack_warning(Octstr *packet, Octstr *value);
+static int pack_version_value(Octstr *packet, Octstr *value);
 
 /* LIST is a comma-separated list such as is described in the "#rule"
  * entry of RFC2616 section 2.1. */
@@ -1396,10 +1415,11 @@
         { WSP_HEADER_WARNING, pack_warning, LIST },
         { WSP_HEADER_WWW_AUTHENTICATE, pack_challenge, BROKEN_LIST },
         { WSP_HEADER_CONTENT_DISPOSITION, pack_content_disposition, 0 },
-        { WSP_HEADER_PUSH_FLAG, pack_integer_string, 0},
-        { WSP_HEADER_X_WAP_CONTENT_URI, pack_uri, 0},
-        { WSP_HEADER_X_WAP_INITIATOR_URI, pack_uri, 0},
-        { WSP_HEADER_X_WAP_APPLICATION_ID, pack_integer_string, 0}
+        { WSP_HEADER_PUSH_FLAG, pack_integer_string, 0 },
+        { WSP_HEADER_X_WAP_CONTENT_URI, pack_uri, 0 },
+        { WSP_HEADER_X_WAP_INITIATOR_URI, pack_uri, 0 },
+        { WSP_HEADER_X_WAP_APPLICATION_ID, pack_integer_string, 0 },
+        { WSP_HEADER_ENCODING_VERSION, pack_version_value, 0 }
     };
 
 static Parameter *parm_create(Octstr *key, Octstr *value)
@@ -1743,7 +1763,7 @@
     return -1;
 }
 
-static void pack_version_value(Octstr *packed, Octstr *version)
+static int pack_version_value(Octstr *packed, Octstr *version)
 {
     long major, minor;
     long pos;
@@ -1763,10 +1783,11 @@
     }
 
     pack_short_integer(packed, major << 4 | minor);
-    return;
+    return 0;
 
 usetext:
     pack_text(packed, version);
+    return 0;
 }
 
 static int pack_constrained_value(Octstr *packed, Octstr *text, long value)
Index: wap/wsp_session.c
===================================================================
RCS file: /home/cvs/gateway/wap/wsp_session.c,v
retrieving revision 1.13
diff -b -B -u -r1.13 wsp_session.c
--- wap/wsp_session.c	14 May 2002 11:05:08 -0000	1.13
+++ wap/wsp_session.c	26 May 2003 08:29:03 -0000
@@ -87,6 +87,10 @@
 static unsigned long next_wsp_session_id(void);
 
 static List *make_capabilities_reply(WSPMachine *m);
+static List *make_reply_headers(WSPMachine *m);
+static int is_default_version(WSPMachine *m);
+static int is_higher_version(WSPMachine *m);
+static int is_lower_version(WSPMachine *m);
 static Octstr *make_connectreply_pdu(WSPMachine *m);
 static Octstr *make_resume_reply_pdu(WSPMachine *m, List *headers);
 static WSP_PDU *make_confirmedpush_pdu(WAPEvent *e);
@@ -946,11 +950,91 @@
 	return caps;
 }
 
+static int is_default_version(WSPMachine *m)
+{
+    Octstr *request_version;
+
+    request_version = http_header_value(m->http_headers, octstr_imm("Encoding-Version"));
+    if (request_version == NULL) {
+        return 1;
+    } else {
+        octstr_destroy(request_version);
+        return 0;
+    }
+}
+
+static int is_higher_version(WSPMachine *m)
+{
+    Octstr *request_version;
+
+    request_version = http_header_value(m->http_headers, octstr_imm("Encoding-Version"));
+    if (request_version && octstr_compare(request_version, octstr_imm("1.1")) != 0 &&
+            octstr_compare(request_version, octstr_imm("1.2")) != 0 &&
+            octstr_compare(request_version, octstr_imm("1.3")) != 0) {
+        octstr_destroy(request_version);
+        return 1;
+    } else {
+        octstr_destroy(request_version);
+        return 0;
+    }
+}
+
+static int is_lower_version(WSPMachine *m)
+{
+    Octstr *request_version;
+
+    request_version = http_header_value(m->http_headers, octstr_imm("Encoding-Version"));
+    if (request_version && (octstr_compare(request_version, octstr_imm("1.1")) == 0 ||
+            octstr_compare(request_version, octstr_imm("1.2")) == 0)) {
+        octstr_destroy(request_version);
+        return 1;        
+    } else {
+        octstr_destroy(request_version);
+        return 0;
+    }
+}
+
+static List *make_reply_headers(WSPMachine *m)
+{
+    List *headers;
+    Octstr *encoding_version;
+    Octstr *request_version;
+
+    /* Add all server wsp level hop-by-hop headers. Currently only 
+     * Encoding-Version, as defined by wsp, chapter 8.4.2.70. 
+     * What headers belong to which version is defined in appendix A,
+     * table 39.. 
+    encoding_version = request_version = NULL;
+     * Essentially, if the client sends us an Encoding-Version
+     * higher than ours (1.3) we send our version number to it,
+     * if it is lower, we left version number intact. */
+    /* First the case that we have no Encoding-Version header at all. 
+     * This case we must assume that the client supports version 1.2
+     * or lower. */
+    if (is_default_version(m)) {
+        encoding_version = octstr_create("1.2");
+    } else if (is_higher_version(m)) {
+        encoding_version = octstr_create("1.3");
+    } else if (is_lower_version(m)) {
+        request_version = http_header_value(m->http_headers, octstr_imm("Encoding-Version"));
+        encoding_version = octstr_duplicate(request_version);
+        octstr_destroy(request_version);
+    }  else {   
+        encoding_version = octstr_create("1.3");
+    }
+
+    headers = http_create_empty_headers();
+    http_header_add(headers, "Encoding-Version", octstr_get_cstr(encoding_version));
+    octstr_destroy(encoding_version);
+
+    return headers;
+}
 
 static Octstr *make_connectreply_pdu(WSPMachine *m) {
 	WSP_PDU *pdu;
 	Octstr *os;
 	List *caps;
+        List *reply_headers;
 	
 	pdu = wsp_pdu_create(ConnectReply);
 
@@ -959,7 +1043,10 @@
 	caps = make_capabilities_reply(m);
 	pdu->u.ConnectReply.capabilities = wsp_cap_pack_list(caps);
 	wsp_cap_destroy_list(caps);
-	pdu->u.ConnectReply.headers = NULL;
+
+        reply_headers = make_reply_headers(m);
+	pdu->u.ConnectReply.headers = wsp_headers_pack(reply_headers, 0);
+        http_destroy_headers(reply_headers);
 	
 	os = wsp_pdu_pack(pdu);
 	wsp_pdu_destroy(pdu);
Index: wap/wsp_strings.def
===================================================================
RCS file: /home/cvs/gateway/wap/wsp_strings.def,v
retrieving revision 1.6
diff -b -B -u -r1.6 wsp_strings.def
--- wap/wsp_strings.def	4 Sep 2002 09:16:31 -0000	1.6
+++ wap/wsp_strings.def	26 May 2003 08:29:03 -0000
@@ -109,7 +109,7 @@
 NSTRING("Encoding-Version", WSP_HEADER_ENCODING_VERSION)
 )
 
-/* Table 40. Content Type Assignments */
+/* Table 40. Content Type Assignments. Only to wsp version 1.3. */
 LINEAR(content_type,
 STRING("*/*")
 STRING("text/*")
@@ -166,14 +166,14 @@
 STRING("application/vnd.wap.sia")
 STRING("text/vnd.wap.connectivity-xml")
 STRING("application/vnd.wap.connectivity-wbxml")
-STRING("application/pkcs7-mime")
+/*STRING("application/pkcs7-mime")
 STRING("application/vnd.wap.hashed-certificate")
 STRING("application/vnd.wap.signed-certificate")
 STRING("application/vnd.wap.cert-response")
 STRING("application/xhtml+xml")
 STRING("application/wml+xml")
 STRING("text/css")
-STRING("application/vnd.wap.mms-message") 
+STRING("application/vnd.wap.mms-message")*/ 
 )
 
 /* Table 42, Character Set Assignment (partial) */
@@ -465,6 +465,22 @@
 ASSIGN("mms.ua", 0x04) 
 ASSIGN("push.syncml", 0x05) 
 ASSIGN("loc.ua", 0x06) 
+ASSIGN("syncml.dm", 0x07)
+ASSIGN("drm.ua", 0x08)
+ASSIGN("emn.ua", 0x09)
+ASSIGN("wv.ua", 0x0A)
+ASSIGN("x-wap-microsoft:localcontent.ua", 0x8000)
+ASSIGN("x-wap-microsoft:IMclient.ua", 0x8001)
+ASSIGN("x-wap-docomo:imode.mail.ua", 0x8002)
+ASSIGN("x-wap-docomo:imode.mr.ua", 0x8003)
+ASSIGN("x-wap-docomo:imode.mf.ua", 0x8004)
+ASSIGN("x-motorola:location.ua", 0x8005)
+ASSIGN("x-motorola:now.ua", 0x8006)
+ASSIGN("x-motorola:otaprov.ua", 0x8007)
+ASSIGN("x-motorola:browser.ua", 0x8008)
+ASSIGN("x-motorola:splash.ua", 0x8009)
+ASSIGN("x-wap-nai:mvsw.command", 0x800B)
+ASSIGN("x-wap-openvawe:iota.ua", 0x8010)
 )
 
 /**** More preprocessor magic ****/
Index: wap/wsp_unit.c
===================================================================
RCS file: /home/cvs/gateway/wap/wsp_unit.c,v
retrieving revision 1.12
diff -b -B -u -r1.12 wsp_unit.c
--- wap/wsp_unit.c	13 Feb 2003 10:34:09 -0000	1.12
+++ wap/wsp_unit.c	26 May 2003 08:29:03 -0000
@@ -192,7 +192,10 @@
 
 /*
  * We do not set TUnitData.ind's SMS-specific fields here, because we do not
- * support sending results to the phone over SMS.
+ * support sending results to the phone over SMS. Wsp, chapter 8.4.1 states
+ * that "that each peer entity is always associated with an encoding version.".
+ * So we add Encoding-Version when we are sending something to the client.
+ * (This includes push, which is not directly mentioned in chapter 8.4.2.70). 
  */
 static WAPEvent *pack_into_result_datagram(WAPEvent *event) {
 	WAPEvent *datagram;
@@ -204,6 +207,8 @@
 	gw_assert(event->type == S_Unit_MethodResult_Req);
 	p = &event->u.S_Unit_MethodResult_Req;
 
+        http_header_add(p->response_headers, "Encoding-Version", "1.3");
+
 	pdu = wsp_pdu_create(Reply);
 	pdu->u.Reply.status = wsp_convert_http_status_to_wsp_status(p->status);
 	pdu->u.Reply.headers = wsp_headers_pack(p->response_headers, 1);
@@ -236,6 +241,10 @@
 
         gw_assert(event->type == S_Unit_Push_Req);
         debug("wap.wsp.unit", 0, "WSP_UNIT: Connectionless push accepted");
+
+        http_header_add(event->u.S_Unit_Push_Req.push_headers, 
+                        "Encoding-Version", "1.3");
+
         pdu = wsp_pdu_create(Push);
 	pdu->u.Push.headers = wsp_headers_pack(
             event->u.S_Unit_Push_Req.push_headers, 1);
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.