Fw: wappush on CDMA

"G. David Butler" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel,gmane.spam.detected
Message-ID <563EFB560E824699AEE6529DD1DA2A77@VAIO>
[resending because I got:
<[email protected]>... Deferred: vm1.kannel.org.: No route to host
Message could not be delivered for 5 hours
Message will be deleted from queue
]

Kannel Developers,

This patch from Rene saved my day yesterday.

I did not expect a problem doing a WAP push on our network and suddenly
found a large problem. CDMA is quite different than GSM in this regard. I
did a Google search and found a thread from 2006 where Rene said he had
patches to allow this. I sent him an email and was suprised he responded so
quickly. Attached is his patch, kannel-cdma-patch.diff.

He warned that it was applied to an old CVS version. I took a current CVS
checkout and worked to apply his patch. I got it working and am currently
doing WAP push on a CDMA network! Attached is the output of cvs diff -u,
kannel-cdma.diff.

Please verify with Rene that his work can be integrated into kannel. My work
can be.

To allow both TXT SMS and WAP Push I had to create two SMSC connections to
the same IP. This isn't optimal but I'm not familiar enough with the code
base to do it better. I hope you can. Attached is my kannel.conf that works.

David

> ----- Original Message ----- 
> From: "Rene Kluwen" <[email protected]>
> To: <[email protected]>
> Sent: Friday, January 15, 2010 9:28 AM
> Subject: FW: wappush on CDMA
>
>
> Here is the CDMA patch already. It is current as of Kannel CVS from a long
> time ago.
>
> I it has been a while since I've last sent it to anybody. I need to look 
> for
> the instructions.
>
> Unfortunately, we cannot give support to free software.
>
> -- Rene Kluwen
> Chimit
>
>
>
kannel-cdma-patch.diff (application/octet-stream, 20.7 KB)
Index: gw/sms.h
===================================================================
RCS file: /home/cvs/gateway/gw/sms.h,v
retrieving revision 1.15
diff -u -a -r1.15 sms.h
--- gw/sms.h	19 Sep 2005 22:07:33 -0000	1.15
+++ gw/sms.h	12 Jul 2006 18:18:53 -0000
@@ -126,7 +126,7 @@
  * Maximum number of octets in an SMS message. Note that this is 8 bit
  * characters, not 7 bit characters.
  */
-#define MAX_SMS_OCTETS 140
+#define MAX_SMS_OCTETS 113
 
 /* Encode DCS using sms fields
  * mode = 0= encode using 00xxxxxx, 1= encode using 1111xxxx mode
Index: gw/smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.95
diff -u -a -r1.95 smsc_smpp.c
--- gw/smsc/smsc_smpp.c	13 Jun 2006 13:50:49 -0000	1.95
+++ gw/smsc/smsc_smpp.c	12 Jul 2006 18:18:53 -0000
@@ -164,6 +164,7 @@
     long connection_timeout;
     long wait_ack;
     int wait_ack_action;
+    int send_binary_as_data_sm;
     SMSCConn *conn; 
 } SMPP; 
  
@@ -216,7 +217,7 @@
                          Octstr *my_number, int smpp_msg_id_type, 
                          int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset,
                          Octstr *service_type, long connection_timeout,
-                         long wait_ack, int wait_ack_action) 
+                         long wait_ack, int wait_ack_action, int send_binary_as_data_sm) 
 { 
     SMPP *smpp; 
      
@@ -259,6 +260,7 @@
     smpp->wait_ack_action = wait_ack_action;
     smpp->bind_addr_ton = 0;
     smpp->bind_addr_npi = 0;
+    smpp->send_binary_as_data_sm = send_binary_as_data_sm;
  
     return smpp; 
 } 
@@ -727,8 +729,7 @@
     }
 }
 
-
-static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)
+static SMPP_PDU *msg_to_submit_pdu(SMPP *smpp, Msg *msg)
 {
     SMPP_PDU *pdu;
     int validity;
@@ -932,6 +933,252 @@
 }
 
 
+#define GETLONGFROMUDHDATA(pos) (long)((long)octstr_get_char(msg->sms.udhdata, pos + 1) + (0x100L * (long)octstr_get_char(msg->sms.udhdata, pos)))
+#define GETSHORTFROMUDHDATA(pos) (octstr_get_char(msg->sms.udhdata, pos))
+/* changed this function submit_sm -> data_sm */
+static SMPP_PDU *msg_to_data_pdu(SMPP *smpp, Msg *msg)
+{
+    SMPP_PDU *pdu;
+    /* RK: Binary (UDH) values that go in optional parameters */
+    long source_port = 0x0000, destination_port = 0x0000;
+    int  sar_msg_ref_num = 0x01, sar_total_segments = 0x01, sar_segment_seqnum = 0x01;
+    long udhlen, udhcurrent, udhtype;
+
+    pdu = smpp_pdu_create(data_sm,
+    	    	    	  counter_increase(smpp->message_id_counter));
+
+    pdu->u.data_sm.source_addr = octstr_duplicate(msg->sms.sender);
+    error(0, "SMPP: Source address: %s", octstr_get_cstr(pdu->u.data_sm.source_addr));
+    pdu->u.data_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
+
+    /* Set the service type of the outgoing message. We'll use the config 
+     * directive as default and 'binfo' as specific parameter. */
+    pdu->u.data_sm.service_type = octstr_len(msg->sms.binfo) ? 
+        octstr_duplicate(msg->sms.binfo) : octstr_duplicate(smpp->service_type);
+
+    /* Check for manual override of source ton and npi values */
+    if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
+        pdu->u.data_sm.source_addr_ton = smpp->source_addr_ton;
+        pdu->u.data_sm.source_addr_npi = smpp->source_addr_npi;
+        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
+              octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,
+              smpp->source_addr_npi);
+    } else {
+        /* setup default values */
+        pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+        pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
+    }
+
+    if (smpp->autodetect_addr) {
+        /* lets see if its international or alphanumeric sender */
+        if (octstr_get_char(pdu->u.data_sm.source_addr, 0) == '+') {
+            if (!octstr_check_range(pdu->u.data_sm.source_addr, 1, 256, gw_isdigit)) {
+                pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
+                pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;    /* short code */
+            } else {
+               /* numeric sender address with + in front -> international (remove the +) */
+               octstr_delete(pdu->u.data_sm.source_addr, 0, 1);
+               pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
+    	    }
+        } else {
+            if (!octstr_check_range(pdu->u.data_sm.source_addr,0, 256, gw_isdigit)) {
+                pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
+                pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
+            }
+        }
+    }
+
+    /* Check for manual override of destination ton and npi values */
+    if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
+        pdu->u.data_sm.dest_addr_ton = smpp->dest_addr_ton;
+        pdu->u.data_sm.dest_addr_npi = smpp->dest_addr_npi;
+        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
+              octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,
+              smpp->dest_addr_npi);
+    } else {
+        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+        pdu->u.data_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
+    }
+
+    /*
+     * if its a international number starting with +, lets remove the
+     * '+' and set number type to international instead
+     */
+    if (octstr_get_char(pdu->u.data_sm.destination_addr,0) == '+') {
+        octstr_delete(pdu->u.data_sm.destination_addr, 0,1);
+        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
+    }
+
+    /* check length of src/dst address */
+    if (octstr_len(pdu->u.data_sm.destination_addr) > 20 ||
+        octstr_len(pdu->u.data_sm.source_addr) > 20) {
+        smpp_pdu_destroy(pdu);
+        return NULL;
+    }
+
+    /*
+     * set the data coding scheme (DCS) field
+     * check if we have a forced value for this from the smsc-group.
+     * Note: if message class is set, then we _must_ force alt_dcs otherwise
+     * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
+     * first here, because MWI and MCLASS can not be set at the same time and
+     * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
+     * if MWI is set.
+     */
+    if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
+        pdu->u.data_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
+    else
+        pdu->u.data_sm.data_coding = fields_to_dcs(msg,
+            (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
+             msg->sms.alt_dcs : smpp->conn->alt_dcs));
+
+    /* set protocol id */
+    /*
+    RK data_sm doesnt have protocol id
+    if(msg->sms.pid != SMS_PARAM_UNDEFINED)
+        pdu->u.data_sm.protocol_id = msg->sms.pid;
+    */
+
+    /*
+     * set the esm_class field
+     * default is store and forward, plus udh and rpi if requested
+     */
+    pdu->u.data_sm.esm_class = ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE;
+    /* RK: We dont send an UDH in payload of data_sm
+    if (octstr_len(msg->sms.udhdata))
+        pdu->u.data_sm.esm_class = pdu->u.data_sm.esm_class |
+            ESM_CLASS_SUBMIT_UDH_INDICATOR;
+    */
+    if (msg->sms.rpi > 0)
+        pdu->u.data_sm.esm_class = pdu->u.data_sm.esm_class |
+            ESM_CLASS_SUBMIT_RPI;
+
+    /*
+     * set data segments and length
+     */
+
+    /* RK: short messages goes into message_payload */
+    pdu->u.data_sm.message_payload = octstr_duplicate(msg->sms.msgdata);
+
+    /*
+     * only re-encoding if using default smsc charset that is defined via
+     * alt-charset in smsc group and if MT is not binary
+     */
+    if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata))) {
+        /* 
+         * consider 3 cases: 
+         *  a) data_coding 0xFX: encoding should always be GSM 03.38 charset 
+         *  b) data_coding 0x00: encoding may be converted according to alt-charset 
+         *  c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
+         */
+        if ((pdu->u.data_sm.data_coding & 0xF0) ||
+            (!smpp->alt_charset && pdu->u.data_sm.data_coding == 0)) {
+            charset_latin1_to_gsm(pdu->u.data_sm.message_payload);
+        }
+        else if (pdu->u.data_sm.data_coding == 0 && smpp->alt_charset) {
+            /*
+             * convert to the given alternative charset
+             */
+            if (charset_convert(pdu->u.data_sm.message_payload, "ISO-8859-1",
+                                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));
+        }
+    }
+
+    /* prepend udh if present */
+    /* RK: udh data is not prepended to payload
+    if (octstr_len(msg->sms.udhdata)) {
+        octstr_insert(pdu->u.data_sm.short_message, msg->sms.udhdata, 0);
+    }
+    RK: sm_lenght is not a data_sm member.
+    pdu->u.data_sm.sm_length = octstr_len(pdu->u.data_sm.short_message);
+    */
+
+    /*
+     * check for validity and defered settings
+     */
+    /* RK: TODO: This should be either qos_time_to_live or ms_validity
+    if (msg->sms.validity >= 0) {
+        struct tm tm = gw_gmtime(time(NULL) + msg->sms.validity * 60);
+        pdu->u.data_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",
+                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+                tm.tm_hour, tm.tm_min, tm.tm_sec);
+    }
+    */
+
+    /*
+    RK: TODO: Which field?
+    if (msg->sms.deferred >= 0) {
+        struct tm tm = gw_gmtime(time(NULL) + msg->sms.deferred * 60);
+        pdu->u.data_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",
+                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+                tm.tm_hour, tm.tm_min, tm.tm_sec);
+    }
+    */
+    /* RK: added code: fill in optional parameters */
+    error(0, "SMPP: UDHLEN: %ld", octstr_len(msg->sms.udhdata));
+    if (octstr_len(msg->sms.udhdata) > 0) {
+	udhcurrent = 1;
+	udhlen = octstr_len(msg->sms.udhdata) - 1;
+	while (udhcurrent < udhlen) {
+		error(0, "SMPP: Processing: %i", octstr_get_char(msg->sms.udhdata, udhcurrent));
+		udhtype = GETLONGFROMUDHDATA(udhcurrent);
+		error(0, "SMPP: UDHTYPE: %x", udhtype);
+		udhcurrent += 2;
+		switch (udhtype) {
+		case 0x0003:
+			/* catenation header */
+			sar_msg_ref_num = GETSHORTFROMUDHDATA(udhcurrent++);
+			sar_total_segments = GETSHORTFROMUDHDATA(udhcurrent++);
+			sar_segment_seqnum = GETSHORTFROMUDHDATA(udhcurrent++);
+			break;
+		case 0x0504:
+			/* binary header */
+			destination_port = GETLONGFROMUDHDATA(udhcurrent);
+			udhcurrent += 2;
+			source_port = GETLONGFROMUDHDATA(udhcurrent);
+			udhcurrent += 2;
+			error(0, "SMPP: Source: %x, Destination: %x", source_port, destination_port);
+			break;
+		default:
+			/* oops... we have a header value we dont know about */
+			udhcurrent = udhlen;
+			break;
+		}
+	}
+	if (source_port) pdu->u.data_sm.source_port = source_port;
+	if (destination_port) pdu->u.data_sm.destination_port = destination_port;
+	/* we should also send sar data if only one segment */
+	pdu->u.data_sm.sar_msg_ref_num = sar_msg_ref_num;
+	pdu->u.data_sm.sar_total_segments = sar_total_segments;
+	pdu->u.data_sm.sar_segment_seqnum = sar_segment_seqnum;
+	pdu->u.data_sm.payload_type = 0; /* set to 0, default */
+    }
+
+    /* ask for the delivery reports if needed */
+    if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
+        pdu->u.data_sm.registered_delivery = 1;
+    else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
+        pdu->u.data_sm.registered_delivery = 2;
+
+    /* set priority */
+    /*
+    RK: Dont have such a thing in data_sm
+    if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
+        pdu->u.data_sm.priority_flag = msg->sms.priority;
+    else
+        pdu->u.data_sm.priority_flag = smpp->priority;
+    */
+
+    /* set more messages to send */
+    if (smpp->version > 0x33 && msg->sms.msg_left > 0)
+        pdu->u.data_sm.more_messages_to_send = 1;
+
+    return pdu;
+}
+
+
 static void send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
 {
     SMPP_PDU *pdu;
@@ -980,12 +1227,14 @@
 }
 
 
+/* RK: changed this function. messages are sent as either data_sm or submit_sm */
 static void send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
 {
     Msg *msg;
     SMPP_PDU *pdu;
     Octstr *os;
     double delay = 0;
+    int send_as_data_sm;
 
     if (*pending_submits == -1)
         return;
@@ -1000,8 +1249,15 @@
         if (msg == NULL)
             break;
 
-        /* Send PDU, record it as waiting for ack from SMS center */
-        pdu = msg_to_pdu(smpp, msg);
+	/* Send PDU, record it as waiting for ack from SMS center */
+	/* RK: todo: make this a setting in smpp.conf */
+	send_as_data_sm = ((smpp->send_binary_as_data_sm) && (octstr_len(msg->sms.udhdata) > 2) &&  (GETLONGFROMUDHDATA(1) == 0x0504));
+	if (send_as_data_sm) {
+        	pdu = msg_to_data_pdu(smpp, msg);
+	}
+	else {
+        	pdu = msg_to_submit_pdu(smpp, msg);
+	}
         if (pdu == NULL) {
             bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED SMS"));
             continue;
@@ -1009,7 +1265,12 @@
         /* check for write errors */
         if (send_pdu(conn, smpp->conn->id, pdu) == 0) {
             struct smpp_msg *smpp_msg = smpp_msg_create(msg);
-            os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
+	    if (send_as_data_sm) {
+            	os = octstr_format("%ld", pdu->u.data_sm.sequence_number);
+	    }
+	    else {
+            	os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
+	    }
             dict_put(smpp->sent_msgs, os, smpp_msg);
             smpp_pdu_destroy(pdu);
             octstr_destroy(os);
@@ -1248,14 +1509,14 @@
          * Obey which SMPP msg_id type this SMSC is using, where we
          * have the following semantics for the variable smpp_msg_id:
          *
-         * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm
+         * bit 1: type for submit_sm/data_sm, bit 2: type for deliver_sm
          *
          * if bit is set value is hex otherwise dec
          *
-         * 0x00 deliver_sm dec, submit_sm_resp dec
-         * 0x01 deliver_sm dec, submit_sm_resp hex
-         * 0x02 deliver_sm hex, submit_sm_resp dec
-         * 0x03 deliver_sm hex, submit_sm_resp hex
+         * 0x00 deliver_sm dec, submit_sm/data_sm dec
+         * 0x01 deliver_sm dec, submit_sm/data_sm hex
+         * 0x02 deliver_sm hex, submit_sm/data_sm dec
+         * 0x03 deliver_sm hex, submit_sm/data_sm hex
          *
          * Default behaviour is SMPP spec compliant, which means
          * msg_ids should be C strings and hence non modified.
@@ -1316,6 +1577,7 @@
 }
 
 
+/* RK: changed this function. Added case data_sm_resp. Also text in generic_nak */
 static void handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu,
     	    	       long *pending_submits)
 {
@@ -1501,6 +1763,67 @@
                 --(*pending_submits);
             } /* end if for SMSC ACK */
             break;
+        case data_sm_resp:
+            os = octstr_format("%ld", pdu->u.data_sm_resp.sequence_number);
+            smpp_msg = dict_remove(smpp->sent_msgs, os);
+            octstr_destroy(os);
+            if (smpp_msg == NULL) {
+                warning(0, "SMPP[%s]: SMSC sent data_sm_resp "
+                        "with wrong sequence number 0x%08lx",
+                        octstr_get_cstr(smpp->conn->id),
+                        pdu->u.data_sm_resp.sequence_number);
+                break;
+            }
+            msg = smpp_msg->msg;
+            smpp_msg_destroy(smpp_msg, 0);
+            if (pdu->u.data_sm_resp.command_status != 0) {
+                error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
+                      "in response to data_sm.",
+                      octstr_get_cstr(smpp->conn->id),
+                      pdu->u.data_sm_resp.command_status,
+		      smpp_error_to_string(pdu->u.data_sm_resp.command_status));
+                reason = smpp_status_to_smscconn_failure_reason(
+                            pdu->u.data_sm_resp.command_status);
+
+                /*
+                 * check to see if we got a "throttling error", in which case we'll just
+                 * sleep for a while
+                 */
+                if (pdu->u.data_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
+                    time(&(smpp->throttling_err_time));
+                else
+                    smpp->throttling_err_time = 0;
+
+                bb_smscconn_send_failed(smpp->conn, msg, reason, 
+                        octstr_format("%ld/%s", pdu->u.data_sm_resp.command_status,
+                            smpp_error_to_string(pdu->u.data_sm_resp.command_status)));
+                --(*pending_submits);
+            } else {
+                Octstr *tmp;
+
+                /* check if msg_id is C string, decimal or hex for this SMSC */
+                if (smpp->smpp_msg_id_type == -1) {
+                    /* the default, C string */
+                    tmp = octstr_duplicate(pdu->u.data_sm_resp.message_id);
+                } else {
+                    if (smpp->smpp_msg_id_type & 0x01) {
+                        tmp = octstr_format("%ld", strtol(  /* hex */
+                            octstr_get_cstr(pdu->u.data_sm_resp.message_id), NULL, 16));
+                    } else {
+                        tmp = octstr_format("%ld", strtol(  /* decimal */
+                            octstr_get_cstr(pdu->u.data_sm_resp.message_id), NULL, 10));
+                    }
+                }
+
+                /* SMSC ACK.. now we have the message id. */
+                if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask))
+                    dlr_add(smpp->conn->id, tmp, msg);
+
+                octstr_destroy(tmp);
+                bb_smscconn_sent(smpp->conn, msg, NULL);
+                --(*pending_submits);
+            } /* end if for SMSC ACK */
+            break;
 
         case bind_transmitter_resp:
             if (pdu->u.bind_transmitter_resp.command_status != 0) {
@@ -1594,7 +1917,7 @@
                 smpp_msg_destroy(smpp_msg, 0);
                 
                 error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
-                      "in response to submit_sm.",
+                      "in response to submit_sm/data_sm.",
                       octstr_get_cstr(smpp->conn->id),
                       cmd_stat,
 		      smpp_error_to_string(cmd_stat));
@@ -1986,6 +2309,7 @@
     Octstr *alt_charset;
     Octstr *alt_addr_charset;
     long connection_timeout, wait_ack, wait_ack_action;
+    int send_binary_as_data_sm;
 
     my_number = alt_addr_charset = alt_charset = NULL;
     transceiver_mode = 0;
@@ -2099,6 +2423,9 @@
         if (smpp_msg_id_type < 0 || smpp_msg_id_type > 3)
             panic(0,"SMPP: Invalid value for msg-id-type directive in configuraton"); 
     }
+    if (cfg_get_bool(&send_binary_as_data_sm, grp, octstr_imm("send-binary-as-datasm")) == -1) {
+	send_binary_as_data_sm = 0;
+    }
 
     /* check for an alternative charset */
     alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
@@ -2124,7 +2451,7 @@
                        dest_addr_npi, enquire_link_interval, 
                        max_pending_submits, version, priority, validity, my_number, 
                        smpp_msg_id_type, autodetect_addr, alt_charset, alt_addr_charset,
-                       service_type, connection_timeout, wait_ack, wait_ack_action); 
+                       service_type, connection_timeout, wait_ack, wait_ack_action, send_binary_as_data_sm); 
  
     cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton"));
     cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.118
diff -u -a -r1.118 cfg.def
--- gwlib/cfg.def	9 May 2006 14:32:31 -0000	1.118
+++ gwlib/cfg.def	12 Jul 2006 18:18:53 -0000
@@ -120,6 +120,7 @@
     OCTSTR(sms-incoming-queue-limit)
     OCTSTR(sms-resend-freq)
     OCTSTR(sms-resend-retry)
+    OCTSTR(default-smsc)
 )
 
 
@@ -240,6 +241,18 @@
 )
 
 
+SINGLE_GROUP(smppbox,
+	OCTSTR(bearerbox-host)
+	OCTSTR(smppbox-id)
+	OCTSTR(smppbox-port)
+	OCTSTR(global-sender)
+	OCTSTR(log-file)
+	OCTSTR(log-level)
+	OCTSTR(our-system-id)
+	OCTSTR(route-to-smsc)
+	OCTSTR(smpp-logins)
+)
+
 SINGLE_GROUP(smsbox,
     OCTSTR(smsbox-id)
     OCTSTR(bearerbox-host)
@@ -368,6 +381,7 @@
     OCTSTR(preferred-prefix-regex)
     OCTSTR(max-error-count)
     OCTSTR(alt-addr-charset)
+    OCTSTR(send-binary-as-datasm)
 )
kannel-cdma.diff (application/octet-stream, 20.8 KB)
Index: gw/smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.123
diff -u -r1.123 smsc_smpp.c
--- gw/smsc/smsc_smpp.c	2 Sep 2009 13:10:50 -0000	1.123
+++ gw/smsc/smsc_smpp.c	16 Jan 2010 16:25:28 -0000
@@ -168,6 +168,7 @@
     long connection_timeout;
     long wait_ack;
     int wait_ack_action;
+    int send_binary_as_data_sm;
     Load *load;
     SMSCConn *conn;
 } SMPP;
@@ -221,7 +222,8 @@
                          Octstr *my_number, int smpp_msg_id_type,
                          int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset,
                          Octstr *service_type, long connection_timeout,
-                         long wait_ack, int wait_ack_action)
+                         long wait_ack, int wait_ack_action,
+                         int send_binary_as_data_sm)
 {
     SMPP *smpp;
 
@@ -262,6 +264,7 @@
     smpp->connection_timeout = connection_timeout;
     smpp->wait_ack = wait_ack;
     smpp->wait_ack_action = wait_ack_action;
+    smpp->send_binary_as_data_sm = send_binary_as_data_sm;
     smpp->bind_addr_ton = 0;
     smpp->bind_addr_npi = 0;
     smpp->use_ssl = 0;
@@ -747,7 +750,7 @@
 }
 
 
-static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)
+static SMPP_PDU *msg_to_submit_pdu(SMPP *smpp, Msg *msg)
 {
     SMPP_PDU *pdu;
     int validity;
@@ -957,6 +960,253 @@
     return pdu;
 }
 
+#define GETLONGFROMUDHDATA(pos) (long)((long)octstr_get_char(msg->sms.udhdata, pos + 1) + (0x100L * (long)octstr_get_char(msg->sms.udhdata, pos)))
+
+#define GETSHORTFROMUDHDATA(pos) (octstr_get_char(msg->sms.udhdata, pos))
+
+/* changed this function submit_sm -> data_sm */
+static SMPP_PDU *msg_to_data_pdu(SMPP *smpp, Msg *msg)
+{
+    SMPP_PDU *pdu;
+    /* RK: Binary (UDH) values that go in optional parameters */
+    long source_port = 0x0000, destination_port = 0x0000;
+    int  sar_msg_ref_num = 0x01, sar_total_segments = 0x01, sar_segment_seqnum = 0x01;
+    long udhlen, udhcurrent, udhtype;
+
+    pdu = smpp_pdu_create(data_sm,
+                          counter_increase(smpp->message_id_counter));
+
+    pdu->u.data_sm.source_addr = octstr_duplicate(msg->sms.sender);
+    error(0, "SMPP: Source address: %s", octstr_get_cstr(pdu->u.data_sm.source_addr));
+    pdu->u.data_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
+
+    /* Set the service type of the outgoing message. We'll use the config 
+     * directive as default and 'binfo' as specific parameter. */
+    pdu->u.data_sm.service_type = octstr_len(msg->sms.binfo) ? 
+        octstr_duplicate(msg->sms.binfo) : octstr_duplicate(smpp->service_type);
+
+    /* Check for manual override of source ton and npi values */
+    if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
+        pdu->u.data_sm.source_addr_ton = smpp->source_addr_ton;
+        pdu->u.data_sm.source_addr_npi = smpp->source_addr_npi;
+        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
+              octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,
+              smpp->source_addr_npi);
+    } else {
+        /* setup default values */
+        pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+        pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
+    }
+
+    if (smpp->autodetect_addr) {
+        /* lets see if its international or alphanumeric sender */
+        if (octstr_get_char(pdu->u.data_sm.source_addr, 0) == '+') {
+            if (!octstr_check_range(pdu->u.data_sm.source_addr, 1, 256, gw_isdigit)) {
+                pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
+                pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;    /* short code */
+            } else {
+               /* numeric sender address with + in front -> international (remove the +) */
+               octstr_delete(pdu->u.data_sm.source_addr, 0, 1);
+               pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
+            }
+        } else {
+            if (!octstr_check_range(pdu->u.data_sm.source_addr,0, 256, gw_isdigit)) {
+                pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
+                pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
+            }
+        }
+    }
+
+    /* Check for manual override of destination ton and npi values */
+    if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
+        pdu->u.data_sm.dest_addr_ton = smpp->dest_addr_ton;
+        pdu->u.data_sm.dest_addr_npi = smpp->dest_addr_npi;
+        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
+              octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,
+              smpp->dest_addr_npi);
+    } else {
+        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+        pdu->u.data_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
+    }
+
+    /*
+     * if its a international number starting with +, lets remove the
+     * '+' and set number type to international instead
+     */
+    if (octstr_get_char(pdu->u.data_sm.destination_addr,0) == '+') {
+        octstr_delete(pdu->u.data_sm.destination_addr, 0,1);
+        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
+    }
+
+    /* check length of src/dst address */
+    if (octstr_len(pdu->u.data_sm.destination_addr) > 20 ||
+        octstr_len(pdu->u.data_sm.source_addr) > 20) {
+        smpp_pdu_destroy(pdu);
+        return NULL;
+    }
+
+    /*
+     * set the data coding scheme (DCS) field
+     * check if we have a forced value for this from the smsc-group.
+     * Note: if message class is set, then we _must_ force alt_dcs otherwise
+     * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
+     * first here, because MWI and MCLASS can not be set at the same time and
+     * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
+     * if MWI is set.
+     */
+    if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
+        pdu->u.data_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
+    else
+        pdu->u.data_sm.data_coding = fields_to_dcs(msg,
+            (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
+             msg->sms.alt_dcs : smpp->conn->alt_dcs));
+
+    /* set protocol id */
+    /*
+    RK data_sm doesnt have protocol id
+    if(msg->sms.pid != SMS_PARAM_UNDEFINED)
+        pdu->u.data_sm.protocol_id = msg->sms.pid;
+    */
+
+    /*
+     * set the esm_class field
+     * default is store and forward, plus udh and rpi if requested
+     */
+    pdu->u.data_sm.esm_class = ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE;
+    /* RK: We dont send an UDH in payload of data_sm
+    if (octstr_len(msg->sms.udhdata))
+        pdu->u.data_sm.esm_class = pdu->u.data_sm.esm_class |
+            ESM_CLASS_SUBMIT_UDH_INDICATOR;
+    */
+    if (msg->sms.rpi > 0)
+        pdu->u.data_sm.esm_class = pdu->u.data_sm.esm_class |
+            ESM_CLASS_SUBMIT_RPI;
+
+    /*
+     * set data segments and length
+     */
+
+    /* RK: short messages goes into message_payload */
+    pdu->u.data_sm.message_payload = octstr_duplicate(msg->sms.msgdata);
+
+    /*
+     * only re-encoding if using default smsc charset that is defined via
+     * alt-charset in smsc group and if MT is not binary
+     */
+    if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata))) {
+        /* 
+         * consider 3 cases: 
+         *  a) data_coding 0xFX: encoding should always be GSM 03.38 charset 
+         *  b) data_coding 0x00: encoding may be converted according to alt-charset 
+         *  c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
+         */
+        if ((pdu->u.data_sm.data_coding & 0xF0) ||
+            (!smpp->alt_charset && pdu->u.data_sm.data_coding == 0)) {
+            charset_latin1_to_gsm(pdu->u.data_sm.message_payload);
+        }
+        else if (pdu->u.data_sm.data_coding == 0 && smpp->alt_charset) {
+            /*
+             * convert to the given alternative charset
+             */
+            if (charset_convert(pdu->u.data_sm.message_payload, "ISO-8859-1",
+                                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));
+        }
+    }
+
+    /* prepend udh if present */
+    /* RK: udh data is not prepended to payload
+    if (octstr_len(msg->sms.udhdata)) {
+        octstr_insert(pdu->u.data_sm.short_message, msg->sms.udhdata, 0);
+    }
+    RK: sm_lenght is not a data_sm member.
+    pdu->u.data_sm.sm_length = octstr_len(pdu->u.data_sm.short_message);
+    */
+
+    /*
+     * check for validity and defered settings
+     */
+    /* RK: TODO: This should be either qos_time_to_live or ms_validity
+    if (msg->sms.validity >= 0) {
+        struct tm tm = gw_gmtime(time(NULL) + msg->sms.validity * 60);
+        pdu->u.data_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",
+                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+                tm.tm_hour, tm.tm_min, tm.tm_sec);
+    }
+    */
+
+    /*
+    RK: TODO: Which field?
+    if (msg->sms.deferred >= 0) {
+        struct tm tm = gw_gmtime(time(NULL) + msg->sms.deferred * 60);
+        pdu->u.data_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",
+                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+                tm.tm_hour, tm.tm_min, tm.tm_sec);
+    }
+    */
+    /* RK: added code: fill in optional parameters */
+    error(0, "SMPP: UDHLEN: %ld", octstr_len(msg->sms.udhdata));
+    if (octstr_len(msg->sms.udhdata) > 0) {
+        udhcurrent = 1;
+        udhlen = octstr_len(msg->sms.udhdata) - 1;
+        while (udhcurrent < udhlen) {
+                error(0, "SMPP: Processing: %i", octstr_get_char(msg->sms.udhdata, udhcurrent));
+                udhtype = GETLONGFROMUDHDATA(udhcurrent);
+                error(0, "SMPP: UDHTYPE: %x", udhtype);
+                udhcurrent += 2;
+                switch (udhtype) {
+                case 0x0003:
+                        /* catenation header */
+                        sar_msg_ref_num = GETSHORTFROMUDHDATA(udhcurrent++);
+                        sar_total_segments = GETSHORTFROMUDHDATA(udhcurrent++);
+                        sar_segment_seqnum = GETSHORTFROMUDHDATA(udhcurrent++);
+                        break;
+                case 0x0504:
+                        /* binary header */
+                        destination_port = GETLONGFROMUDHDATA(udhcurrent);
+                        udhcurrent += 2;
+                        source_port = GETLONGFROMUDHDATA(udhcurrent);
+                        udhcurrent += 2;
+                        error(0, "SMPP: Source: %x, Destination: %x", source_port, destination_port);
+                        break;
+                default:
+                        /* oops... we have a header value we dont know about */
+                        udhcurrent = udhlen;
+                        break;
+                }
+        }
+        if (source_port) pdu->u.data_sm.source_port = source_port;
+        if (destination_port) pdu->u.data_sm.destination_port = destination_port;
+        /* we should also send sar data if only one segment */
+        pdu->u.data_sm.sar_msg_ref_num = sar_msg_ref_num;
+        pdu->u.data_sm.sar_total_segments = sar_total_segments;
+        pdu->u.data_sm.sar_segment_seqnum = sar_segment_seqnum;
+        pdu->u.data_sm.payload_type = 0; /* set to 0, default */
+    }
+
+    /* ask for the delivery reports if needed */
+    if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
+        pdu->u.data_sm.registered_delivery = 1;
+    else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
+        pdu->u.data_sm.registered_delivery = 2;
+
+    /* set priority */
+    /*
+    RK: Dont have such a thing in data_sm
+    if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
+        pdu->u.data_sm.priority_flag = msg->sms.priority;
+    else
+        pdu->u.data_sm.priority_flag = smpp->priority;
+    */
+
+    /* set more messages to send */
+    if (smpp->version > 0x33 && msg->sms.msg_left > 0)
+        pdu->u.data_sm.more_messages_to_send = 1;
+
+    return pdu;
+}
+
 
 static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
 {
@@ -1034,7 +1284,7 @@
         /* it's not a error if we still have data buffered */
         ret = (ret == 1) ? 0 : ret;
     } else
-	ret = -1;
+        ret = -1;
     octstr_destroy(os);
     return ret;
 }
@@ -1050,6 +1300,8 @@
         return 0;
 
     while (*pending_submits < smpp->max_pending_submits) {
+        int send_as_data_sm;
+
         /* check our throughput */
         if (smpp->conn->throughput > 0 && load_get(smpp->load, 0) >= smpp->conn->throughput) {
             debug("bb.sms.smpp", 0, "SMPP[%s]: throughput limit exceeded (%.02f,%.02f)",
@@ -1059,13 +1311,19 @@
         debug("bb.sms.smpp", 0, "SMPP[%s]: throughput (%.02f,%.02f)",
               octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
 
-    	/* Get next message, quit if none to be sent */
+            /* Get next message, quit if none to be sent */
     	msg = gw_prioqueue_remove(smpp->msgs_to_send);
         if (msg == NULL)
             break;
 
         /* Send PDU, record it as waiting for ack from SMS center */
-        pdu = msg_to_pdu(smpp, msg);
+        /* RK: todo: make this a setting in smpp.conf */
+        send_as_data_sm = ((smpp->send_binary_as_data_sm) && (octstr_len(msg->sms.udhdata) > 2) && (GETLONGFROMUDHDATA(1) == 0x0504));
+        if (send_as_data_sm) {
+            pdu = msg_to_data_pdu(smpp, msg);
+        } else {
+            pdu = msg_to_submit_pdu(smpp, msg);
+        }
         if (pdu == NULL) {
             bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED SMS"));
             continue;
@@ -1073,7 +1331,11 @@
         /* check for write errors */
         if (send_pdu(conn, smpp->conn->id, pdu) == 0) {
             struct smpp_msg *smpp_msg = smpp_msg_create(msg);
-            os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
+            if (send_as_data_sm) {
+                os = octstr_format("%ld", pdu->u.data_sm.sequence_number);
+            } else {
+                os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
+            }
             dict_put(smpp->sent_msgs, os, smpp_msg);
             smpp_pdu_destroy(pdu);
             octstr_destroy(os);
@@ -1365,14 +1627,14 @@
          * Obey which SMPP msg_id type this SMSC is using, where we
          * have the following semantics for the variable smpp_msg_id:
          *
-         * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm
+         * bit 1: type for submit_sm/data_sm, bit 2: type for deliver_sm
          *
          * if bit is set value is hex otherwise dec
          *
-         * 0x00 deliver_sm dec, submit_sm_resp dec
-         * 0x01 deliver_sm dec, submit_sm_resp hex
-         * 0x02 deliver_sm hex, submit_sm_resp dec
-         * 0x03 deliver_sm hex, submit_sm_resp hex
+         * 0x00 deliver_sm dec, submit_sm/data_sm dec
+         * 0x01 deliver_sm dec, submit_sm/data_sm hex
+         * 0x02 deliver_sm hex, submit_sm/data_sm dec
+         * 0x03 deliver_sm hex, submit_sm/data_sm hex
          *
          * Default behaviour is SMPP spec compliant, which means
          * msg_ids should be C strings and hence non modified.
@@ -1643,6 +1905,68 @@
             } /* end if for SMSC ACK */
             break;
 
+        case data_sm_resp:
+            os = octstr_format("%ld", pdu->u.data_sm_resp.sequence_number);
+            smpp_msg = dict_remove(smpp->sent_msgs, os);
+            octstr_destroy(os);
+            if (smpp_msg == NULL) {
+                warning(0, "SMPP[%s]: SMSC sent data_sm_resp "
+                        "with wrong sequence number 0x%08lx",
+                        octstr_get_cstr(smpp->conn->id),
+                        pdu->u.data_sm_resp.sequence_number);
+                break;
+            }
+            msg = smpp_msg->msg;
+            smpp_msg_destroy(smpp_msg, 0);
+            if (pdu->u.data_sm_resp.command_status != 0) {
+                error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
+                      "in response to data_sm.",
+                      octstr_get_cstr(smpp->conn->id),
+                      pdu->u.data_sm_resp.command_status,
+		      smpp_error_to_string(pdu->u.data_sm_resp.command_status));
+                reason = smpp_status_to_smscconn_failure_reason(
+                            pdu->u.data_sm_resp.command_status);
+
+                /*
+                 * check to see if we got a "throttling error", in which case we'll just
+                 * sleep for a while
+                 */
+                if (pdu->u.data_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
+                    time(&(smpp->throttling_err_time));
+                else
+                    smpp->throttling_err_time = 0;
+
+                bb_smscconn_send_failed(smpp->conn, msg, reason, 
+                        octstr_format("%ld/%s", pdu->u.data_sm_resp.command_status,
+                            smpp_error_to_string(pdu->u.data_sm_resp.command_status)));
+                --(*pending_submits);
+            } else {
+                Octstr *tmp;
+
+                /* check if msg_id is C string, decimal or hex for this SMSC */
+                if (smpp->smpp_msg_id_type == -1) {
+                    /* the default, C string */
+                    tmp = octstr_duplicate(pdu->u.data_sm_resp.message_id);
+                } else {
+                    if (smpp->smpp_msg_id_type & 0x01) {
+                        tmp = octstr_format("%ld", strtol(  /* hex */
+                            octstr_get_cstr(pdu->u.data_sm_resp.message_id), NULL, 16));
+                    } else {
+                        tmp = octstr_format("%ld", strtol(  /* decimal */
+                            octstr_get_cstr(pdu->u.data_sm_resp.message_id), NULL, 10));
+                    }
+                }
+
+                /* SMSC ACK.. now we have the message id. */
+                if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask))
+                    dlr_add(smpp->conn->id, tmp, msg);
+
+                octstr_destroy(tmp);
+                bb_smscconn_sent(smpp->conn, msg, NULL);
+                --(*pending_submits);
+            } /* end if for SMSC ACK */
+            break;
+
         case bind_transmitter_resp:
             if (pdu->u.bind_transmitter_resp.command_status != 0 &&
                 pdu->u.bind_transmitter_resp.command_status != SMPP_ESME_RALYNBD) {
@@ -1746,7 +2070,7 @@
                 msg = smpp_msg->msg;
                 smpp_msg_destroy(smpp_msg, 0);
 
-                error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) in response to submit_sm.",
+                error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) in response to submit_sm/data_sm.",
                       octstr_get_cstr(smpp->conn->id),
                       cmd_stat,
                 smpp_error_to_string(cmd_stat));
@@ -2190,6 +2514,7 @@
     Octstr *alt_charset;
     Octstr *alt_addr_charset;
     long connection_timeout, wait_ack, wait_ack_action;
+    int send_binary_as_data_sm;
 
     my_number = alt_addr_charset = alt_charset = NULL;
     transceiver_mode = 0;
@@ -2303,6 +2628,8 @@
         if (smpp_msg_id_type < 0 || smpp_msg_id_type > 3)
             panic(0,"SMPP: Invalid value for msg-id-type directive in configuraton");
     }
+    if (cfg_get_bool(&send_binary_as_data_sm, grp, octstr_imm("send-binary-as-datasm")) == -1)
+        send_binary_as_data_sm = 0;
 
     /* check for an alternative charset */
     alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
@@ -2328,7 +2655,8 @@
                        dest_addr_npi, enquire_link_interval,
                        max_pending_submits, version, priority, validity, my_number,
                        smpp_msg_id_type, autodetect_addr, alt_charset, alt_addr_charset,
-                       service_type, connection_timeout, wait_ack, wait_ack_action);
+                       service_type, connection_timeout, wait_ack, wait_ack_action,
+                       send_binary_as_data_sm);
 
     cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton"));
     cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.142
diff -u -r1.142 cfg.def
--- gwlib/cfg.def	6 Dec 2009 17:24:14 -0000	1.142
+++ gwlib/cfg.def	16 Jan 2010 16:25:28 -0000
@@ -387,6 +387,7 @@
     OCTSTR(status-permfail-regex)
     OCTSTR(status-tempfail-regex)
     OCTSTR(max-sms-octets)
+    OCTSTR(send-binary-as-datasm)
     OCTSTR(login-prompt)
     OCTSTR(password-prompt)
     OCTSTR(generic-param-username)
kannel.conf (application/octet-stream, 1.6 KB)
# Bearerbox related core
group = core
admin-port = 13000
admin-password = notGiven
box-deny-ip = *.*.*.*
box-allow-ip = 127.0.0.1
smsbox-port = 13001
wapbox-port = 13002
dlr-storage = internal
udp-deny-ip = *.*.*.*
udp-allow-ip = 127.0.0.1
wdp-interface-name = *

# SMSC CONNECTIONS

# production

# TXT
group = smsc
smsc = smpp
smsc-id = carriertxt
allowed-smsc-id = carriertxt
host = 10.1.1.1
port = 6400
transceiver-mode = 1
smsc-username = notGiven
smsc-password = notGiven
system-type =
alt-charset = UTF-8
enquire-link-interval = 60

# WAP
group = smsc
smsc = smpp
smsc-id = carrierwap
allowed-smsc-id = carrierwap
host = 10.1.1.1
port = 6400
transceiver-mode = 1
smsc-username = notGiven
smsc-password = notGiven
system-type =
service-type = WAP
alt-charset = UTF-8
send-binary-as-datasm = 1
enquire-link-interval = 60


# SMSBOX SETUP
group = smsbox
sendsms-port = 13003
sendsms-url = /sendsms
sendota-url = /sendota
bearerbox-host = 127.0.0.1
global-sender = ourShortCode

# SEND-SMS USERS
group = sendsms-user
name = Txt
username = txt
password = notGiven
default-smsc = carriertxt

# SMS SERVICES
group = sms-service
keyword = default
get-url = "http://127.0.0.1:1980/sms?p=%p&b=%b"

# WAPBOX SETUP
group = wapbox
bearerbox-host = 127.0.0.1

# PPG SERVICES
group = ppg
service-name = metroppg
ppg-port = 13004
ppg-url = /wappush
ppg-allow-ip = "127.0.0.1"
global-sender = ourShortCode
#default-dlr-url = "http://127.0.0.1:1980/dlr?smsc-id=%i&status=%d&anser=%A&to=%P&from=%p&ts=%t"

# PPG USERS
group = wap-push-user
wap-push-user = Wap
ppg-username = wap
ppg-password = notGiven
default-smsc = carrierwap
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.