[PATCH] SMPP data_coding enforcing for UCS-2 messages

Stipe Tolj <[email protected]> Wed, 08 Nov 2017 14:12:37 +0100
Newsgroups gmane.comp.mobile.kannel.devel
Organization Kannel Software Foundation (KSF)
Message-ID <[email protected]>
Hi list,

we already support "forcing" the SMPP defined 'data_coding' values to be 
proxied via the meta-data construct, in order to allows converting from 
UTF-8 to any designated target encoding for the SMPP based upstream.

But we couldn't handle the same for input that was presented with 
coding=2 (UCS-2, aka UTF-16BE).

The patch fixes this missing piece and allows to convert any UCS-2 
message to the relevant SMPP data_coding values above 0x04, which may be 
used by various SMSCs to ease the transmission of language specific content.

The patch doesn't change any default behavior. Please review and comment.

Thanks,
Stipe

-- 
Best Regards,
Stipe Tolj

-------------------------------------------------------------------
DÃŒsseldorf, NRW, Germany

Kannel Foundation                 tolj.org system architecture
http://www.kannel.org/            http://www.tolj.org/

stolj at kannel.org               st at tolj.org
-------------------------------------------------------------------
smpp-data-coding.diff (text/plain, 5.8 KB)
Index: gw/smsc/smsc_smpp.c
===================================================================
--- gw/smsc/smsc_smpp.c	(revision 5190)
+++ gw/smsc/smsc_smpp.c	(working copy)
@@ -81,8 +81,10 @@
 #include "meta_data.h"
 #include "load.h"
 
-#define SMPP_DEFAULT_CHARSET "UTF-8"
+#define SMPP_DEFAULT_CHARSET        "UTF-8"
+#define SMPP_DEFAULT_UCS2_CHARSET   "UTF-16BE"
 
+
 enum smpp_pdu_dump_format {
     SMPP_PDU_DUMP_MULTILINE = 1,
     SMPP_PDU_DUMP_LINE      = 2
@@ -434,7 +436,7 @@
 }
 
 
-static void handle_mt_dcs(Octstr *short_message, int data_coding)
+static void handle_mt_dcs(Octstr *short_message, char *internal, int data_coding)
 {
     /*
      * Keep in mind that we do transcode the encoding here,
@@ -448,45 +450,45 @@
      */
     switch (data_coding) {
         case 0x01: /* ASCII or IA5 */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ASCII") != 0) {
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to ASCII, will leave as is");
+            if (charset_convert(short_message, internal, "ASCII") != 0) {
+                error(0, "Failed to convert msgdata from %s to ASCII, will leave as is", internal);
             }
             break;
         case 0x03: /* ISO-8859-1 (aka latin1) */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "LATIN1") != 0) {
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to LATIN1, will leave as is");
+            if (charset_convert(short_message, internal, "LATIN1") != 0) {
+                error(0, "Failed to convert msgdata from %s to LATIN1, will leave as is", internal);
             }
             break;
         case 0x02: /* 8 bit binary - do nothing */
         case 0x04: /* 8 bit binary - do nothing */
             break;
         case 0x05: /* Japanese, JIS(X 0208-1990) */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "JIS_X0208-1990") != 0)
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Japanese (JIS-X0208-1990), "
-                         "will leave as is");
+            if (charset_convert(short_message, internal, "JIS_X0208-1990") != 0)
+                error(0, "Failed to convert msgdata from %s to Japanese (JIS-X0208-1990), "
+                         "will leave as is", internal);
             break;
         case 0x06: /* Cyrllic - iso-8859-5 */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ISO-8859-5") != 0)
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Cyrllic (ISO-8859-5), "
-                         "will leave as is");
+            if (charset_convert(short_message, internal, "ISO-8859-5") != 0)
+                error(0, "Failed to convert msgdata from %s to Cyrllic (ISO-8859-5), "
+                         "will leave as is", internal);
             break;
         case 0x07: /* Hebrew iso-8859-8 */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ISO-8859-8") != 0)
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Hebrew (ISO-8859-8), "
-                         "will leave as is");
+            if (charset_convert(short_message, internal, "ISO-8859-8") != 0)
+                error(0, "Failed to convert msgdata from %s to Hebrew (ISO-8859-8), "
+                         "will leave as is", internal);
             break;
         case 0x08: /* unicode UCS-2, don't convert here anything. */
             break;
         case 0x0D: /* Japanese, Extended Kanji JIS(X 0212-1990) */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "JIS_X0212-1990") != 0)
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Japanese (JIS-X0212-1990), "
-                         "will leave as is");
+            if (charset_convert(short_message, internal, "JIS_X0212-1990") != 0)
+                error(0, "Failed to convert msgdata from %s to Japanese (JIS-X0212-1990), "
+                         "will leave as is", internal);
             break;
         case 0x0E: /* Korean, KS C 5601 - now called KS X 1001, convert to Unicode */
-            if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "KSC_5601") != 0 &&
-                    charset_convert(short_message, SMPP_DEFAULT_CHARSET, "KSC5636") != 0)
-                error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Korean (KSC_5601/KSC5636), "
-                         "will leave as is");
+            if (charset_convert(short_message, internal, "KSC_5601") != 0 &&
+                    charset_convert(short_message, internal, "KSC5636") != 0)
+                error(0, "Failed to convert msgdata from %s to Korean (KSC_5601/KSC5636), "
+                         "will leave as is", internal);
             break;
         case 0x00: /* GSM 03.38 */
         default:
@@ -1064,7 +1066,7 @@
             /*
              * convert to a forced data_coding value, or GSM 03.38 if not
              */
-            handle_mt_dcs(pdu->u.submit_sm.short_message, data_coding);
+            handle_mt_dcs(pdu->u.submit_sm.short_message, SMPP_DEFAULT_CHARSET, data_coding);
             if (data_coding != -1)
                 pdu->u.submit_sm.data_coding = data_coding;
         } else if (pdu->u.submit_sm.data_coding == 0 && smpp->alt_charset) {
@@ -1077,6 +1079,13 @@
                           SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_charset));
         }
     }
+    else if (msg->sms.coding == DC_UCS2 && data_coding > 0x04) {
+        /*
+         * convert to a forced data_coding value, which is given in UCS-2
+         */
+        handle_mt_dcs(pdu->u.submit_sm.short_message, SMPP_DEFAULT_UCS2_CHARSET, data_coding);
+        pdu->u.submit_sm.data_coding = data_coding;
+    }
 
     /* prepend udh if present */
     if (octstr_len(msg->sms.udhdata)) {