[PATCH] allow start/stop/restart for equals smsc-id's

Alexander Malysh <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi,

attached you can find a patch that make it possible to start/stop/restart of
_all_ smscconn's that have equals smsc-id's instead of only one. This patch
maybe need some discussion, due to a behaviour change.

Comments/votes are highly welcome!

Thanks,
Alex
bb_smscconn_equal_smsc.diff (text/x-diff, 11.7 KB)
Index: gw/bb_smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_smscconn.c,v
retrieving revision 1.76
diff -a -u -p -r1.76 bb_smscconn.c
--- gw/bb_smscconn.c	28 Jun 2004 15:18:35 -0000	1.76
+++ gw/bb_smscconn.c	2 Aug 2004 00:05:21 -0000
@@ -100,12 +100,12 @@ extern Counter *outgoing_sms_counter;
 extern List *flow_threads;
 extern List *suspended;
 extern List *isolated;
-extern Dict *smsbox_routes;
 
 /* our own thingies */
 
 static volatile sig_atomic_t smsc_running;
 static List *smsc_list;
+static RWLock smsc_list_lock = GW_RWLOCK_INITIALIZER;
 static List *smsc_groups;
 static Octstr *unified_prefix;
 
@@ -191,8 +191,6 @@ void bb_smscconn_sent(SMSCConn *conn, Ms
 
 void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
 {
-    Msg *mnack;
-
     switch (reason) {
 
     case SMSCCONN_FAILED_SHUTDOWN:
@@ -202,14 +200,7 @@ void bb_smscconn_send_failed(SMSCConn *c
     default:
 
 	/* write NACK to store file */
-
-	mnack = msg_create(ack);
-	mnack->ack.nack = ack_failed;
-	mnack->ack.time = sms->sms.time;
-	uuid_copy(mnack->ack.id, sms->sms.id);
-
-	(void) store_save(mnack);
-	msg_destroy(mnack);
+        store_save_ack(sms, ack_failed);
 
 	if (conn) counter_increase(conn->failed);
 	if (reason == SMSCCONN_FAILED_DISCARDED)
@@ -315,13 +306,10 @@ long bb_smscconn_receive(SMSCConn *conn,
                 bb_alog_sms(conn, sms, "DROPPED Received DLR");
             else
                 bb_alog_sms(conn, sms, "DROPPED Received SMS");
-            msg_destroy(copy);
+
             /* put nack into store-file */
-            copy = msg_create(ack);
-            uuid_copy(copy->ack.id, sms->sms.id);
-            copy->ack.time = sms->sms.time;
-            copy->ack.nack = ack_failed;
-            store_save(copy);
+            store_save_ack(sms, ack_failed);
+
             msg_destroy(copy);
 
             msg_destroy(sms);
@@ -477,19 +465,24 @@ int smsc2_start(Cfg *cfg)
     return 0;
 }
 
-static int smsc2_find(Octstr *id)
+/*
+ * Find a matching smsc-id in the smsc list starting at position start.
+ * NOTE: Caller must ensure that smsc_list is properly locked!
+ */
+static long smsc2_find(Octstr *id, long start)
 {
     SMSCConn *conn = NULL;
-    int i;
+    long i;
 
-    list_lock(smsc_list);
-    for (i = 0; i < list_len(smsc_list); i++) {
+    if (start > list_len(smsc_list) || start < 0)
+        return -1;
+
+    for (i = start; i < list_len(smsc_list); i++) {
         conn = list_get(smsc_list, i);
         if (conn != NULL && octstr_compare(conn->id, id) == 0) {
             break;
         }
     }
-    list_unlock(smsc_list);
     if (i >= list_len(smsc_list))
         i = -1;
     return i;
@@ -498,87 +491,103 @@ static int smsc2_find(Octstr *id)
 int smsc2_stop_smsc(Octstr *id)
 {
     SMSCConn *conn;
-    int i;
+    long i = -1;
 
+    gw_rwlock_rdlock(&smsc_list_lock);
     /* find the specific smsc via id */
-    if ((i = smsc2_find(id)) == -1) {
-        error(0, "HTTP: Could not shutdown smsc-id `%s'", octstr_get_cstr(id));
-        return -1;
-    }
-    conn = list_get(smsc_list, i);
-    if (conn != NULL && conn->status == SMSCCONN_DEAD) {
-        error(0, "HTTP: Could not shutdown already dead smsc-id `%s'", 
-              octstr_get_cstr(id));
-        return -1;
+    while((i = smsc2_find(id, ++i)) != -1) {
+        conn = list_get(smsc_list, i);
+        if (conn != NULL && smscconn_status(conn) == SMSCCONN_DEAD) {
+            info(0, "HTTP: Could not shutdown already dead smsc-id `%s'",
+                octstr_get_cstr(id));
+        } else {
+            info(0,"HTTP: Shutting down smsc-id `%s'", octstr_get_cstr(id));
+            smscconn_shutdown(conn, 1);   /* shutdown the smsc */
+        }
     }
-    info(0,"HTTP: Shutting down smsc-id `%s'", octstr_get_cstr(id));
-    smscconn_shutdown(conn, 1);   /* shutdown the smsc */
+    gw_rwlock_unlock(&smsc_list_lock);
     return 0;
 }
 
 int smsc2_restart_smsc(Octstr *id)
 {
     CfgGroup *grp;
-    SMSCConn *conn;
+    SMSCConn *conn, *new_conn;
     Octstr *smscid = NULL;
-    int i;
+    long i = -1;
+    int num = 0;
 
+    gw_rwlock_wrlock(&smsc_list_lock);
     /* find the specific smsc via id */
-    if ((i = smsc2_find(id)) == -1) {
-        error(0, "HTTP: Could not re-start non defined smsc-id `%s'", 
-              octstr_get_cstr(id));
-        return -1;
-    }
-
-    /* check if smsc is online status already */
-    conn = list_get(smsc_list, i);
-    if (conn != NULL && conn->status != SMSCCONN_DEAD) {
-        error(0, "HTTP: Could not re-start already running smsc-id `%s'", 
-              octstr_get_cstr(id));
-        return -1;
-    }
-  
-    list_delete(smsc_list, i, 1); /* drop it from the active smsc list */
-	smscconn_destroy(conn);       /* destroy the connection */
-
-    /* find the group with smsc id */
-    grp = NULL;
-    list_lock(smsc_groups);
-    for (i = 0; i < list_len(smsc_groups) && 
-        (grp = list_get(smsc_groups, i)) != NULL; i++) {
-        smscid = cfg_get(grp, octstr_imm("smsc-id"));
-        if (smscid != NULL && octstr_compare(smscid, id) == 0) {
+    while((i = smsc2_find(id, ++i)) != -1) {
+        int hit;
+        long group_index;
+        /* check if smsc has online status already */
+        conn = list_get(smsc_list, i);
+        if (conn != NULL && smscconn_status(conn) != SMSCCONN_DEAD) {
+            warning(0, "HTTP: Could not re-start already running smsc-id `%s'",
+                octstr_get_cstr(id));
+            continue;
+        }
+        /* find the group with equal smsc id */
+        hit = 0;
+        grp = NULL;
+        for (group_index = 0; group_index < list_len(smsc_groups) && 
+             (grp = list_get(smsc_groups, group_index)) != NULL; group_index++) {
+            smscid = cfg_get(grp, octstr_imm("smsc-id"));
+            if (smscid != NULL && octstr_compare(smscid, id) == 0) {
+                if (hit == num)
+                    break;
+                else
+                    hit++;
+            }
+            octstr_destroy(smscid);
+            smscid = NULL;
+        }
+        octstr_destroy(smscid);
+        if (hit != num) {
+            /* config group not found */
+            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);
+        if (new_conn == NULL) {
+            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 */
+        list_delete(smsc_list, i, 1);
+        /* destroy the connection */
+        smscconn_destroy(conn);
+        list_insert(smsc_list, i, new_conn);
+        smscconn_start(new_conn);
+        num++;
     }
-    list_unlock(smsc_groups);
-    octstr_destroy(smscid);
-    if (i > list_len(smsc_groups))
-        return -1;
+    gw_rwlock_unlock(&smsc_list_lock);
     
-    info(0,"HTTP: Re-starting smsc-id `%s'", octstr_get_cstr(id));
-
-    conn = smscconn_create(grp, 1); 
-    if (conn == NULL)
-        error(0, "Cannot start with SMSC connection failing");
-    list_append(smsc_list, conn);
-
-    smscconn_start(conn);
+    /* wake-up the router */
     if (router_thread >= 0)
         gwthread_wakeup(router_thread);
 
+    
     return 0;
 }
 
 void smsc2_resume(void)
 {
     SMSCConn *conn;
-    int i;
-    
+    long i;
+
+    gw_rwlock_rdlock(&smsc_list_lock);
     for (i = 0; i < list_len(smsc_list); i++) {
         conn = list_get(smsc_list, i);
         smscconn_start(conn);
     }
+    gw_rwlock_unlock(&smsc_list_lock);
     if (router_thread >= 0)
 	gwthread_wakeup(router_thread);
 }
@@ -587,33 +596,34 @@ void smsc2_resume(void)
 void smsc2_suspend(void)
 {
     SMSCConn *conn;
-    int i;
-    
-    list_lock(smsc_list);
+    long i;
+
+    gw_rwlock_rdlock(&smsc_list_lock);
     for (i = 0; i < list_len(smsc_list); i++) {
         conn = list_get(smsc_list, i);
         smscconn_stop(conn);
     }
-    list_unlock(smsc_list);
+    gw_rwlock_unlock(&smsc_list_lock);
 }
 
 
 int smsc2_shutdown(void)
 {
     SMSCConn *conn;
-    int i;
+    long i;
 
-    if (!smsc_running) return -1;
+    if (!smsc_running)
+        return -1;
 
     /* Call shutdown for all SMSC Connections; they should
      * handle that they quit, by emptying queues and then dying off
      */
-    list_lock(smsc_list);
+    gw_rwlock_rdlock(&smsc_list_lock);
     for(i=0; i < list_len(smsc_list); i++) {
         conn = list_get(smsc_list, i);
 	smscconn_shutdown(conn, 1);
     }
-    list_unlock(smsc_list);
+    gw_rwlock_unlock(&smsc_list_lock);
     if (router_thread >= 0)
 	gwthread_wakeup(router_thread);
 
@@ -631,26 +641,26 @@ int smsc2_shutdown(void)
 void smsc2_cleanup(void)
 {
     SMSCConn *conn;
-    int i;
+    long i;
 
     debug("smscconn", 0, "final clean-up for SMSCConn");
     
-    /* do only cleanup if any smsc-ids have been defined */
-    if (smsc_list != NULL) {
-        list_lock(smsc_list);
-        for (i = 0; i < list_len(smsc_list); i++) {
-            conn = list_get(smsc_list, i);
-            smscconn_destroy(conn);
-        }
-        list_unlock(smsc_list);
+    gw_rwlock_wrlock(&smsc_list_lock);
+    for (i = 0; i < list_len(smsc_list); i++) {
+        conn = list_get(smsc_list, i);
+        smscconn_destroy(conn);
     }
     list_destroy(smsc_list, NULL);
+    smsc_list = NULL;
+    gw_rwlock_unlock(&smsc_list_lock);
     list_destroy(smsc_groups, NULL);
     octstr_destroy(unified_prefix);    
     numhash_destroy(white_list);
     numhash_destroy(black_list);
-    if (white_list_regex != NULL) gw_regex_destroy(white_list_regex);
-    if (black_list_regex != NULL) gw_regex_destroy(black_list_regex);
+    if (white_list_regex != NULL)
+        gw_regex_destroy(white_list_regex);
+    if (black_list_regex != NULL)
+        gw_regex_destroy(black_list_regex);
 }
 
 
@@ -659,7 +669,8 @@ Octstr *smsc2_status(int status_type)
     Octstr *tmp;
     char tmp3[64];
     char *lb;
-    int i, para = 0;
+    long i;
+    int para = 0;
     SMSCConn *conn;
     StatusInfo info;
     const Octstr *conn_id = NULL;
@@ -683,8 +694,8 @@ Octstr *smsc2_status(int status_type)
         tmp = octstr_format("%sSMSC connections:%s", para ? "<p>" : "", lb);
     else
         tmp = octstr_format("<smscs><count>%d</count>\n\t", list_len(smsc_list));
-    
-    list_lock(smsc_list);
+
+    gw_rwlock_rdlock(&smsc_list_lock);
     for (i = 0; i < list_len(smsc_list); i++) {
         conn = list_get(smsc_list, i);
 
@@ -752,7 +763,7 @@ Octstr *smsc2_status(int status_type)
             info.received, info.sent, info.failed,
             info.queued, lb);
     }
-    list_unlock(smsc_list);
+    gw_rwlock_unlock(&smsc_list_lock);
 
     if (para)
         octstr_append_cstr(tmp, "</p>");
@@ -786,11 +797,6 @@ int smsc2_rout(Msg *msg)
     if (msg_type(msg) != sms)
 	return -1;
     
-    if (list_len(smsc_list) == 0) {
-	warning(0, "No SMSCes to receive message");
-	return -1;
-    }
-
     /* unify prefix of receiver, in case of it has not been
      * already done */
 
@@ -800,8 +806,12 @@ int smsc2_rout(Msg *msg)
     /* select in which list to add this
      * start - from random SMSCConn, as they are all 'equal'
      */
-
-    list_lock(smsc_list);
+    gw_rwlock_rdlock(&smsc_list_lock);
+    if (list_len(smsc_list) == 0) {
+	warning(0, "No SMSCes to receive message");
+        gw_rwlock_unlock(&smsc_list_lock);
+	return SMSCCONN_FAILED_DISCARDED;
+    }
 
     s = gw_rand() % list_len(smsc_list);
     best_preferred = best_ok = NULL;
@@ -837,7 +847,7 @@ int smsc2_rout(Msg *msg)
 	    bo_load = info.load;
 	}
     }
-    list_unlock(smsc_list);
+    gw_rwlock_unlock(&smsc_list_lock);
 
     if (best_preferred)
 	ret = smscconn_send(best_preferred, msg);
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.