Index: doc/userguide/userguide.xml
===================================================================
RCS file: /home/cvs/gateway/doc/userguide/userguide.xml,v
retrieving revision 1.353
diff -u -b -w -r1.353 userguide.xml
--- doc/userguide/userguide.xml	23 Jun 2009 07:19:58 -0000	1.353
+++ doc/userguide/userguide.xml	8 Jul 2009 10:25:47 -0000
@@ -1918,6 +1918,8 @@
         Re-start a single SMSC link. Password required. Additionally
 		  the <literal>smsc</literal> parameter must be given to identify
  		  which <literal>smsc-admin-id</literal> should be re-started.
+        The configuration for the SMSC link is re-read from disk before
+        the action is performed.
    </entry></row>
 
   	<row><entry><literal>stop-smsc</literal></entry>
@@ -1926,6 +1928,21 @@
 		  the <literal>smsc</literal> parameter must be given (see above).
    </entry></row>
 
+    <row><entry><literal>add-smsc</literal></entry>
+    <entry valign="bottom">
+        Adds an SMSC link previously removed or created after the service was
+        started. Password required. Additionally the <literal>smsc</literal>
+        parameter must be given (see above).
+    </entry></row>
+
+    <row><entry><literal>remove-smsc</literal></entry>
+    <entry valign="bottom">
+        Removes an existing SMSC link. Password required. Additionally the
+        <literal>smsc</literal> parameter must be given (see above). If you
+        want a permanent removal, you should also remove the entry from the
+        configuration file or it will be recreated after a service restart.
+    </entry></row>
+
 	<row><entry><literal>restart</literal></entry>
    <entry valign="bottom">
         Re-start whole bearerbox, hence all SMSC links. Password required.
Index: gw/bb_http.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_http.c,v
retrieving revision 1.53
diff -u -b -w -r1.53 bb_http.c
--- gw/bb_http.c	12 Jan 2009 16:46:56 -0000	1.53
+++ gw/bb_http.c	8 Jul 2009 10:25:49 -0000
@@ -266,6 +266,42 @@
         return octstr_create("SMSC id not given");
 }
 
+static Octstr *httpd_remove_smsc(List *cgivars, int status_type)
+{
+    Octstr *reply;
+    Octstr *smsc;
+    if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
+    if ((reply = httpd_check_status())!= NULL) return reply;
+
+    /* check if the smsc id is given */
+    smsc = http_cgi_variable(cgivars, "smsc");
+    if (smsc) {
+        if (bb_remove_smsc(smsc) == -1)
+            return octstr_format("Could not remove smsc-id `%s'", octstr_get_cstr(smsc));
+        else
+            return octstr_format("SMSC `%s' removed", octstr_get_cstr(smsc));
+    } else
+        return octstr_create("SMSC id not given");
+}
+
+static Octstr *httpd_add_smsc(List *cgivars, int status_type)
+{
+    Octstr *reply;
+    Octstr *smsc;
+    if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
+    if ((reply = httpd_check_status())!= NULL) return reply;
+
+    /* check if the smsc id is given */
+    smsc = http_cgi_variable(cgivars, "smsc");
+    if (smsc) {
+        if (bb_add_smsc(smsc) == -1)
+            return octstr_format("Could not add smsc-id `%s'", octstr_get_cstr(smsc));
+        else
+            return octstr_format("SMSC `%s' added", octstr_get_cstr(smsc));
+    } else
+        return octstr_create("SMSC id not given");
+}
+
 static Octstr *httpd_restart_smsc(List *cgivars, int status_type)
 {
     Octstr *reply;
@@ -312,6 +348,8 @@
     { "flush-dlr", httpd_flush_dlr },
     { "stop-smsc", httpd_stop_smsc },
     { "start-smsc", httpd_restart_smsc },
+    { "add-smsc", httpd_add_smsc },
+    { "remove-smsc", httpd_remove_smsc },
     { "reload-lists", httpd_reload_lists },
     { NULL , NULL } /* terminate list */
 };
Index: gw/bb_smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_smscconn.c,v
retrieving revision 1.101
diff -u -b -w -r1.101 bb_smscconn.c
--- gw/bb_smscconn.c	6 May 2009 18:47:34 -0000	1.101
+++ gw/bb_smscconn.c	8 Jul 2009 10:25:53 -0000
@@ -115,6 +115,9 @@
 /* incoming sms queue control */
 extern long max_incoming_sms_qlength;
 
+/* configuration filename */
+extern Octstr *cfg_filename;
+
 /* our own thingies */
 
 static volatile sig_atomic_t smsc_running;
@@ -494,6 +497,22 @@
     return SMSCCONN_SUCCESS;
 }
 
+int bb_reload_smsc_groups()
+{
+    Cfg *cfg;
+
+    debug("bb.sms", 0, "Reloading groups list from disk");
+    cfg =  cfg_create(cfg_filename);
+    if (cfg_read(cfg) == -1) {
+        warning(0, "Error opening configuration file %s", octstr_get_cstr(cfg_filename));
+        return -1;
+    }
+    if (smsc_groups != NULL)
+        gwlist_destroy(smsc_groups, NULL);
+    smsc_groups = cfg_get_multi_group(cfg, octstr_imm("smsc"));
+    return 0;
+}
+
 
 /*---------------------------------------------------------------------
  * Other functions
@@ -703,6 +722,7 @@
 {
     SMSCConn *conn;
     long i = -1;
+    int success = 0;
 
     if (!smsc_running)
         return -1;
@@ -717,9 +737,14 @@
         } else {
             info(0,"HTTP: Shutting down smsc-id `%s'", octstr_get_cstr(id));
             smscconn_shutdown(conn, 1);   /* shutdown the smsc */
+            success = 1;
         }
     }
     gw_rwlock_unlock(&smsc_list_lock);
+    if (success == 0) {
+        error(0, "SMSC %s not found", octstr_get_cstr(id));
+        return -1;
+    }
     return 0;
 }
 
@@ -729,15 +754,21 @@
     SMSCConn *conn, *new_conn;
     Octstr *smscid = NULL;
     long i = -1;
+    int hit;
     int num = 0;
+    int success = 0;
 
     if (!smsc_running)
         return -1;
 
     gw_rwlock_wrlock(&smsc_list_lock);
+
+    if (bb_reload_smsc_groups() != 0) {
+        gw_rwlock_unlock(&smsc_list_lock);
+        return -1;
+    }
     /* find the specific smsc via id */
     while((i = smsc2_find(id, ++i)) != -1) {
-        int hit;
         long group_index;
         /* check if smsc has online status already */
         conn = gwlist_get(smsc_list, i);
@@ -746,13 +777,17 @@
                 octstr_get_cstr(id));
             continue;
         }
-        /* find the group with equal smsc id */
-        hit = 0;
+        /* find the group with equal smsc (admin-)id */
+        hit = -1;
         grp = NULL;
         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-admin-id"));
+            if (smscid == NULL)
             smscid = cfg_get(grp, octstr_imm("smsc-id"));
             if (smscid != NULL && octstr_compare(smscid, id) == 0) {
+                if (hit < 0)
+                    hit = 0;
                 if (hit == num)
                     break;
                 else
@@ -782,14 +817,99 @@
         smscconn_destroy(conn);
         gwlist_insert(smsc_list, i, new_conn);
         smscconn_start(new_conn);
+        success = 1;
         num++;
     }
+
     gw_rwlock_unlock(&smsc_list_lock);
     
+    if (success == 0) {
+        error(0, "SMSC %s not found", octstr_get_cstr(id));
+        return -1;
+    }
     /* wake-up the router */
     if (router_thread >= 0)
         gwthread_wakeup(router_thread);
+    return 0;
+}
+
+int smsc2_remove_smsc(Octstr *id)
+{
+    SMSCConn *conn;
+    Octstr *smscid = NULL;
+    long i = -1;
+    int success = 0;
+
+    if (!smsc_running)
+        return -1;
+
+    gw_rwlock_wrlock(&smsc_list_lock);
+
+    gwlist_add_producer(smsc_list);
+    while((i = smsc2_find(id, ++i)) != -1) {
+        conn = gwlist_get(smsc_list, i);
+        gwlist_delete(smsc_list, i, 1);
+        smscconn_shutdown(conn, 0);
+        smscconn_destroy(conn);
+        success = 1;
+    }
+    gwlist_remove_producer(smsc_list);
+
+    gw_rwlock_unlock(&smsc_list_lock);
+    if (success == 0) {
+        error(0, "SMSC %s not found", octstr_get_cstr(id));
+        return -1;
+    }
+    return 0;
+}
+
+int smsc2_add_smsc(Octstr *id)
+{
+    CfgGroup *grp;
+    SMSCConn *conn;
+    Octstr *smsc_type;
+    Octstr *smscid = NULL;
+    long i;
+    int success = 0;
+
+    if (!smsc_running)
+        return -1;
+
+    gw_rwlock_wrlock(&smsc_list_lock);
+    if (bb_reload_smsc_groups() != 0) {
+        gw_rwlock_unlock(&smsc_list_lock);
+        return -1;
+    }
     
+    if (smsc2_find(id, 0) != -1) {
+        warning(0, "Could not add already existing SMSC %s", octstr_get_cstr(id));
+        gw_rwlock_unlock(&smsc_list_lock);
+        return -1;
+    }
+
+    gwlist_add_producer(smsc_list);
+    grp = NULL;
+    for (i = 0; i < gwlist_len(smsc_groups) &&
+        (grp = gwlist_get(smsc_groups, i)) != NULL; i++) {
+        smscid = cfg_get(grp, octstr_imm("smsc-admin-id"));
+        if (smscid == NULL)
+            smscid = cfg_get(grp, octstr_imm("smsc-id"));
+
+        if (smscid != NULL && octstr_compare(smscid, id) == 0) {
+            conn = smscconn_create(grp, 1);
+            if (conn != NULL) {
+                gwlist_append(smsc_list, conn);
+                smscconn_start(conn);
+                success = 1;
+            }
+        }
+    }
+    gwlist_remove_producer(smsc_list);
+    gw_rwlock_unlock(&smsc_list_lock);
+    if (success == 0) {
+        error(0, "SMSC %s not found", octstr_get_cstr(id));
+        return -1;
+    }
     return 0;
 }
 
Index: gw/bearerbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/bearerbox.c,v
retrieving revision 1.169
diff -u -b -w -r1.169 bearerbox.c
--- gw/bearerbox.c	12 Jan 2009 16:46:56 -0000	1.169
+++ gw/bearerbox.c	8 Jul 2009 10:25:56 -0000
@@ -122,6 +122,9 @@
  */
 List *isolated;
 
+/* configuration filename */
+Octstr *cfg_filename;
+
 volatile sig_atomic_t bb_status;
 
 /* 
@@ -591,7 +594,6 @@
 {
     int cf_index;
     Cfg *cfg;
-    Octstr *filename;
 
     bb_status = BB_RUNNING;
     
@@ -606,15 +608,13 @@
     cf_index = get_and_set_debugs(argc, argv, check_args);
 
     if (argv[cf_index] == NULL)
-        filename = octstr_create("kannel.conf");
+        cfg_filename = octstr_create("kannel.conf");
     else
-        filename = octstr_create(argv[cf_index]);
-    cfg = cfg_create(filename); 
+        cfg_filename = octstr_create(argv[cf_index]);
+    cfg = cfg_create(cfg_filename);
     
     if (cfg_read(cfg) == -1)
-        panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
-    
-    octstr_destroy(filename);
+        panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(cfg_filename));
 
     dlr_init(cfg);
     
@@ -821,6 +821,16 @@
     return smsc2_restart_smsc(id);
 }
 
+int bb_add_smsc(Octstr *id)
+{
+    return smsc2_add_smsc(id);
+}
+
+int bb_remove_smsc(Octstr *id)
+{
+    return smsc2_remove_smsc(id);
+}
+
 int bb_restart(void)
 {
     restart = 1;
Index: gw/bearerbox.h
===================================================================
RCS file: /home/cvs/gateway/gw/bearerbox.h,v
retrieving revision 1.35
diff -u -b -w -r1.35 bearerbox.h
--- gw/bearerbox.h	12 Jan 2009 16:46:56 -0000	1.35
+++ gw/bearerbox.h	8 Jul 2009 10:26:00 -0000
@@ -170,6 +170,8 @@
 
 int smsc2_stop_smsc(Octstr *id);   /* shutdown a specific smsc */
 int smsc2_restart_smsc(Octstr *id);  /* re-start a specific smsc */
+int smsc2_add_smsc(Octstr *id);   /* add a new smsc */
+int smsc2_remove_smsc(Octstr *id);   /* remove a specific smsc */
 
 
 /*---------------
@@ -208,8 +210,11 @@
 int bb_restart(void);
 int bb_flush_dlr(void);
 int bb_stop_smsc(Octstr *id);
+int bb_add_smsc(Octstr *id);
+int bb_remove_smsc(Octstr *id);
 int bb_restart_smsc(Octstr *id);
 int bb_reload_lists(void);
+int bb_reload_smsc_groups(void);
 
 /* return string of current status */
 Octstr *bb_print_status(int status_type);
