Hi again,

Here's the lot split into logical pieces (and synchronized with todays CVS).


kannel.mysql.escape.diff:
 * Escapes strings in dlr_mysql_add INSERT query.


kannel.smpp.cp1252.diff:
 * Changed internal non-unicode character set to CP1252 in smsbox and SMPP


kannel.smpp.errors.diff:
 * Added recognition of all possible SMPP errors (including SMPPv5)


kannel.mblox.errors.diff:
 * Added recognition of all mBlox SMPP errors


kannel.smpp.pack_udh.diff
* Added pack_udh option to SMPP. When set, Message is packed with the UDH into binary data when sent.


Everything but the pack_udh patch have been thoroughly tested with millions of messages for seveal months. pack_udh have only been tested with some 100-200 different messages.


Med venlig hilsen / Best regards

Peter Christensen

Developer
------------------
Cool Systems ApS

Tel: +45 2888 1600
 @ : [EMAIL PROTECTED]
www: www.coolsystems.dk


Stipe Tolj wrote:
Peter Christensen wrote:

Hi,

I'd like to address a couple things now that a new kannel release near:


1. Some while ago, I reported problems within the dlr_mysql_add function. If the entry->timestamp, entry->source, or entry->url contains some unfortunate characters (most significantly <'>), the SQL query gets broken and the DLRs are wasted. After a while, the first patch was submitted, but as it used mysql_real_escape_string, it would potentially require an additional MySQL connection (or something - don't remember what the exact problem was), so it was not committed, and another patch was promised in a near future. Apparently this patch never came, however, and I see that the current CVS is still not escaping the strings.

correct, I have that escaping version of mysql here and it's scheduled for commit to 1.5.0 devel, since I won't have the time to test it that extensively to ensure stability for 1.4.1 stable.

Any thoughts on this?

I could post the patch and let the list confirm via votes that it should or should not go to 1.4.1 stable?

So, question is: What is the cause of the delay, and are you interested in my own patch, which uses mysql_escape_string instead of mysql_real_escape_string?

The cuase is lack in tme... at least from my side... I'm pushing, but I have several "construction sides" at Kannel side, including the more "important" WTP-SAR issue.

If you have ready code for that post to the mailing list. I will do the same, so we can leaverage work time.

I admit that problems related to this is somewhat rare (most likely cause for errors would be an SMS with <'> in the originator string), but since it can be fixed relatively easy, I see no reason why NOT to do it. Although mysql_escape_string does not look at the character set (unlike mysql_real_escape_string), I still believe that it will be better to use it than to do nothing.

absolutely agree'ing... following the main strategy: stability and safe.

2. I've noticed that the charset_gsm_to_latin1 and charset_latin1_to_gsm functions actually uses windows-1252 as character set, but at least the SMPP gateway uses iso-8859-1 internally, which practically removes support for the € (euro) sign. This is probably also a problem within other gateways. If interesseted, I can supply a patch.

yep... Please comment the patch in detail, so that anyone of us who is reviewing has an easier job.

But in relation to that, there is one thing which have begun to annoy me. By restricting to the windows-1252 character set when transmitting with the GSM character set, you remove support for the 10 Greek characters which is support by GSM. And as it always is when something is potentially possible, there will always be some large annoying customer who wants support for that particular feature. This last bit is only an observation and nothing more. I realize that fixing this (preferable by using UTF-8 or UCS-2BE as internal character set regardless of the output character set), would require a significantly amount of recoding within almost every part of the kannel software package.

yep.

The reason while I have not attached any patches to this mail (although I have made quite a few changes), is that my own patch is really a combination of several patches, which is not in sync with the CVS. But if people are interested, I will update the patch and post the relevant bits.

yes, please try to keep clean logical patchsets. Which means one patchset = one logical change. It's too hard to trace several issues in just one single patchset.

The whole patch does the following:
 SMPP:
* Add support for mBlox operator and billing identifier (Not my own work) * Add support for ALL SMPPv5 error codes, including mBlox specific codes. (That is, recognize them and translate to human readable text)
  * Use CP1252 instead of ISO-8859-1 as internal charset
* Added pack_udh parameter. When set, messages are sent as packed GSM data when UDH is present. (A few gateways require this)

 MySQL:
  * Escapes strings in dlr_mysql_add

 run_kannel_box:
* Added waitpid after kill to avoid false terminations (the init scripts reports that kannel is terminated, while bearerbox is actually stuck within a connect call. - happens relatively often). With later CVS releases this didn't seem to work, so instead I've added some functionaly to the init script instead.

Stipe


diff -Nru gateway/gw/dlr_mysql.c gateway.new/gw/dlr_mysql.c
--- gateway/gw/dlr_mysql.c	2006-01-10 13:53:29.000000000 +0100
+++ gateway.new/gw/dlr_mysql.c	2006-01-10 16:05:29.000000000 +0100
@@ -140,9 +140,38 @@
     dlr_db_fields_destroy(fields);
 }
 
+char *_mysql_escape_string(const char *string) {
+	unsigned long int size, length;
+	char *buffer;
+	length = strlen(string);
+	size = (strlen(string) << 1) + 1;
+	if ((buffer = (char *)gw_malloc(size)) == NULL) {
+		error(0, "MYSQL: Error allocating buffer for string");
+		return NULL;
+	}
+	else {
+		mysql_escape_string(buffer, string, length);
+		return buffer;
+	}
+}
+
 static void dlr_mysql_add(struct dlr_entry *entry)
 {
     Octstr *sql;
+	char *safe_ts, *safe_src, *safe_url;
+
+	if ((safe_ts = _mysql_escape_string(octstr_get_cstr(entry->timestamp))) == NULL)
+		return;
+	if ((safe_src = _mysql_escape_string(octstr_get_cstr(entry->source))) == NULL) {
+		gw_free(safe_ts);
+		return;
+	}
+	if ((safe_url = _mysql_escape_string(octstr_get_cstr(entry->url))) == NULL) {
+		gw_free(safe_ts);
+		gw_free(safe_src);
+		return;
+	}
+
 
     sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES "
                         "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d');",
@@ -152,10 +181,14 @@
                         octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->field_url),
                         octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_boxc),
                         octstr_get_cstr(fields->field_status),
-                        octstr_get_cstr(entry->smsc), octstr_get_cstr(entry->timestamp), octstr_get_cstr(entry->source),
-                        octstr_get_cstr(entry->destination), octstr_get_cstr(entry->service), octstr_get_cstr(entry->url),
+                        octstr_get_cstr(entry->smsc), safe_ts, safe_src,
+                        octstr_get_cstr(entry->destination), octstr_get_cstr(entry->service), safe_url,
                         entry->mask, octstr_get_cstr(entry->boxc_id), 0);
 
+	gw_free(safe_ts);
+	gw_free(safe_src);
+	gw_free(safe_url);
+
 
     mysql_update(sql);
 
diff -Nru gateway/gw/smsbox.c gateway.new/gw/smsbox.c
--- gateway/gw/smsbox.c	2005-12-09 03:14:31.000000000 +0100
+++ gateway.new/gw/smsbox.c	2006-01-10 15:57:05.000000000 +0100
@@ -3654,9 +3654,9 @@
 
 	if (coding == DC_7BIT) {
 	    /*
-	     * For 7 bit, convert to ISO-8859-1
+	     * For 7 bit, convert to CP1252
 	     */
-	    if (octstr_recode (octstr_imm ("ISO-8859-1"), charset, body) < 0) {
+	    if (octstr_recode (octstr_imm ("CP1252"), charset, body) < 0) {
 		resultcode = -1;
 	    }
 	} else if (coding == DC_UCS2) {
diff -Nru gateway/gw/smsc/smsc_smpp.c gateway.new/gw/smsc/smsc_smpp.c
--- gateway/gw/smsc/smsc_smpp.c	2005-12-18 21:21:16.000000000 +0100
+++ gateway.new/gw/smsc/smsc_smpp.c	2006-01-10 15:58:41.000000000 +0100
@@ -78,6 +78,8 @@
 #include "sms.h"
 #include "dlr.h"
 
+#define SMPP_CHARSET	"CP1252"
+
 /*
  * Select these based on whether you want to dump SMPP PDUs as they are
  * sent and received or not. Not dumping should be the default in at least
@@ -490,9 +492,9 @@
              * unless it was specified binary, ie. UDH indicator was detected
              */
             if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {
-                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), "ISO-8859-1") != 0)
+                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_CHARSET) != 0)
                     error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
-                             octstr_get_cstr(smpp->alt_charset), "ISO-8859-1");
+                             octstr_get_cstr(smpp->alt_charset), SMPP_CHARSET);
                 msg->sms.coding = DC_7BIT;
             } else { /* assume GSM 03.38 7-bit alphabet */
                 charset_gsm_to_latin1(msg->sms.msgdata);
@@ -640,9 +642,9 @@
              * unless it was specified binary, ie. UDH indicator was detected
              */
             if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {
-                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), "ISO-8859-1") != 0)
+                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_CHARSET) != 0)
                     error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
-                             octstr_get_cstr(smpp->alt_charset), "ISO-8859-1");
+                             octstr_get_cstr(smpp->alt_charset), SMPP_CHARSET);
                 msg->sms.coding = DC_7BIT;
             } else { /* assume GSM 03.38 7-bit alphabet */
                 charset_gsm_to_latin1(msg->sms.msgdata);
@@ -845,10 +847,10 @@
             /*
              * convert to the given alternative charset
              */
-            if (charset_convert(pdu->u.submit_sm.short_message, "ISO-8859-1",
+            if (charset_convert(pdu->u.submit_sm.short_message, SMPP_CHARSET,
                                 octstr_get_cstr(smpp->alt_charset)) != 0)
                 error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
-                             "ISO-8859-1", octstr_get_cstr(smpp->alt_charset));
+                             SMPP_CHARSET, octstr_get_cstr(smpp->alt_charset));
         }
     }
 
diff -Nru gateway/gw/smsc/smpp_pdu.c gateway.new/gw/smsc/smpp_pdu.c
--- gateway/gw/smsc/smpp_pdu.c	2005-09-02 15:05:15.000000000 +0200
+++ gateway.new/gw/smsc/smpp_pdu.c	2006-01-10 16:10:36.000000000 +0100
@@ -462,6 +462,8 @@
 	    return "Incorrect BIND Status for given command";
         case SMPP_ESME_RALYNBD:
 	    return "ESME Already in Bound State";
+	case SMPP_ESME_RINVPRTFLG:
+	    return "Invalid Priority Flag";
         case SMPP_ESME_RINVREGDLVFLG:
 	    return "Invalid Registered Delivery Flag";
         case SMPP_ESME_RSYSERR:
@@ -469,35 +471,118 @@
         case SMPP_ESME_RINVSRCADR:
 	    return "Invalid Source Address";
         case SMPP_ESME_RINVDSTADR:
-	    return "Invalid Dest Address";
+	    return "Invalid Destination Address";
         case SMPP_ESME_RBINDFAIL:
 	    return "Bind Failed";
         case SMPP_ESME_RINVPASWD:
 	    return "Invalid Password";
         case SMPP_ESME_RINVSYSID:
 	    return "Invalid System ID";
+	case SMPP_ESME_RCANCELFAIL:
+	    return "Cancel SM Failed";
+	case SMPP_ESME_RREPLACEFAIL:
+	    return "Replace SM Failed";
         case SMPP_ESME_RMSGQFUL:
 	    return "Message Queue Full";
+	case SMPP_ESME_RINVSERTYP:
+	    return "Invalid Service Type";
+	case SMPP_ESME_RINVNUMDESTS:
+	    return "Invalid number of destinations";
+	case SMPP_ESME_RINVDLNAME:
+	    return "Invalid Distribution List Name";
+	case SMPP_ESME_RINVDESTFLAG:
+	    return "Destination flag is invalid";
+	case SMPP_ESME_RINVSUBREP:
+	    return "Submit w/replace not supported/allowed";
         case SMPP_ESME_RINVESMCLASS:
 	    return "Invalid esm_class field data";
+	case SMPP_ESME_RCNTSUBDL:
+	    return "Cannot Submit to Distribution List";
+	case SMPP_ESME_RSUBMITFAIL:
+	    return "Submit failed";
         case SMPP_ESME_RINVSRCTON:
-	    return "Invalid Source Address TON"; 
+	    return "Invalid Source address TON"; 
+	case SMPP_ESME_RINVSRCNPI:
+	    return "Invalid Source address NPI";
+	case SMPP_ESME_RINVDSTTON:
+	    return "Invalid Destination address TON";
+	case SMPP_ESME_RINVDSTNPI:
+	    return "Invalid Destination address NPI";
+	case SMPP_ESME_RINVSYSTYP:
+	    return "Invalid system_type field";
+	case SMPP_ESME_RINVREPFLAG:
+	    return "Invalid replace_if_present flag";
+	case SMPP_ESME_RINVNUMMSGS:
+	    return "Invalid number of messages";
         case SMPP_ESME_RTHROTTLED:
 	    return "Throttling error";
         case SMPP_ESME_RINVSCHED:
 	    return "Invalid Scheduled Delivery Time";
         case SMPP_ESME_RINVEXPIRY:
 	    return "Invalid message validity period";
+	case SMPP_ESME_RINVDFTMSGID:
+	    return "Predefined Message ID is Invalid or specific predefined message was not found";
         case SMPP_ESME_RX_T_APPN:
 	    return "ESME Receiver Temporary App Error Code";
         case SMPP_ESME_RX_P_APPN:
 	    return "ESME Receiver Permanent App Error Code";
         case SMPP_ESME_RX_R_APPN:
 	    return "ESME Receiver Reject Message Error Code";
-        case SMPP_ESME_ROPTPARNOTALLWD:
-	    return "Optional Parameter not allowed";
+	case SMPP_ESME_RQUERYFAIL:
+	    return "query_sm request failed";
+	case SMPP_ESME_RINVTLVSTREAM:
+	    return "Error in optional part of the PDU Body";
+	case SMPP_ESME_RTLVNOTALLWD:
+	    return "TLV not allowed";
+	case SMPP_ESME_RINVTLVLEN:
+	    return "Invalid Parameter Length";
+	case SMPP_ESME_RMISSINGTLV:
+	    return "Expected TLV missing";
+	case SMPP_ESME_RINVTLVVAL:
+	    return "Invalid TLV value";
+	case SMPP_ESME_RDELIVERYFAILURE:
+	    return "Transaction Delivery Failure";
 	case SMPP_ESME_RUNKNOWNERR:
 	    return "Unknown Error";
+	case SMPP_ESME_RSERTYPUNAUTH:
+	    return "ESME Not authorized to use specified service_type";
+	case SMPP_ESME_RPROHIBITED:
+	    return "ESME Prohibited from using specified operation";
+	case SMPP_ESME_RSERTYPUNAVAIL:
+	    return "Specified service_type is unavailable";
+	case SMPP_ESME_RSERTYPDENIED:
+	    return "Specified service_Type is denied";
+	case SMPP_ESME_RINVDCS:
+	    return "Invalid Data Coding Scheme";
+	case SMPP_ESME_RINVSRCADDRSUBUNIT:
+	    return "Source Address Sub unit is invalid";
+	case SMPP_ESME_RINVDSTADDRSUBUNIT:
+	    return "Destination Address Sub unit is invalid";
+	case SMPP_ESME_RINVBCASTFREQINT:
+	    return "Broadcast Frequency Interval is invalid";
+	case SMPP_ESME_RINVBCASTALIAS_NAME:
+	    return "Broadcast Alias Name is invalid";
+	case SMPP_ESME_RINVBCASTAREAFMT:
+	    return "Broadcast Area Format is invalid";
+	case SMPP_ESME_RINVNUMBCAST_AREAS:
+	    return "Number of Broadcast Areas is invalid";
+	case SMPP_ESME_RINVBCASTCNTTYPE:
+	    return "Broadcast Content Type is invalid";
+	case SMPP_ESME_RINVBCASTMSGCLASS:
+	    return "Broadcast Message Class is invalid";
+	case SMPP_ESME_RBCASTFAIL:
+	    return "broadcast_sm operation failed";
+	case SMPP_ESME_RBCASTQUERYFAIL:
+	    return "broadcast_query_sm operation failed";
+	case SMPP_ESME_RBCASTCANCELFAIL:
+	    return "broadcast_cancel_sm operation failed";
+	case SMPP_ESME_RINVBCAST_REP:
+	    return "Number of Repeated Broadcasts is invalid";
+	case SMPP_ESME_RINVBCASTSRVGRP:
+	    return "Broadcast Service Group is invalid";
+	case SMPP_ESME_RINVBCASTCHANIND:
+	    return "Broadcast Channel Indicator is invalid";
+
 	default:
 	    return "Unknown/Reserved";
     }
diff -Nru gateway/gw/smsc/smpp_pdu.h gateway.new/gw/smsc/smpp_pdu.h
--- gateway/gw/smsc/smpp_pdu.h	2005-02-11 16:35:48.000000000 +0100
+++ gateway.new/gw/smsc/smpp_pdu.h	2006-01-10 16:10:50.000000000 +0100
@@ -161,24 +161,67 @@
     SMPP_ESME_RINVCMDID = 0x00000003,
     SMPP_ESME_RINVBNDSTS = 0x00000004,
     SMPP_ESME_RALYNBD = 0x00000005,
+    SMPP_ESME_RINVPRTFLG = 0x00000006,
     SMPP_ESME_RINVREGDLVFLG = 0x00000007,
     SMPP_ESME_RSYSERR = 0x00000008,
     SMPP_ESME_RINVSRCADR = 0x0000000A,
     SMPP_ESME_RINVDSTADR = 0x0000000B,
+    SMPP_ESME_RINVMSGID = 0x0000000C,
     SMPP_ESME_RBINDFAIL = 0x0000000D,
     SMPP_ESME_RINVPASWD = 0x0000000E,
     SMPP_ESME_RINVSYSID = 0x0000000F,
+    SMPP_ESME_RCANCELFAIL = 0x00000011,
+    SMPP_ESME_RREPLACEFAIL = 0x00000013,
     SMPP_ESME_RMSGQFUL   = 0x00000014,
+    SMPP_ESME_RINVSERTYP = 0x00000015,
+    SMPP_ESME_RINVNUMDESTS = 0x00000033,
+    SMPP_ESME_RINVDLNAME = 0x00000034,
+    SMPP_ESME_RINVDESTFLAG = 0x00000040,
+    SMPP_ESME_RINVSUBREP = 0x00000042,
     SMPP_ESME_RINVESMCLASS = 0x00000043,
+    SMPP_ESME_RCNTSUBDL = 0x00000044,
+    SMPP_ESME_RSUBMITFAIL = 0x00000045,
     SMPP_ESME_RINVSRCTON = 0x00000048,
+    SMPP_ESME_RINVSRCNPI = 0x00000049,
+    SMPP_ESME_RINVDSTTON = 0x00000050,
+    SMPP_ESME_RINVDSTNPI = 0x00000051,
+    SMPP_ESME_RINVSYSTYP = 0x00000053,
+    SMPP_ESME_RINVREPFLAG = 0x00000054,
+    SMPP_ESME_RINVNUMMSGS = 0x00000055,
     SMPP_ESME_RTHROTTLED = 0x00000058,
     SMPP_ESME_RINVSCHED = 0x00000061,
     SMPP_ESME_RINVEXPIRY = 0x00000062,
+    SMPP_ESME_RINVDFTMSGID = 0x00000063,
     SMPP_ESME_RX_T_APPN = 0x00000064,
     SMPP_ESME_RX_P_APPN = 0x00000065,
     SMPP_ESME_RX_R_APPN = 0x00000066,
-    SMPP_ESME_ROPTPARNOTALLWD = 0x000000C1,
-    SMPP_ESME_RUNKNOWNERR = 0x000000FF
+    SMPP_ESME_RQUERYFAIL = 0x00000067,
+    SMPP_ESME_RINVTLVSTREAM = 0x000000C0,
+    SMPP_ESME_RTLVNOTALLWD = 0x000000C1,
+    SMPP_ESME_RINVTLVLEN = 0x000000C2,
+    SMPP_ESME_RMISSINGTLV = 0x000000C3,
+    SMPP_ESME_RINVTLVVAL = 0x000000C4,
+    SMPP_ESME_RDELIVERYFAILURE = 0x000000FE,
+    SMPP_ESME_RUNKNOWNERR = 0x000000FF,
+    SMPP_ESME_RSERTYPUNAUTH = 0x00000100,
+    SMPP_ESME_RPROHIBITED = 0x00000101,
+    SMPP_ESME_RSERTYPUNAVAIL = 0x00000102,
+    SMPP_ESME_RSERTYPDENIED = 0x00000103,
+    SMPP_ESME_RINVDCS = 0x00000104,
+    SMPP_ESME_RINVSRCADDRSUBUNIT = 0x00000105,
+    SMPP_ESME_RINVDSTADDRSUBUNIT = 0x00000106,
+    SMPP_ESME_RINVBCASTFREQINT = 0x00000107,
+    SMPP_ESME_RINVBCASTALIAS_NAME = 0x00000108,
+    SMPP_ESME_RINVBCASTAREAFMT = 0x00000109,
+    SMPP_ESME_RINVNUMBCAST_AREAS = 0x0000010A,
+    SMPP_ESME_RINVBCASTCNTTYPE = 0x0000010B,
+    SMPP_ESME_RINVBCASTMSGCLASS = 0x0000010C,
+    SMPP_ESME_RBCASTFAIL = 0x0000010D,
+    SMPP_ESME_RBCASTQUERYFAIL = 0x0000010E,
+    SMPP_ESME_RBCASTCANCELFAIL = 0x0000010F,
+    SMPP_ESME_RINVBCAST_REP = 0x00000110,
+    SMPP_ESME_RINVBCASTSRVGRP = 0x00000111,
+    SMPP_ESME_RINVBCASTCHANIND = 0x00000112,
 };
 
 SMPP_PDU *smpp_pdu_create(unsigned long type, unsigned long seq_no);
diff -Nru gateway.new/gw/smsc/smpp_pdu.c gateway.new.2/gw/smsc/smpp_pdu.c
--- gateway.new/gw/smsc/smpp_pdu.c	2006-01-10 16:10:36.000000000 +0100
+++ gateway.new.2/gw/smsc/smpp_pdu.c	2006-01-10 16:10:18.000000000 +0100
@@ -582,7 +582,78 @@
 	    return "Broadcast Service Group is invalid";
 	case SMPP_ESME_RINVBCASTCHANIND:
 	    return "Broadcast Channel Indicator is invalid";
-
+	    
+	case SMPP_ESME_RMBLOX_NUMBER_BLACKLISTED:
+	    return "mBlox: Number blacklisted in system";
+	case SMPP_ESME_RMBLOX_CLIENT_BLACKLISTED:
+	    return "mBlox: Client blacklisted in system";
+	case SMPP_ESME_RMBLOX_PREFIX_BLACKLISTED:
+	    return "mBlox: Prefix blacklisted in system";
+	case SMPP_ESME_RMBLOX_INVALID_ACCOUNT:
+	    return "mBlox: Invalid account error";
+	case SMPP_ESME_RMBLOX_NOT_APPLICABLE1:
+	case SMPP_ESME_RMBLOX_NOT_APPLICABLE2:
+	    return "mBlox: No long applicable";
+	case SMPP_ESME_RMBLOX_DESTINATION_BUSY:
+	    return "mBlox: Destination Busy, please try again";
+	case SMPP_ESME_RMBLOX_REPLY_TYPE_ERROR:
+	    return "mBlox: Reply Type Error";
+	case SMPP_ESME_RMBLOX_MSIP_SYNTAX_ERROR:
+	    return "mBlox: MSIP Syntax Error";
+	case SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL1:
+	case SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL2:
+	case SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL3:
+	    return "mBlox: System unavailable";
+	case SMPP_ESME_RMBLOX_PROFILE_ERROR:
+	    return "mBlox: Profile Error";
+	case SMPP_ESME_RMBLOX_USERNAME_NOT_SET:
+	    return "mBlox: Username not set";
+	case SMPP_ESME_RMBLOX_BINARY_NOT_ALLOWED:
+	    return "mBlox: Binary messages not allowed on profile";
+	case SMPP_ESME_RMBLOX_TEMP_SYSTEM_FAIL:
+	    return "mBlox: Temporary System Failure, please retry";
+	case SMPP_ESME_RMBLOX_UNROUTABLE1:
+	case SMPP_ESME_RMBLOX_UNROUTABLE2:
+	case SMPP_ESME_RMBLOX_UNROUTABLE3:
+	case SMPP_ESME_RMBLOX_UNROUTABLE4:
+	case SMPP_ESME_RMBLOX_UNROUTABLE5:
+	case SMPP_ESME_RMBLOX_UNROUTABLE6:
+	case SMPP_ESME_RMBLOX_UNROUTABLE7:
+	case SMPP_ESME_RMBLOX_UNROUTABLE8:
+	case SMPP_ESME_RMBLOX_UNROUTABLE9:
+	    return "mBlox: Number unroutable, do not retry";
+	case SMPP_ESME_RMBLOX_TEMP_UNROUTABLE1:
+	case SMPP_ESME_RMBLOX_TEMP_UNROUTABLE2:
+	case SMPP_ESME_RMBLOX_TEMP_UNROUTABLE3:
+	case SMPP_ESME_RMBLOX_TEMP_UNROUTABLE4:
+	case SMPP_ESME_RMBLOX_TEMP_UNROUTABLE5:
+	    return "mBlox: Number temporarily unroutable, please try again";
+	case SMPP_ESME_RMBLOX_CURRENT_UNROUTABLE:
+	    return "mBlox: Number unroutable on current settings. Do not retry";
+	case SMPP_ESME_RMBLOX_LOCAL_DELIVERER_FAIL:
+	    return "mBlox: Unable to send on local deliverer";
+	case SMPP_ESME_RMBLOX_CANT_FIND_ORIGINATOR:
+	    return "mBlox: Cannot find originator index. Do not retry";
+	case SMPP_ESME_RMBLOX_DESTINATION_RETRY:
+	    return "mBlox: Destination please try again";
+	case SMPP_ESME_RMBLOX_NUMBER_BLOCKED1:
+	case SMPP_ESME_RMBLOX_NUMBER_BLOCKED2:
+	    return "mBlox: Number is blocked. Do not retry";
+	case SMPP_ESME_RMBLOX_BILLING_REF_ERROR:
+	    return "mBlox: Billing Reference Error. Do not retry";
+	case SMPP_ESME_RMBLOX_THROTTLING:
+	    return "mBlox: Throttling - Please try again";
+	case SMPP_ESME_RMBLOX_BAD_SEQUENCE:
+	    return "mBlox: Bad sequence";
+	case SMPP_ESME_RMBLOX_CLIENT_ID_ERROR1:
+	case SMPP_ESME_RMBLOX_CLIENT_ID_ERROR2:
+	    return "mBlox: Error when supplying a client id";
+	case SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR1:
+	case SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR2:
+	case SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR3:
+	case SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR4:
+	    return "mBlox: Routing error for PSMS";
+	    
 	default:
 	    return "Unknown/Reserved";
     }
diff -Nru gateway.new/gw/smsc/smpp_pdu.h gateway.new.2/gw/smsc/smpp_pdu.h
--- gateway.new/gw/smsc/smpp_pdu.h	2006-01-10 16:10:50.000000000 +0100
+++ gateway.new.2/gw/smsc/smpp_pdu.h	2006-01-10 16:10:18.000000000 +0100
@@ -222,6 +222,52 @@
     SMPP_ESME_RINVBCAST_REP = 0x00000110,
     SMPP_ESME_RINVBCASTSRVGRP = 0x00000111,
     SMPP_ESME_RINVBCASTCHANIND = 0x00000112,
+
+    SMPP_ESME_RMBLOX_NUMBER_BLACKLISTED = 0x00000401,
+    SMPP_ESME_RMBLOX_CLIENT_BLACKLISTED = 0x00000402,
+    SMPP_ESME_RMBLOX_PREFIX_BLACKLISTED = 0x00000403,
+    SMPP_ESME_RMBLOX_INVALID_ACCOUNT = 0x00000404,
+    SMPP_ESME_RMBLOX_NOT_APPLICABLE1 = 0x00000405,
+    SMPP_ESME_RMBLOX_DESTINATION_BUSY = 0x00000406,
+    SMPP_ESME_RMBLOX_REPLY_TYPE_ERROR = 0x00000407,
+    SMPP_ESME_RMBLOX_MSIP_SYNTAX_ERROR = 0x00000408,
+    SMPP_ESME_RMBLOX_NOT_APPLICABLE2 = 0x00000409,
+    SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL1 = 0x0000040A,
+    SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL2 = 0x0000040B,
+    SMPP_ESME_RMBLOX_SYSTEM_UNAVAIL3 = 0x0000040C,
+    SMPP_ESME_RMBLOX_PROFILE_ERROR = 0x0000040D,
+    SMPP_ESME_RMBLOX_USERNAME_NOT_SET = 0x0000040E,
+    SMPP_ESME_RMBLOX_BINARY_NOT_ALLOWED = 0x0000040F,
+    SMPP_ESME_RMBLOX_TEMP_SYSTEM_FAIL = 0x00000410,
+    SMPP_ESME_RMBLOX_UNROUTABLE1 = 0x00000411,
+    SMPP_ESME_RMBLOX_TEMP_UNROUTABLE1 = 0x00000412,
+    SMPP_ESME_RMBLOX_UNROUTABLE2 = 0x00000413,
+    SMPP_ESME_RMBLOX_CURRENT_UNROUTABLE = 0x00000414,
+    SMPP_ESME_RMBLOX_TEMP_UNROUTABLE2 = 0x00000415,
+    SMPP_ESME_RMBLOX_UNROUTABLE3 = 0x00000416,
+    SMPP_ESME_RMBLOX_UNROUTABLE4 = 0x00000417,
+    SMPP_ESME_RMBLOX_UNROUTABLE5 = 0x00000418,
+    SMPP_ESME_RMBLOX_UNROUTABLE6 = 0x00000419,
+    SMPP_ESME_RMBLOX_UNROUTABLE7 = 0x0000041A,
+    SMPP_ESME_RMBLOX_UNROUTABLE8 = 0x0000041B,
+    SMPP_ESME_RMBLOX_TEMP_UNROUTABLE3 = 0x0000041C,
+    SMPP_ESME_RMBLOX_UNROUTABLE9 = 0x0000041D,
+    SMPP_ESME_RMBLOX_TEMP_UNROUTABLE4 = 0x0000041E,
+    SMPP_ESME_RMBLOX_TEMP_UNROUTABLE5 = 0x0000041F,
+    SMPP_ESME_RMBLOX_LOCAL_DELIVERER_FAIL = 0x00000420,
+    SMPP_ESME_RMBLOX_CANT_FIND_ORIGINATOR = 0x00000421,
+    SMPP_ESME_RMBLOX_DESTINATION_RETRY = 0x00000422,
+    SMPP_ESME_RMBLOX_NUMBER_BLOCKED1 = 0x00000423,
+    SMPP_ESME_RMBLOX_BILLING_REF_ERROR = 0x00000424,
+    SMPP_ESME_RMBLOX_NUMBER_BLOCKED2 = 0x00000425,
+    SMPP_ESME_RMBLOX_THROTTLING = 0x00000426,
+    SMPP_ESME_RMBLOX_BAD_SEQUENCE = 0x00000427,
+    SMPP_ESME_RMBLOX_CLIENT_ID_ERROR1 = 0x00000428,
+    SMPP_ESME_RMBLOX_CLIENT_ID_ERROR2 = 0x00000429,
+    SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR1 = 0x0000042A,
+    SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR2 = 0x0000042B,
+    SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR3 = 0x0000042C,
+    SMPP_ESME_RMBLOX_PSMS_ROUTING_ERROR4 = 0x0000042D
 };
 
 SMPP_PDU *smpp_pdu_create(unsigned long type, unsigned long seq_no);
diff -Nru gateway/gw/smsc/smsc_smpp.c gateway.new/gw/smsc/smsc_smpp.c
--- gateway/gw/smsc/smsc_smpp.c	2005-12-18 21:21:16.000000000 +0100
+++ gateway.new/gw/smsc/smsc_smpp.c	2006-01-10 16:26:11.000000000 +0100
@@ -69,6 +69,8 @@
        either) */
 /* XXX numbering plans and type of number: check spec */
 
+#include <math.h>
+
 #include "gwlib/gwlib.h"
 #include "msg.h"
 #include "smsc_p.h"
@@ -159,6 +161,7 @@
     long connection_timeout;
     long wait_ack;
     int wait_ack_action;
+	int pack_udh;
     SMSCConn *conn; 
 } SMPP; 
  
@@ -211,7 +214,7 @@
                          Octstr *my_number, int smpp_msg_id_type, 
                          int autodetect_addr, Octstr *alt_charset, 
                          Octstr *service_type, long connection_timeout,
-                         long wait_ack, int wait_ack_action) 
+                         long wait_ack, int wait_ack_action, int pack_udh) 
 { 
     SMPP *smpp; 
      
@@ -251,6 +254,7 @@
     smpp->connection_timeout = connection_timeout;
     smpp->wait_ack = wait_ack;
     smpp->wait_ack_action = wait_ack_action;
+	smpp->pack_udh = pack_udh;
  
     return smpp; 
 } 
@@ -711,6 +715,45 @@
     }
 }
 
+static Octstr *smpp_pack_septets (Octstr *string) {
+	int i, len;
+	Octstr *res = octstr_create("");
+	len = octstr_len(string);
+	for (i=0; i<len; i++) {
+		unsigned char val1, val2, val3;
+		val1 = octstr_get_char(string, i) & 0x7F;
+		if (i + 1 < len)
+			val2 = octstr_get_char(string, i + 1) & 0x7F;
+		else
+			val2 = 0;
+		val3 = ((val1 >> (i & 7)) | (val2 << (7 - (i & 7)))) & 0xFF;
+		octstr_append_char(res, val3);
+		if ((i & 7) == 6)
+			i = i + 1;
+	}
+	return res;
+}
+
+static Octstr *smpp_unpack_septets (Octstr *string, int len) {
+	int i, j;
+	Octstr *res;
+	if (len == 0)
+		len = ceil((float)octstr_len(string) * 8.0 / 7.0);
+	res = octstr_create("");
+	j = 0;
+	for (i=0; i<len; i++) {
+		octstr_append_char(
+				res,
+				(
+				 (j < octstr_len(string) ? (octstr_get_char(string, j) << (i & 0x07)) : 0) |
+				 (j > 0 && j - 1 < octstr_len(string) ? (octstr_get_char(string, j - 1) >> (8 - (i & 0x07))) : 0)
+				 ) & 0x7F);
+		if ((i & 7) != 7)
+			j++;
+	}
+	return res;
+}
+
 
 static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)
 {
@@ -854,7 +897,25 @@
 
     /* prepend udh if present */
     if (octstr_len(msg->sms.udhdata)) {
-        octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);
+		if (smpp->pack_udh && msg->sms.coding == DC_7BIT) {
+			Octstr *udh_septets = smpp_unpack_septets(msg->sms.udhdata, 0);
+			Octstr *message;
+		
+			octstr_insert(pdu->u.submit_sm.short_message, udh_septets, 0);
+
+			if (((octstr_len(pdu->u.submit_sm.short_message) + 1) & 7) == 0) {
+				/* message length will result in an @ in the end. Add a space instead */
+				octstr_append_char(pdu->u.submit_sm.short_message, ' ');
+			}
+
+			octstr_destroy(udh_septets);
+			message = smpp_pack_septets(pdu->u.submit_sm.short_message);
+
+			octstr_destroy(pdu->u.submit_sm.short_message);
+			pdu->u.submit_sm.short_message = message;
+		}
+		else
+			octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);
     }
 
     pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message);
@@ -1937,6 +1998,7 @@
     int autodetect_addr;
     Octstr *alt_charset;
     long connection_timeout, wait_ack, wait_ack_action;
+	int pack_udh;
 
     my_number = alt_charset = NULL;
     transceiver_mode = 0;
@@ -2021,6 +2083,9 @@
     if (cfg_get_bool(&autodetect_addr, grp, octstr_imm("source-addr-autodetect")) == -1)
         autodetect_addr = 1; /* default is autodetect if no option defined */
 
+	if (cfg_get_bool(&pack_udh, grp, octstr_imm("pack-udh")) == -1)
+		pack_udh = 0;
+
     /* check for any specified interface version */
     if (cfg_get_integer(&version, grp, octstr_imm("interface-version")) == -1)
         version = SMPP_DEFAULT_VERSION;
@@ -2074,7 +2139,7 @@
                        dest_addr_npi, enquire_link_interval, 
                        max_pending_submits, version, priority, validity, my_number, 
                        smpp_msg_id_type, autodetect_addr, alt_charset, 
-                       service_type, connection_timeout, wait_ack, wait_ack_action); 
+                       service_type, connection_timeout, wait_ack, wait_ack_action, pack_udh); 
  
     conn->data = smpp; 
     conn->name = octstr_format("SMPP:%S:%d/%d:%S:%S",  
diff -Nru gateway/gwlib/cfg.def gateway.new/gwlib/cfg.def
--- gateway/gwlib/cfg.def	2005-12-13 01:11:04.000000000 +0100
+++ gateway.new/gwlib/cfg.def	2006-01-10 16:24:59.000000000 +0100
@@ -365,6 +365,7 @@
     OCTSTR(denied-prefix-regex)
     OCTSTR(preferred-prefix-regex)
     OCTSTR(max-error-count)
+	OCTSTR(pack-udh)
 )
 
 

Reply via email to