Kannel Patches

hisham malik <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
I'm attaching the following patches for the kannel source.


1. Concatenate using SAR parameters:
Added support for concatenation through SAR parameters in Kannel

2. Re-Establish Transmitter Connection:
Re-establish transmitter connection when connection is lost with smsc.
concat_sar.patch (application/octet-stream, 29.1 KB)
Index: smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.114
diff -u -r1.114 smsc_smpp.c
--- smsc/smsc_smpp.c	2 Apr 2009 20:30:19 -0000	1.114
+++ smsc/smsc_smpp.c	30 Apr 2009 09:16:18 -0000
@@ -499,6 +499,13 @@
         octstr_delete(msg->sms.msgdata, 0, udhl);
     }
 
+    //support SAR parameters
+	if (pdu->u.deliver_sm.sar_total_segments > 1) {
+		msg->sms.sar_msg_ref_num = pdu->u.deliver_sm.sar_msg_ref_num;
+		msg->sms.sar_total_segments = pdu->u.deliver_sm.sar_total_segments;
+		msg->sms.sar_segment_seqnum = pdu->u.deliver_sm.sar_segment_seqnum;
+	}
+
     dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
 
     /* handle default data coding */
Index: msg-decl.h
===================================================================
RCS file: /home/cvs/gateway/gw/msg-decl.h,v
retrieving revision 1.37
diff -u -r1.37 msg-decl.h
--- msg-decl.h	14 Jan 2009 11:11:46 -0000	1.37
+++ msg-decl.h	30 Apr 2009 09:16:17 -0000
@@ -1,58 +1,58 @@
-/* ==================================================================== 
- * The Kannel Software License, Version 1.0 
- * 
- * Copyright (c) 2001-2009 Kannel Group  
- * Copyright (c) 1998-2001 WapIT Ltd.   
- * All rights reserved. 
- * 
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
- * 
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in 
- *    the documentation and/or other materials provided with the 
- *    distribution. 
- * 
- * 3. The end-user documentation included with the redistribution, 
- *    if any, must include the following acknowledgment: 
- *       "This product includes software developed by the 
- *        Kannel Group (http://www.kannel.org/)." 
- *    Alternately, this acknowledgment may appear in the software itself, 
- *    if and wherever such third-party acknowledgments normally appear. 
- * 
- * 4. The names "Kannel" and "Kannel Group" must not be used to 
- *    endorse or promote products derived from this software without 
- *    prior written permission. For written permission, please  
- *    contact [email protected]. 
- * 
- * 5. Products derived from this software may not be called "Kannel", 
- *    nor may "Kannel" appear in their name, without prior written 
- *    permission of the Kannel Group. 
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- * ==================================================================== 
- * 
- * This software consists of voluntary contributions made by many 
- * individuals on behalf of the Kannel Group.  For more information on  
- * the Kannel Group, please see <http://www.kannel.org/>. 
- * 
- * Portions of this software are based upon software originally written at  
- * WapIT Ltd., Helsinki, Finland for the Kannel project.  
- */ 
+/* ====================================================================
+ * The Kannel Software License, Version 1.0
+ *
+ * Copyright (c) 2001-2009 Kannel Group
+ * Copyright (c) 1998-2001 WapIT Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Kannel Group (http://www.kannel.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Kannel" and "Kannel Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please
+ *    contact [email protected].
+ *
+ * 5. Products derived from this software may not be called "Kannel",
+ *    nor may "Kannel" appear in their name, without prior written
+ *    permission of the Kannel Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Kannel Group.  For more information on
+ * the Kannel Group, please see <http://www.kannel.org/>.
+ *
+ * Portions of this software are based upon software originally written at
+ * WapIT Ltd., Helsinki, Finland for the Kannel project.
+ */
 
 /*
  * msg-decl.h - message declarations
@@ -76,7 +76,7 @@
         INTEGER(command);
         OCTSTR(boxc_id);
     })
-    
+
 MSG(sms,
 	{
 		OCTSTR(sender);
@@ -111,6 +111,9 @@
         INTEGER(resend_try);
         INTEGER(resend_time);
         OCTSTR(meta_data);
+		INTEGER(sar_msg_ref_num);
+		INTEGER(sar_total_segments);
+		INTEGER(sar_segment_seqnum);
 	})
 
 MSG(ack,
@@ -119,7 +122,7 @@
 		INTEGER(time);
 		UUID(id);
 	})
-    
+
 MSG(wdp_datagram,
 	{
 		OCTSTR(source_address);
Index: bb_smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_smscconn.c,v
retrieving revision 1.100
diff -u -r1.100 bb_smscconn.c
--- bb_smscconn.c	14 Jan 2009 11:11:46 -0000	1.100
+++ bb_smscconn.c	30 Apr 2009 09:16:16 -0000
@@ -1,58 +1,58 @@
-/* ==================================================================== 
- * The Kannel Software License, Version 1.0 
- * 
- * Copyright (c) 2001-2009 Kannel Group  
- * Copyright (c) 1998-2001 WapIT Ltd.   
- * All rights reserved. 
- * 
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
- * 
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
- * 
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in 
- *    the documentation and/or other materials provided with the 
- *    distribution. 
- * 
- * 3. The end-user documentation included with the redistribution, 
- *    if any, must include the following acknowledgment: 
- *       "This product includes software developed by the 
- *        Kannel Group (http://www.kannel.org/)." 
- *    Alternately, this acknowledgment may appear in the software itself, 
- *    if and wherever such third-party acknowledgments normally appear. 
- * 
- * 4. The names "Kannel" and "Kannel Group" must not be used to 
- *    endorse or promote products derived from this software without 
- *    prior written permission. For written permission, please  
- *    contact [email protected]. 
- * 
- * 5. Products derived from this software may not be called "Kannel", 
- *    nor may "Kannel" appear in their name, without prior written 
- *    permission of the Kannel Group. 
- * 
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- * ==================================================================== 
- * 
- * This software consists of voluntary contributions made by many 
- * individuals on behalf of the Kannel Group.  For more information on  
- * the Kannel Group, please see <http://www.kannel.org/>. 
- * 
- * Portions of this software are based upon software originally written at  
- * WapIT Ltd., Helsinki, Finland for the Kannel project.  
- */ 
+/* ====================================================================
+ * The Kannel Software License, Version 1.0
+ *
+ * Copyright (c) 2001-2009 Kannel Group
+ * Copyright (c) 1998-2001 WapIT Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Kannel Group (http://www.kannel.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Kannel" and "Kannel Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please
+ *    contact [email protected].
+ *
+ * 5. Products derived from this software may not be called "Kannel",
+ *    nor may "Kannel" appear in their name, without prior written
+ *    permission of the Kannel Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Kannel Group.  For more information on
+ * the Kannel Group, please see <http://www.kannel.org/>.
+ *
+ * Portions of this software are based upon software originally written at
+ * WapIT Ltd., Helsinki, Finland for the Kannel project.
+ */
 
 /*
  * SMSC Connection interface for Bearerbox.
@@ -65,7 +65,7 @@
  * Kalle Marjola 2000 for project Kannel
  * Alexander Malysh <amalysh at kannel.org> 2003, 2004, 2005
  */
- 
+
 #include "gw-config.h"
 
 #include <errno.h>
@@ -193,7 +193,7 @@
 static void handle_split(SMSCConn *conn, Msg *msg, long reason)
 {
     struct split_parts *split = msg->sms.split_parts;
-    
+
     /*
      * If temporarely failed, try again immediately but only if connection active.
      * Because if connection is not active we will loop for ever here consuming 100% CPU
@@ -205,7 +205,7 @@
         msg_destroy(msg);
         return;
     }
-    
+
     /*
      * if the reason is not a success and status is still success
      * then set status of a split to the reason.
@@ -233,7 +233,7 @@
      * we will split it again in smscconn_send(...).
      */
     msg_destroy(msg);
-        
+
     if (counter_decrease(split->parts_left) <= 1) {
         /* all splited parts were processed */
         counter_destroy(split->parts_left);
@@ -257,7 +257,7 @@
         octstr_destroy(reply);
         return;
     }
-    
+
     counter_increase(outgoing_sms_counter);
     load_increase(outgoing_sms_load);
     if (conn) counter_increase(conn->sent);
@@ -294,7 +294,7 @@
         octstr_destroy(reply);
         return;
     }
-    
+
     switch (reason) {
     case SMSCCONN_FAILED_TEMPORARILY:
         /*
@@ -309,7 +309,7 @@
              */
            if (sms_resend_retry >= 0 && sms->sms.resend_try >= sms_resend_retry) {
                warning(0, "Maximum retries for message exceeded, discarding it!");
-               bb_smscconn_send_failed(NULL, sms, SMSCCONN_FAILED_DISCARDED, 
+               bb_smscconn_send_failed(NULL, sms, SMSCCONN_FAILED_DISCARDED,
                                        octstr_create("Retries Exceeded"));
                break;
            }
@@ -318,7 +318,7 @@
        }
        gwlist_produce(outgoing_sms, sms);
        break;
-       
+
     case SMSCCONN_FAILED_SHUTDOWN:
         gwlist_produce(outgoing_sms, sms);
         break;
@@ -388,7 +388,7 @@
         msg_destroy(sms);
         return SMSCCONN_FAILED_REJECTED;
     }
-    
+
     if (black_list &&
 	numhash_find_number(black_list, sms->sms.sender) == 1) {
 	info(0, "Number <%s> is in black-list, message discarded",
@@ -439,7 +439,7 @@
                 msg_destroy(sms);
                 return SMSCCONN_SUCCESS;
             case concat_complete:
-                /* Combined sms received! save new one since it is now combined. */ 
+                /* Combined sms received! save new one since it is now combined. */
                 msg_destroy(sms);
                 /* Change the sms. */
                 sms = msg_duplicate(copy);
@@ -463,7 +463,7 @@
          */
         rc = route_incoming_to_boxc(copy);
     }
-    
+
     if (rc == -1 || (rc != SMSCCONN_SUCCESS && rc != SMSCCONN_QUEUED)) {
         warning(0, "incoming messages queue too long, dropping a message");
         if (sms->sms.sms_type == report_mo)
@@ -597,7 +597,7 @@
 
     /* create split sms counter */
     split_msg_counter = counter_create();
-    
+
     /* create smsc list and rwlock for it */
     smsc_list = gwlist_create();
     gw_rwlock_init_static(&smsc_list_lock);
@@ -610,7 +610,7 @@
     white_list_url = cfg_get(grp, octstr_imm("white-list"));
     if (white_list_url != NULL) {
         if ((white_list = numhash_create(octstr_get_cstr(white_list_url))) == NULL)
-            panic(0, "Could not get white-list at URL <%s>", 
+            panic(0, "Could not get white-list at URL <%s>",
                   octstr_get_cstr(white_list_url));
     }
     if ((os = cfg_get(grp, octstr_imm("white-list-regex"))) != NULL) {
@@ -618,11 +618,11 @@
             panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
         octstr_destroy(os);
     }
-    
+
     black_list_url = cfg_get(grp, octstr_imm("black-list"));
     if (black_list_url != NULL) {
         if ((black_list = numhash_create(octstr_get_cstr(black_list_url))) == NULL)
-            panic(0, "Could not get black-list at URL <%s>", 
+            panic(0, "Could not get black-list at URL <%s>",
                   octstr_get_cstr(black_list_url));
     }
     if ((os = cfg_get(grp, octstr_imm("black-list-regex"))) != NULL) {
@@ -636,7 +636,7 @@
         sms_resend_frequency = 60;
     }
     info(0, "Set SMS resend frequency to %ld seconds.", sms_resend_frequency);
-            
+
     if (cfg_get_integer(&sms_resend_retry, grp, octstr_imm("sms-resend-retry")) == -1) {
         sms_resend_retry = -1;
         info(0, "SMS resend retry set to unlimited.");
@@ -659,18 +659,18 @@
 
     smsc_groups = cfg_get_multi_group(cfg, octstr_imm("smsc"));
     gwlist_add_producer(smsc_list);
-    for (i = 0; i < gwlist_len(smsc_groups) && 
+    for (i = 0; i < gwlist_len(smsc_groups) &&
         (grp = gwlist_get(smsc_groups, i)) != NULL; i++) {
-        conn = smscconn_create(grp, 1); 
+        conn = smscconn_create(grp, 1);
         if (conn == NULL)
             panic(0, "Cannot start with SMSC connection failing");
         gwlist_append(smsc_list, conn);
     }
     gwlist_remove_producer(smsc_list);
-    
+
     if ((router_thread = gwthread_create(sms_router, NULL)) == -1)
 	panic(0, "Failed to start a new thread for SMS routing");
-    
+
     gwlist_add_producer(incoming_sms);
     smsc_running = 1;
     return 0;
@@ -749,7 +749,7 @@
         /* find the group with equal smsc id */
         hit = 0;
         grp = NULL;
-        for (group_index = 0; group_index < gwlist_len(smsc_groups) && 
+        for (group_index = 0; group_index < gwlist_len(smsc_groups) &&
              (grp = gwlist_get(smsc_groups, group_index)) != NULL; group_index++) {
             smscid = cfg_get(grp, octstr_imm("smsc-id"));
             if (smscid != NULL && octstr_compare(smscid, id) == 0) {
@@ -767,7 +767,7 @@
             error(0, "HTTP: Could not find config for smsc-id `%s'", octstr_get_cstr(id));
             break;
         }
-        
+
         info(0,"HTTP: Re-starting smsc-id `%s'", octstr_get_cstr(id));
 
         new_conn = smscconn_create(grp, 1);
@@ -775,7 +775,7 @@
             error(0, "Start of SMSC connection failed, smsc-id `%s'", octstr_get_cstr(id));
             continue; /* keep old connection on the list */
         }
-        
+
         /* drop old connection from the active smsc list */
         gwlist_delete(smsc_list, i, 1);
         /* destroy the connection */
@@ -785,11 +785,11 @@
         num++;
     }
     gw_rwlock_unlock(&smsc_list_lock);
-    
+
     /* wake-up the router */
     if (router_thread >= 0)
         gwthread_wakeup(router_thread);
-    
+
     return 0;
 }
 
@@ -807,7 +807,7 @@
         smscconn_start(conn);
     }
     gw_rwlock_unlock(&smsc_list_lock);
-    
+
     if (router_thread >= 0)
         gwthread_wakeup(router_thread);
 }
@@ -874,7 +874,7 @@
         return;
 
     debug("smscconn", 0, "final clean-up for SMSCConn");
-    
+
     gw_rwlock_wrlock(&smsc_list_lock);
     for (i = 0; i < gwlist_len(smsc_list); i++) {
         conn = gwlist_get(smsc_list, i);
@@ -884,7 +884,7 @@
     smsc_list = NULL;
     gw_rwlock_unlock(&smsc_list_lock);
     gwlist_destroy(smsc_groups, NULL);
-    octstr_destroy(unified_prefix);    
+    octstr_destroy(unified_prefix);
     numhash_destroy(white_list);
     numhash_destroy(black_list);
     octstr_destroy(white_list_url);
@@ -940,8 +940,8 @@
         conn = gwlist_get(smsc_list, i);
 
         if ((smscconn_info(conn, &info) == -1)) {
-            /* 
-             * we do not delete SMSCs from the list 
+            /*
+             * we do not delete SMSCs from the list
              * this way we can show in the status which links are dead
              */
             continue;
@@ -959,7 +959,7 @@
             octstr_append_cstr(tmp, "    ");
             octstr_append(tmp, conn_id);
             octstr_append_cstr(tmp, "    ");
-        } 
+        }
         if (status_type == BBSTATUS_XML) {
             octstr_append_cstr(tmp, "<smsc>\n\t\t<name>");
             octstr_append(tmp, conn_name);
@@ -990,7 +990,7 @@
             default:
                 sprintf(tmp3, "unknown");
         }
-	
+
         if (status_type == BBSTATUS_XML)
             octstr_format_append(tmp, "<status>%s</status>\n\t\t<received>%ld</received>"
                 "\n\t\t<sent>%ld</sent>\n\t\t<failed>%ld</failed>\n\t\t"
@@ -1165,11 +1165,11 @@
 static long route_incoming_to_smsc(SMSCConn *conn, Msg *msg)
 {
     Octstr *smsc;
-    
+
     /* sanity check */
     if (!conn || !msg)
         return -1;
-        
+
     /* check for dlr rerouting */
     if (!conn->reroute_dlr && (msg->sms.sms_type == report_mo || msg->sms.sms_type == report_mt))
         return -1;
@@ -1186,7 +1186,7 @@
         /* drop into outbound queue again for routing */
         return smsc2_rout(msg, 0);
     }
-    
+
     if (conn->reroute_to_smsc) {
         /* change message direction */
         store_save_ack(msg, ack_success);
@@ -1197,7 +1197,7 @@
         msg->sms.smsc_id = octstr_duplicate(conn->reroute_to_smsc);
         return smsc2_rout(msg, 0);
     }
-    
+
     if (conn->reroute_by_receiver && msg->sms.receiver &&
                  (smsc = dict_get(conn->reroute_by_receiver, msg->sms.receiver))) {
         /* change message direction */
@@ -1211,7 +1211,7 @@
         return smsc2_rout(msg, 0);
     }
 
-    return -1; 
+    return -1;
 }
 
 
@@ -1254,7 +1254,7 @@
 {
     if (incoming_concat_msgs != NULL) /* already initialised? */
         return;
-    incoming_concat_msgs = dict_create(max_incoming_sms_qlength > 0 ? max_incoming_sms_qlength : 1024, 
+    incoming_concat_msgs = dict_create(max_incoming_sms_qlength > 0 ? max_incoming_sms_qlength : 1024,
                                        destroy_concatMsg);
     concat_lock = mutex_create();
     debug("bb.sms",0,"smsbox MO concatenated message handling enabled");
@@ -1357,6 +1357,114 @@
     gwlist_destroy(keys, octstr_destroy_item);
 }
 
+/**
+ * Concatenate using sar parameters
+ */
+static int check_concatenation_sar(Msg **pmsg, Octstr *smscid)
+{
+    Msg *msg = *pmsg;
+    Octstr *key;
+	int refnum = msg->sms.sar_msg_ref_num;
+	int totalparts = msg->sms.sar_total_segments;
+	int part = msg->sms.sar_segment_seqnum;
+	ConcatMsg *cmsg;
+    int ret = concat_complete;
+    int i;
+
+    if(totalparts == 0) {
+    	return concat_none;
+    }
+
+    if (part < 1 || part > totalparts) {
+        warning(0, "Invalid concatenation SAR [ref = %d] in message from %s!",
+                refnum, octstr_get_cstr(msg->sms.sender));
+        return concat_none;
+    }
+
+    debug("bb.sms.splits", 0, "Got part %d [ref %d, total parts %d] of message from %s. Dump follows:",
+          part, refnum,totalparts, octstr_get_cstr(msg->sms.sender));
+
+    msg_dump(msg,0);
+
+    key = octstr_format("%S %S %S %d", msg->sms.sender, msg->sms.receiver, smscid, refnum);
+    mutex_lock(concat_lock);
+    if ((cmsg = dict_get(incoming_concat_msgs, key)) == NULL) {
+        cmsg = gw_malloc(sizeof(*cmsg));
+        cmsg->refnum = refnum;
+        cmsg->total_parts = totalparts;
+        cmsg->num_parts = 0;
+        cmsg->key = octstr_duplicate(key);
+        cmsg->ack = ack_success;
+        cmsg->parts = gw_malloc(totalparts * sizeof(*cmsg->parts));
+        memset(cmsg->parts, 0, cmsg->total_parts * sizeof(*cmsg->parts)); /* clear it. */
+
+        dict_put(incoming_concat_msgs, key, cmsg);
+    }
+    octstr_destroy(key);
+
+    if (totalparts != cmsg->total_parts) {
+        /* totalparts in udh and cmsg not equal assume bad message */
+        error(0, "Totalparts in SAR doesn't match received before, "
+                "total parts <%d>:<%d> part %d, ref %d, from %s, to %s. Discarded!",
+                cmsg->total_parts, totalparts, part, refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
+        mutex_unlock(concat_lock);
+        store_save_ack(msg, ack_success);
+        msg_destroy(msg);
+        *pmsg = msg = NULL;
+        return concat_error;
+    }
+
+    /* check if we have seen message part before... */
+    if (cmsg->parts[part - 1] != NULL) {
+        warning(0, "Duplicate message part %d, ref %d, from %s, to %s. Discarded!",
+                part, refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
+        store_save_ack(msg, ack_success);
+        msg_destroy(msg);
+        *pmsg = msg = NULL;
+    } else {
+        cmsg->parts[part -1] = msg;
+        cmsg->num_parts++;
+        /* always update receive time so we have it from last part and don't timeout */
+        cmsg->trecv = time(NULL);
+    }
+
+    if (cmsg->num_parts < cmsg->total_parts) {  /* wait for more parts. */
+        *pmsg = msg = NULL;
+        mutex_unlock(concat_lock);
+        return concat_pending;
+    }
+
+    /* we have all the parts: Put them together, return message. */
+    msg = msg_duplicate(cmsg->parts[0]);
+    uuid_generate(msg->sms.id); /* give it a new ID. */
+
+    debug("bb.sms.splits",0,"Received all concatenated message parts from %s, to %s, refnum %d",
+          octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver), refnum);
+
+    for (i = 1; i < cmsg->total_parts; i++)
+        octstr_append(msg->sms.msgdata, cmsg->parts[i]->sms.msgdata);
+
+    /* Attempt to save the new one, if that fails, then reply with fail. */
+    if (store_save(msg) == -1) {
+        mutex_unlock(concat_lock);
+        msg_destroy(msg);
+        *pmsg = msg = NULL;
+        return concat_error;
+    } else
+        *pmsg = msg; /* return the message part. */
+
+    /* Delete it from the queue and from the Dict. */
+    /* Note: dict_put with NULL value delete and destroy value */
+    dict_put(incoming_concat_msgs, cmsg->key, NULL);
+    mutex_unlock(concat_lock);
+
+    debug("bb.sms.splits", 0, "Got full message [ref %d] of message from %s to %s. Dumping: ",
+          refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
+    msg_dump(msg,0);
+
+    return ret;
+}
+
 /* Checks if message is concatenated. Returns:
  * - returns concat_complete if no concat parts, or message complete
  * - returns concat_pending (and sets *pmsg to NULL) if parts pending
@@ -1369,12 +1477,18 @@
     Octstr *udh = msg->sms.udhdata, *key;
     ConcatMsg *cmsg;
     int ret = concat_complete;
+    int ret_sar = concat_complete;
 
     /* ... module not initialised or there is no UDH or smscid is NULL. */
-    if (incoming_concat_msgs == NULL || (l = octstr_len(udh)) == 0 || smscid == NULL)
+    if (incoming_concat_msgs == NULL || ((l = octstr_len(udh)) == 0 && msg->sms.sar_total_segments == 0) || smscid == NULL)
         return concat_none;
 
-    for (pos = 1, c = -1; pos < l - 1; pos += iel + 2) {
+    ret_sar = check_concatenation_sar(pmsg, smscid);
+	if (ret_sar != concat_none && ret_sar != concat_complete) {
+		return ret_sar;
+	}
+
+	for (pos = 1, c = -1; pos < l - 1; pos += iel + 2) {
         iel = octstr_get_char(udh, pos + 1);
         if ((c = octstr_get_char(udh,pos)) == 0 || c == 8)
             break;
@@ -1397,9 +1511,9 @@
 
     debug("bb.sms.splits", 0, "Got part %d [ref %d, total parts %d] of message from %s. Dump follows:",
           part, refnum,totalparts, octstr_get_cstr(msg->sms.sender));
-     
+
     msg_dump(msg,0);
-     
+
     key = octstr_format("%S %S %S %d", msg->sms.sender, msg->sms.receiver, smscid, refnum);
     mutex_lock(concat_lock);
     if ((cmsg = dict_get(incoming_concat_msgs, key)) == NULL) {
@@ -1429,11 +1543,11 @@
     }
 
     /* check if we have seen message part before... */
-    if (cmsg->parts[part - 1] != NULL) {	  
+    if (cmsg->parts[part - 1] != NULL) {
         warning(0, "Duplicate message part %d, ref %d, from %s, to %s. Discarded!",
                 part, refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
         store_save_ack(msg, ack_success);
-        msg_destroy(msg); 
+        msg_destroy(msg);
         *pmsg = msg = NULL;
     } else {
         cmsg->parts[part -1] = msg;
@@ -1459,12 +1573,12 @@
         octstr_append(msg->sms.msgdata, cmsg->parts[i]->sms.msgdata);
 
     /* Attempt to save the new one, if that fails, then reply with fail. */
-    if (store_save(msg) == -1) {	  
+    if (store_save(msg) == -1) {
         mutex_unlock(concat_lock);
         msg_destroy(msg);
         *pmsg = msg = NULL;
         return concat_error;
-    } else 
+    } else
         *pmsg = msg; /* return the message part. */
 
     /* Delete it from the queue and from the Dict. */
@@ -1498,7 +1612,7 @@
 {
     numhash_destroy(white_list);
     numhash_destroy(black_list);
-    
+
     if (white_list_url != NULL) {
         white_list = numhash_create(octstr_get_cstr(white_list_url));
     }
re_establish_transmitter.patch (application/octet-stream, 1.1 KB)
Index: smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.114
diff -u -r1.114 smsc_smpp.c
--- smsc_smpp.c	2 Apr 2009 20:30:19 -0000	1.114
+++ smsc_smpp.c	30 Apr 2009 09:21:42 -0000
@@ -1861,7 +1861,15 @@
                  * check if we are still connected.
                  * Note: smsc can send unbind request, so we must check it.
                  */
-                if (smpp->conn->status != SMSCCONN_ACTIVE && smpp->conn->status != SMSCCONN_ACTIVE_RECV) {
+				/**
+				 * PATCH for handling disconnection issues
+				 *
+				 * if (smpp->conn->status != SMSCCONN_ACTIVE && smpp->conn->status != SMSCCONN_ACTIVE_RECV) {
+				 * we are disconnected if the transmitter mode is set and connection
+				 * status say SMSCCONN_ACTIVE_RECV
+				 */
+                if (smpp->conn->status != SMSCCONN_ACTIVE &&
+                		!(smpp->conn->status == SMSCCONN_ACTIVE_RECV && !transmitter)) {
                      /* we are disconnected */
                      ret = -1;
                      break;
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.