Hi all,

attached is a patch that I developed today for internal smsbox routing
inside bearerbox. The patch is quite big, so I'll try to explain what
the intention is and what it does.

Basically currently any sms that arrives at bearerbox via a specific
thread of a specific smsc module is produced to a global queue
(incoming_sms). All connected smsbox'es do grap a msg from that queue
all process it. This mechanism is basically used to load-balance msg
traffic to various smsbox'es.

However, sometimes it may be desireable for various reasons to be able
to "route" the sms msg to a specific smsbox. This has to be done
inside bearerbox, between the smsc module layer and the communication
to the smsbox'es.

First, bearerbox needs to know about smsboxes in a way that is
semantically more relevant. We know the IP of the smsbox and even a
local file descriptor, but that's not enough. Imagine a smsbox sending
a DLR-requesting msg. Not smsbox(1) sends msg to bearerbox, bearerbox
holds the dlr queue, receives the report from the smsc module and now
does not know if it should route to smsbox(1) or smsbox(2). Now
basically in this easy scenario it does not matter, because each
smsbox instance does "only" a URL lookup. But think of a SMPP proxying
box that has own state tables and reports have to be re-routed exactly
to that instance to update status tables.

Ok, here is how the thing works:

  * gw/smsbox.c: graps a 'smsbox-id' from it's config group and sends
an admin msg identifying itself with a id to bearerbox
  * gw/bb_boxc.c: when an admin msg is received by an identicying
smsbox, the incoming queue is switched to a private list, so that no
other smsbox shares the same list with the new identified smsbox
  * gw/msg.h: adding a boxc_id Octstr to type sms to hold the
smsbox-id while transporting msg from smsbox'es to bearerbox
  * gw/dlr.c: adding a boxc_id parameter to the dlr_add() abstraction
layers and to the relecant smsc_foobar.c modules
  * the message went out of the smsc module door
  * the delivery report comes in
  * gw/dlr.c: dlr_find() inserts the remembered boxc_id to the msg
structure and passes it through the smsc module to gw/bb_smscconn.c
  * gw/bb_smscconn.c: gets all incoming sms from the smsc modules and
calls the new gw/bb_boxc.c:route_incoming_sms() routine to descride to
while list this msg is produced and hence to which smsbox the msg is
routed

The smsbox routing is defined in the configuration file via the
multi-grou "smsbox-route", like this

  group = smsbox-route
  smsbox-id = smsbox_1
  smsc_ids = "fake_1;fake_2;fake_3"
  shortcuts = "83444;83555"

which means route any message coming from the smsc-id's or
msg.receiver number to this smsbox instance.

To store the mapping and routing information, 3 hash dictionaries are
used. One that holds all connection pointers from the smsbox'es and 2
seperate dictionaries for the smsc-id and receiver number mapping.

I'd like to apply the patch. Mainly it does not change any current
behaviour, but it's still a cerious change in the bearerbox internals,
so I'd like to ask for comments or objections before going to commit
this. I have tested a lot of this, but no garantee, as always :))

Stipe

[EMAIL PROTECTED]
-------------------------------------------------------------------
Wapme Systems AG

Vogelsanger Weg 80
40470 Düsseldorf

Tel: +49-211-74845-0
Fax: +49-211-74845-299

E-Mail: [EMAIL PROTECTED]
Internet: http://www.wapme-systems.de
-------------------------------------------------------------------
wapme.net - wherever you are
diff -ru gateway/gw/bb_boxc.c gateway-smpp/gw/bb_boxc.c
--- gateway/gw/bb_boxc.c        2002-09-06 14:03:16.000000000 +0200
+++ gateway-smpp/gw/bb_boxc.c   2002-09-06 21:21:16.000000000 +0200
@@ -40,6 +40,9 @@
 static volatile sig_atomic_t wapbox_running;
 static List    *wapbox_list = NULL;
 static List    *smsbox_list = NULL;
+static Dict *smsbox_by_id = NULL; 
+static Dict *smsbox_by_smsc = NULL; 
+static Dict *smsbox_by_receiver = NULL; 
 
 static long    smsbox_port;
 static int smsbox_port_ssl = 0;
@@ -65,6 +68,7 @@
     List       *retry;         /* If sending fails */
     List               *outgoing;
     volatile sig_atomic_t alive;
+    Octstr *boxc_id;
 } Boxc;
 
 
@@ -173,6 +177,26 @@
                      store_save(msg);
                      debug("bb.boxc", 0, "boxc_receiver: got ack");
             }
+            else if (msg_type(msg) == admin && msg->admin.command == cmd_identify) {
+              List *newlist;
+
+              /* and add the boxc_ud into conn for boxc_status() output */
+              if (conn->boxc_id == NULL)
+                   conn->boxc_id = octstr_duplicate(msg->admin.boxc_id);
+              /* 
+               * re-link the incoming queue for this connection to an independent
+               */
+              newlist = list_create();
+              list_add_producer(newlist);
+              conn->incoming = newlist;
+              conn->retry = newlist;
+
+              /* add this identified smsbox to the dictionary */       
+              dict_put(smsbox_by_id, msg->admin.boxc_id, conn);
+                     debug("bb.boxc", 0, "boxc_receiver: got boxc_id <%s> from <%s>",
+                    octstr_get_cstr(msg->admin.boxc_id),
+                    octstr_get_cstr(conn->client_ip));
+            }
             else
                      warning(0, "boxc_receiver: unknown msg received from <%s>, "
                        "ignored", octstr_get_cstr(conn->client_ip));
@@ -270,6 +294,7 @@
     boxc->client_ip = ip;
     boxc->alive = 1;
     boxc->connect_time = time(NULL);
+    boxc->boxc_id = NULL;
     return boxc;
 }    
 
@@ -283,6 +308,8 @@
     if (boxc->conn)
            conn_destroy(boxc->conn);
     octstr_destroy(boxc->client_ip);
+    if (boxc->boxc_id)
+        octstr_destroy(boxc->boxc_id);
     gw_free(boxc);
 }    
 
@@ -349,6 +376,7 @@
            list_remove_producer(flow_threads);
            return;
     }
+
     newconn->incoming = incoming_sms;
     newconn->retry = incoming_sms;
     newconn->outgoing = outgoing_sms;
@@ -367,7 +395,14 @@
 
     gwthread_join(sender);
 
-cleanup:    
+cleanup: 
+    if (newconn->boxc_id) {
+        dict_remove(smsbox_by_id, newconn->boxc_id);
+        while (list_producer_count(newconn->incoming) > 0)
+              list_remove_producer(newconn->incoming);
+        gw_assert(list_len(newconn->incoming) == 0);
+        list_destroy(newconn->incoming, NULL);
+    }
     list_delete_equal(smsbox_list, newconn);
     boxc_destroy(newconn);
 
@@ -676,6 +711,12 @@
 
     list_destroy(smsbox_list, NULL);
     smsbox_list = NULL;
+    dict_destroy(smsbox_by_id);
+    smsbox_by_id = NULL;
+    dict_destroy(smsbox_by_smsc);
+    smsbox_by_smsc = NULL;
+    dict_destroy(smsbox_by_receiver);
+    smsbox_by_receiver = NULL;
     
     list_remove_producer(flow_threads);
 }
@@ -721,6 +762,60 @@
 }
 
 
+/*
+ * Populates the corresponding smsbox_by_foobar dictionary hash tables
+ */
+static void init_smsbox_routes(Cfg *cfg)
+{
+    CfgGroup *grp;
+    List *list, *items;
+    Octstr *boxc_id, *smsc_ids, *shortcuts;
+    int i;
+
+    boxc_id = smsc_ids = shortcuts = NULL;
+
+    list = cfg_get_multi_group(cfg, octstr_imm("smsbox-route")); 
+ 
+    /* loop multi-group "smsbox-route" */
+    while (list && (grp = list_extract_first(list)) != NULL) { 
+         
+        if ((boxc_id = cfg_get(grp, octstr_imm("smsbox-id"))) == NULL) { 
+            grp_dump(grp); 
+            panic(0,"'smsbox-route' group without valid 'smsbox-id' directive!"); 
+        }
+        smsc_ids = cfg_get(grp, octstr_imm("smsc-ids"));
+        shortcuts = cfg_get(grp, octstr_imm("shortcuts"));
+
+        /* now parse the smsc-ids and shortcuts semicolon seperated list */
+        if (smsc_ids) {
+            items = octstr_split(smsc_ids, octstr_imm(";"));
+            for (i = 0; i < list_len(items); i++) {
+                Octstr *item = list_get(items, i);
+
+                debug("bb.boxc",0,"Adding smsbox routing to id <%s> for smsc id <%s>",
+                      octstr_get_cstr(boxc_id), octstr_get_cstr(item));
+
+                dict_put(smsbox_by_smsc, item, boxc_id);
+            }
+            list_destroy(items, octstr_destroy_item);
+        }
+        
+        if (shortcuts) {
+            items = octstr_split(shortcuts, octstr_imm(";"));
+            for (i = 0; i < list_len(items); i++) {
+                Octstr *item = item = list_get(items, i);
+
+                debug("bb.boxc",0,"Adding smsbox routing to id <%s> for receiver no 
+<%s>",
+                      octstr_get_cstr(boxc_id), octstr_get_cstr(item));
+            
+                dict_put(smsbox_by_receiver, item, boxc_id);
+            }
+            list_destroy(items, octstr_destroy_item);
+        }
+    }       
+}
+
+
 
 /*-------------------------------------------------------------
  * public functions
@@ -750,6 +845,12 @@
 
     
     smsbox_list = list_create();       /* have a list of connections */
+    smsbox_by_id = dict_create(10, NULL);  /* and a hash directory of identified */
+    smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
+    smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
+
+    init_smsbox_routes(cfg);
+
     list_add_producer(outgoing_sms);
 
     smsbox_running = 1;
@@ -907,8 +1008,9 @@
 #endif
                     );
             else
-                   octstr_format_append(tmp, "%ssmsbox, IP %s (on-line %ldd %ldh %ldm 
%lds) %s %s",
-                           ws, octstr_get_cstr(bi->client_ip),
+                   octstr_format_append(tmp, "%ssmsbox:%s, IP %s (on-line %ldd %ldh 
+%ldm %lds) %s %s",
+                           ws, (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : 
+"(none)"), 
+                    octstr_get_cstr(bi->client_ip),
                            t/3600/24, t/3600%24, t/60%60, t%60, 
 #ifdef HAVE_LIBSSL
                     conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
@@ -958,3 +1060,59 @@
     box_allow_ip = NULL;
     box_deny_ip = NULL;
 }
+
+/*
+ * Route the incoming message to a specific smsbox conn
+ * or simply to a random if no shortcut routing and msg->sms.boxc_id
+ * match.
+ */
+void route_incoming_sms(Msg *msg)
+{
+    Boxc *conn = NULL;
+    Octstr *s, *r;
+
+    s = r = NULL;
+    gw_assert(msg_type(msg) == sms);
+
+    msg_dump(msg, 0);
+
+    /* 
+     * We have a specific route to pass this msg to smsbox-id 
+     * Lookup the connection in the dictionary.
+     */
+    if (msg->sms.boxc_id != NULL) {
+        
+        conn = dict_get(smsbox_by_id, msg->sms.boxc_id);
+        if (conn == 0) {
+            /* 
+             * something is wrong, this was the smsbox connection we used 
+             * for sending, so it seems this smsbox is gone
+             */
+            error(0,"Could not route message to smsbox id <%s>, smsbox is gone!",
+                  octstr_get_cstr(msg->sms.boxc_id));
+        } 
+    }
+
+    /*
+     * Check if we have a "smsbox-route" for this msg.
+     * Where the shortcut route has a higher priority then the smsc-id rule.
+     */
+    if (conn == NULL) {
+        s = (msg->sms.smsc_id ? dict_get(smsbox_by_smsc, msg->sms.smsc_id) : NULL);
+        r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, msg->sms.receiver) : 
+NULL);
+        conn = r ? dict_get(smsbox_by_id, r) : (s ? dict_get(smsbox_by_id, s) : NULL);
+    }
+
+    /* 
+     * ok, none of the routing things applied previously, so route it to
+     * a random smsbox via the shared incoming_sms queue, otherwise to the
+     * smsc specific incoming queue
+     */
+    if (conn == NULL)
+        list_produce(incoming_sms, msg);
+    else
+        list_produce(conn->incoming, msg);
+
+}
+
+
diff -ru gateway/gw/bb_smscconn.c gateway-smpp/gw/bb_smscconn.c
--- gateway/gw/bb_smscconn.c    2002-09-06 14:03:16.000000000 +0200
+++ gateway-smpp/gw/bb_smscconn.c       2002-09-06 18:30:47.000000000 +0200
@@ -44,6 +44,7 @@
 extern List *flow_threads;
 extern List *suspended;
 extern List *isolated;
+extern Dict *smsbox_routes;
 
 /* our own thingies */
 
@@ -59,6 +60,8 @@
 
 static long router_thread = -1;
 
+void route_incoming_sms(Msg *sms);
+ 
 static void log_sms(SMSCConn *conn, Msg *sms, char *message)
 {
     Octstr *text, *udh;
@@ -233,7 +236,14 @@
     else
        log_sms(conn, sms, "DLR SMS");
 
-    list_produce(incoming_sms, sms);
+    /*
+     * Now try to route the message to a specific smsbox
+     * connection based on the existing msg->sms.boxc_id or
+     * the registered receiver numbers for specific smsbox'es.
+     */
+    route_incoming_sms(sms);
+
+    //list_produce(incoming_sms, sms);
     counter_increase(incoming_sms_counter);
     counter_increase(conn->received);
 
diff -ru gateway/gw/dlr.c gateway-smpp/gw/dlr.c
--- gateway/gw/dlr.c    2002-09-06 14:03:16.000000000 +0200
+++ gateway-smpp/gw/dlr.c       2002-09-06 15:22:41.000000000 +0200
@@ -13,6 +13,11 @@
  *     added more abstraction to fit for several other storage types
  * 2002-08-04: [EMAIL PROTECTED]:
  *     added simple database library (sdb) support
+ * 2002-09-06: [EMAIL PROTECTED]:
+ *     added re-routing info for DLRs to route via bearerbox to the same smsbox
+ *     instance. This is required if you use state conditioned smsboxes or smppboxes
+ *     via one bearerbox. Previously bearerbox was simple ignoring to which smsbox
+ *     connection a msg is passed. Now we can route the messages inside bearerbox.
  */
  
 #include <ctype.h>
@@ -44,6 +49,7 @@
    Octstr *service;
    Octstr *url;        
    int mask;
+   Octstr *boxc_id;
 } dlr_wle;
 
 /* 
@@ -103,6 +109,8 @@
         panic(0, "DLR: DB: directive 'field-mask' is not specified!");
     if (!(field_status = cfg_get(grp, octstr_imm("field-status"))))
            panic(0, "DLR: DB: directive 'field-status' is not specified!");
+    if (!(field_boxc = cfg_get(grp, octstr_imm("field-boxc-id"))))
+           panic(0, "DLR: DB: directive 'field-boxc-id' is not specified!");
 }
 #endif
    
@@ -376,6 +384,7 @@
        O_DELETE (dlr->destination);
        O_DELETE (dlr->service);
        O_DELETE (dlr->url);
+       O_DELETE (dlr->boxc_id);
        dlr->mask = 0;
        gw_free(dlr);
 }
@@ -386,15 +395,15 @@
  */
 
 static void dlr_add_mem(char *smsc, char *ts, char *src, char *dst, 
-                        char *service, char *url, int mask)
+                        char *service, char *url, int mask, char *boxc)
 {
    dlr_wle *dlr;
        
    if (mask & 0x1F) {
         dlr = dlr_new(); 
 
-        debug("dlr.dlr", 0, "Adding DLR smsc=%s, ts=%s, src=%s, dst=%s, mask=%d", 
-              smsc, ts, src, dst, mask);
+        debug("dlr.dlr", 0, "Adding DLR smsc=%s, ts=%s, src=%s, dst=%s, mask=%d, 
+boxc=%s", 
+              smsc, ts, src, dst, mask, boxc);
        
         dlr->smsc = octstr_create(smsc);
         dlr->timestamp = octstr_create(ts);
@@ -402,26 +411,28 @@
         dlr->destination = octstr_create(dst);
         dlr->service = octstr_create(service); 
         dlr->url = octstr_create(url);
+        dlr->boxc_id = octstr_create(boxc);
         dlr->mask = mask;
         list_append(dlr_waiting_list,dlr);
     }
 }
 
 static void dlr_add_mysql(char *smsc, char *ts, char *src, char *dst, 
-                          char *service, char *url, int mask)
+                          char *service, char *url, int mask, char *boxc)
 {
 #ifdef DLR_MYSQL
     Octstr *sql;
     int        state;
 
-    sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s) VALUES "
-                        "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d');",
+    sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES "
+                        "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d');",
                                octstr_get_cstr(table), octstr_get_cstr(field_smsc), 
                         octstr_get_cstr(field_ts), 
                         octstr_get_cstr(field_src), octstr_get_cstr(field_dst),
                         octstr_get_cstr(field_serv), octstr_get_cstr(field_url), 
-                        octstr_get_cstr(field_mask), octstr_get_cstr(field_status),
-                        smsc, ts, src, dst, service, url, mask, 0);
+                        octstr_get_cstr(field_mask), octstr_get_cstr(field_boxc),
+                        octstr_get_cstr(field_status),
+                        smsc, ts, src, dst, service, url, mask, boxc, 0);
 
     mutex_lock(dlr_mutex);
   
@@ -435,20 +446,21 @@
 }
 
 static void dlr_add_sdb(char *smsc, char *ts, char *src, char *dst, 
-                        char *service, char *url, int mask)
+                        char *service, char *url, int mask, char *boxc)
 {
 #ifdef DLR_SDB
     Octstr *sql;
     int        state;
 
-    sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s) VALUES "
-                        "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d')",
+    sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES "
+                        "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d')",
                                octstr_get_cstr(table), octstr_get_cstr(field_smsc), 
                         octstr_get_cstr(field_ts), 
                         octstr_get_cstr(field_src), octstr_get_cstr(field_dst), 
                         octstr_get_cstr(field_serv), octstr_get_cstr(field_url), 
-                        octstr_get_cstr(field_mask), octstr_get_cstr(field_status),
-                        smsc, ts, src, dst, service, url, mask, 0);
+                        octstr_get_cstr(field_mask), octstr_get_cstr(field_boxc), 
+                        octstr_get_cstr(field_status),
+                        smsc, ts, src, dst, service, url, mask, boxc, 0);
 
     mutex_lock(dlr_mutex);
   
@@ -462,16 +474,16 @@
 }
 
 void dlr_add(char *smsc, char *ts, char *src, char *dst, 
-             char *keyword, char *id, int mask)
+             char *keyword, char *id, int mask, char *boxc)
 {
     if (octstr_compare(dlr_type, octstr_imm("internal")) == 0) {
-        dlr_add_mem(smsc, ts, src, dst, keyword, id, mask);
+        dlr_add_mem(smsc, ts, src, dst, keyword, id, mask, boxc);
     } else 
     if (octstr_compare(dlr_type, octstr_imm("mysql")) == 0) {
-        dlr_add_mysql(smsc, ts, src, dst, keyword, id, mask);
+        dlr_add_mysql(smsc, ts, src, dst, keyword, id, mask, boxc);
     } else 
     if (octstr_compare(dlr_type, octstr_imm("sdb")) == 0) {
-        dlr_add_sdb(smsc, ts, src, dst, keyword, id, mask);
+        dlr_add_sdb(smsc, ts, src, dst, keyword, id, mask, boxc);
 
     /*
      * add aditional types here
@@ -522,6 +534,13 @@
                  */
                 msg->sms.msgdata = NULL;
 
+                /* 
+                 * If a boxc_id is available, then instruct bearerbox to 
+                 * route this msg back to originating smsbox
+                 */
+                msg->sms.boxc_id = octstr_len(dlr->boxc_id) ?
+                    octstr_duplicate(dlr->boxc_id) : NULL;
+
                 time(&msg->sms.time);
                 debug("dlr.dlr", 0, "created DLR message for URL <%s>", 
                       octstr_get_cstr(msg->sms.dlr_url));
@@ -555,12 +574,14 @@
     Octstr *dlr_service;
     Octstr *dlr_url;
     Octstr *source_addr;
+    Octstr *boxc_id;
     MYSQL_RES *result;
     MYSQL_ROW row;
     
-    sql = octstr_format("SELECT %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s';",
+    sql = octstr_format("SELECT %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND 
+%s='%s';",
                         octstr_get_cstr(field_mask), octstr_get_cstr(field_serv), 
                         octstr_get_cstr(field_url), octstr_get_cstr(field_src),
+                        octstr_get_cstr(field_boxc),
                         octstr_get_cstr(table), octstr_get_cstr(field_smsc),
                         smsc, octstr_get_cstr(field_ts), ts);
 
@@ -588,15 +609,13 @@
         return NULL;
     }
     
-    debug("dlr.mysql", 0, "Found entry, row[0]=%s, row[1]=%s, row[2]=%s, row[3]=%s", 
-          row[0], row[1], row[2], row[3] ? row[3] : "NULL");
+    debug("dlr.mysql", 0, "Found entry, row[0]=%s, row[1]=%s, row[2]=%s, row[3]=%s, 
+row[4]=%s", 
+          row[0], row[1], row[2], (row[3] ? row[3] : "NULL"), (row[4] ? row[4] : 
+"NULL"));
     dlr_mask = atoi(row[0]);
     dlr_service = octstr_create(row[1]);
     dlr_url = octstr_create(row[2]);
-    if(row[3])         
-       source_addr = octstr_create(row[3]);
-    else
-       source_addr = octstr_create("");
+    source_addr = row[3] ? octstr_create(row[3]) : octstr_create("");
+    boxc_id = row[4] ? octstr_create(row[4]) : octstr_create("");
     mysql_free_result(result);
     
     mutex_unlock(dlr_mutex);
@@ -630,7 +649,7 @@
 
         /* if dlr_url was present, recode it here again */
         msg->sms.dlr_url = octstr_len(dlr_url) ? 
-        octstr_duplicate(dlr_url) : NULL;      
+            octstr_duplicate(dlr_url) : NULL;  
 
         /* 
          * insert orginal message to the data segment 
@@ -638,6 +657,13 @@
          */
         msg->sms.msgdata = NULL;
 
+        /* 
+         * If a boxc_id is available, then instruct bearerbox to 
+         * route this msg back to originating smsbox
+         */
+        msg->sms.boxc_id = octstr_len(boxc_id) ?
+            octstr_duplicate(boxc_id) : NULL;
+
         time(&msg->sms.time);
         debug("dlr.dlr", 0, "created DLR message for URL <%s>", 
               octstr_get_cstr(msg->sms.dlr_url));
@@ -667,6 +693,7 @@
     octstr_destroy(dlr_service);
     octstr_destroy(dlr_url);
     octstr_destroy(source_addr);
+    octstr_destroy(boxc_id);
 
 #endif
     return msg;
@@ -682,7 +709,7 @@
 
     /* strip string into words */
     row = octstr_split(octstr_imm(p[0]), octstr_imm(" "));
-    if (list_len(row) != 4) {
+    if (list_len(row) != 5) {
         debug("dlr.sdb", 0, "Row has wrong length %ld", list_len(row));
         return 0;
     }
@@ -704,11 +731,13 @@
     Octstr *dlr_service;
     Octstr *dlr_url;
     Octstr *source_addr;
+    Octstr *boxc_id;
     List *row;
     
-    sql = octstr_format("SELECT %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s'",
+    sql = octstr_format("SELECT %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s'",
                         octstr_get_cstr(field_mask), octstr_get_cstr(field_serv), 
-                        octstr_get_cstr(field_url), octstr_get_cstr(field_src), 
+                        octstr_get_cstr(field_url), octstr_get_cstr(field_src),
+                        octstr_get_cstr(field_boxc),
                         octstr_get_cstr(table), octstr_get_cstr(field_smsc),
                         smsc, octstr_get_cstr(field_ts), ts);
 
@@ -722,16 +751,18 @@
         return NULL;
     }
 
-    debug("dlr.sdb", 0, "Found entry, row[0]=%s, row[1]=%s, row[2]=%s, row[3]=%s", 
+    debug("dlr.sdb", 0, "Found entry, row[0]=%s, row[1]=%s, row[2]=%s, row[3]=%s 
+row[4]=%s", 
           octstr_get_cstr(list_get(row, 0)), 
           octstr_get_cstr(list_get(row, 1)), 
           octstr_get_cstr(list_get(row, 2)),
-          octstr_get_cstr(list_get(row, 3)));
+          octstr_get_cstr(list_get(row, 3))
+          octstr_get_cstr(list_get(row, 4)));
 
     dlr_mask = atoi(octstr_get_cstr(list_get(row, 0)));
     dlr_service = octstr_duplicate(list_get(row, 1));
     dlr_url = octstr_duplicate(list_get(row, 2));
     source_addr = octstr_duplicate(list_get(row, 3));
+    boxc_id = octstr_duplicate(list_get(row, 4));
     list_destroy(row, octstr_destroy_item);
     
     mutex_unlock(dlr_mutex);
@@ -773,6 +804,13 @@
          */
         msg->sms.msgdata = NULL;
 
+        /* 
+         * If a boxc_id is available, then instruct bearerbox to 
+         * route this msg back to originating smsbox
+         */
+        msg->sms.boxc_id = octstr_len(boxc_id) ?
+            octstr_duplicate(boxc_id) : NULL;
+
         time(&msg->sms.time);
         debug("dlr.dlr", 0, "created DLR message for URL <%s>", 
               octstr_get_cstr(msg->sms.dlr_url));
@@ -802,6 +840,7 @@
     octstr_destroy(dlr_service);
     octstr_destroy(dlr_url);
     octstr_destroy(source_addr);
+    octstr_destroy(boxc_id);
 
 #endif
     return msg;
diff -ru gateway/gw/dlr.h gateway-smpp/gw/dlr.h
--- gateway/gw/dlr.h    2002-09-04 19:06:12.000000000 +0200
+++ gateway-smpp/gw/dlr.h       2002-09-06 15:04:45.000000000 +0200
@@ -38,7 +38,7 @@
 #endif
 Octstr *table;
 Octstr *field_smsc, *field_ts, *field_src, *field_dst, *field_serv;
-Octstr *field_url, *field_mask, *field_status;
+Octstr *field_url, *field_mask, *field_status, *field_boxc;
 #endif

 /* macros */
@@ -54,7 +54,7 @@
  * Add a new entry to the list
  */
 void dlr_add(char *smsc, char *ts, char *src, char *dst,
-             char *keyword, char *id, int mask);
+             char *keyword, char *id, int mask, char *boxc);

 /*
  * Find an entry in the list. If there is one a message is returned and
diff -ru gateway/gw/msg-decl.h gateway-smpp/gw/msg-decl.h
--- gateway/gw/msg-decl.h       2002-08-05 16:02:23.000000000 +0200
+++ gateway-smpp/gw/msg-decl.h  2002-09-06 16:26:17.000000000 +0200
@@ -16,9 +16,10 @@
        })
 
 MSG(admin,
-        {
-               INTEGER(command);
-       })
+    {
+        INTEGER(command);
+        OCTSTR(boxc_id);
+    })
     
 MSG(sms,
        {
@@ -42,8 +43,9 @@
                OCTSTR(dlr_url);
                INTEGER(pid);
                INTEGER(alt_dcs);
-        INTEGER(rpi);
+               INTEGER(rpi);
                OCTSTR(charset);
+               OCTSTR(boxc_id);
        })
 
 MSG(ack,
@@ -62,6 +64,7 @@
                OCTSTR(user_data);
        })
 
+
 #undef MSG
 #undef INTEGER
 #undef OCTSTR
diff -ru gateway/gw/msg.h gateway-smpp/gw/msg.h
--- gateway/gw/msg.h    2001-10-11 19:18:33.000000000 +0200
+++ gateway-smpp/gw/msg.h       2002-09-06 16:27:24.000000000 +0200
@@ -43,7 +43,8 @@
 enum {
     cmd_shutdown = 0,
     cmd_suspend = 1,
-    cmd_resume = 2
+    cmd_resume = 2,
+    cmd_identify = 3
 };
 
 /*
diff -ru gateway/gw/smsbox.c gateway-smpp/gw/smsbox.c
--- gateway/gw/smsbox.c 2002-08-19 19:25:59.000000000 +0200
+++ gateway-smpp/gw/smsbox.c    2002-09-06 16:56:28.000000000 +0200
@@ -44,6 +44,7 @@
 static long bb_port;
 static int bb_ssl = 0;
 static long sendsms_port = 0;
+static Octstr *smsbox_id = NULL;
 static Octstr *sendsms_url = NULL;
 static Octstr *sendota_url = NULL;
 static Octstr *xmlrpc_url = NULL;
@@ -75,6 +76,22 @@
  * Communication with the bearerbox.
  */
 
+/* 
+ * If we have a smsbox-id set, identify to bearerbox for smsbox-specific
+ * routing inside bearerbox.
+ */
+static void identify_to_bearerbox(void)
+{
+    Msg *msg;
+    
+    if (smsbox_id != NULL) {
+        msg = msg_create(admin);
+        msg->admin.command = cmd_identify;
+        msg->admin.boxc_id = octstr_duplicate(smsbox_id);
+        write_to_bearerbox(msg);
+    }
+}
+
 
 /*
  * Read an Msg from the bearerbox and send it to the proper receiver
@@ -156,6 +173,15 @@
        info(0, "No reply sent, denied.");
        return 0;
     }
+
+    /* 
+     * Encode our smsbox-id to the msg structure.
+     * This will allow bearerbox to return specific answers to the
+     * same smsbox, mainly for DLRs and SMS proxy modes.
+     */
+    if (smsbox_id != NULL) {
+        msg->sms.boxc_id = octstr_duplicate(smsbox_id);
+    }
     
     /* Empty message?  Either ignore it or substitute the "empty"
      * warning defined  */
@@ -1444,7 +1470,6 @@
        reply_msg->ack.time = msg->sms.time;
        reply_msg->ack.id = msg->sms.id;
 
-    
        if (dreport) {
            trans = urltrans_find_service(translations, msg);
 
@@ -2861,6 +2886,8 @@
     if (grp == NULL)
        panic(0, "No 'smsbox' group in configuration");
 
+    smsbox_id = cfg_get(grp, octstr_imm("smsbox-id"));
+
     p = cfg_get(grp, octstr_imm("bearerbox-host"));
     if (p != NULL) {
        octstr_destroy(bb_host);
@@ -3047,6 +3074,7 @@
         info(0, GW_NAME "Could not start heartbeat.");
     }
 
+    identify_to_bearerbox();
     read_messages_from_bearerbox();
 
     info(0, GW_NAME " smsbox terminating.");
@@ -3074,6 +3102,7 @@
     octstr_destroy(bb_host);
     octstr_destroy(global_sender);
     octstr_destroy(accepted_chars);
+    octstr_destroy(smsbox_id);
     octstr_destroy(sendsms_url);
     octstr_destroy(sendota_url);
     octstr_destroy(xmlrpc_url);
diff -ru gateway/gw/smsc/smsc_at2.c gateway-smpp/gw/smsc/smsc_at2.c
--- gateway/gw/smsc/smsc_at2.c  2002-09-06 14:03:17.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_at2.c     2002-09-06 15:23:16.000000000 +0200
@@ -1682,7 +1682,8 @@
                                octstr_get_cstr(msg->sms.receiver),
                                octstr_get_cstr(msg->sms.service),
                                octstr_get_cstr(msg->sms.dlr_url),
-                               msg->sms.dlr_mask);
+                               msg->sms.dlr_mask,
+                    octstr_get_cstr(msg->sms.boxc_id));
                                
                    O_DESTROY(dlrmsgid);
                }
diff -ru gateway/gw/smsc/smsc_cgw.c gateway-smpp/gw/smsc/smsc_cgw.c
--- gateway/gw/smsc/smsc_cgw.c  2002-09-04 19:06:14.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_cgw.c     2002-09-06 15:24:14.000000000 +0200
@@ -1127,7 +1127,8 @@
                     octstr_get_cstr(msg->sms.receiver),
                     octstr_get_cstr(msg->sms.service),
                     octstr_get_cstr(msg->sms.dlr_url),
-                    msg->sms.dlr_mask);
+                    msg->sms.dlr_mask,
+                    octstr_get_cstr(msg->sms.boxc_id));
 
             octstr_destroy(ts);
             privdata->dlr[trn] = 1;
diff -ru gateway/gw/smsc/smsc_cimd2.c gateway-smpp/gw/smsc/smsc_cimd2.c
--- gateway/gw/smsc/smsc_cimd2.c        2002-09-04 19:06:14.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_cimd2.c   2002-09-06 15:24:37.000000000 +0200
@@ -1831,7 +1831,8 @@
                 octstr_get_cstr(msg->sms.receiver),
                 octstr_get_cstr(msg->sms.service),
                 octstr_get_cstr(msg->sms.dlr_url),
-                msg->sms.dlr_mask);
+                msg->sms.dlr_mask,
+                octstr_get_cstr(msg->sms.boxc_id));
             octstr_destroy(ts);
             ts = NULL;         
        }
diff -ru gateway/gw/smsc/smsc_emi2.c gateway-smpp/gw/smsc/smsc_emi2.c
--- gateway/gw/smsc/smsc_emi2.c 2002-09-04 19:06:14.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_emi2.c    2002-09-06 15:25:20.000000000 +0200
@@ -883,7 +883,8 @@
                    octstr_get_cstr(emimsg->fields[E50_ADC]),
                    octstr_get_cstr(msg->sms.service),
                    octstr_get_cstr(msg->sms.dlr_url),
-                   msg->sms.dlr_mask);
+                   msg->sms.dlr_mask,
+                   octstr_get_cstr(msg->sms.boxc_id));
            
            octstr_destroy(ts);
            PRIVDATA(conn)->slots[nexttrn].dlr = 1;
@@ -1020,7 +1021,8 @@
                                            octstr_get_cstr(adc),
                                            octstr_get_cstr(m->sms.service),
                                            octstr_get_cstr(m->sms.dlr_url),
-                                           m->sms.dlr_mask);
+                                           m->sms.dlr_mask,
+                                           octstr_get_cstr(m->sms.boxc_id));
                                }
                                octstr_destroy(ts);
                                octstr_destroy(adc);
diff -ru gateway/gw/smsc/smsc_fake.c gateway-smpp/gw/smsc/smsc_fake.c
--- gateway/gw/smsc/smsc_fake.c 2002-08-08 19:44:38.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_fake.c    2002-09-06 18:05:01.000000000 +0200
@@ -141,6 +141,13 @@
         if (octstr_url_decode(msg->sms.msgdata) == -1 ||
             octstr_url_decode(msg->sms.udhdata) == -1)
             warning(0, "smsc_fake: urlcoded data from client looks malformed");
+    } 
+    else if (!octstr_compare(type, octstr_imm("route"))) {
+        p2 = octstr_search_char(line, ' ', p + 1);
+        if (p2 == -1)
+            goto error;
+        msg->sms.boxc_id = octstr_copy(line, p + 1, p2 - p - 1);
+        msg->sms.msgdata = octstr_copy(line, p2 + 1, LONG_MAX);
     } else
         goto error;
     octstr_destroy(line);
diff -ru gateway/gw/smsc/smsc_smpp.c gateway-smpp/gw/smsc/smsc_smpp.c
--- gateway/gw/smsc/smsc_smpp.c 2002-09-06 21:22:45.000000000 +0200
+++ gateway-smpp/gw/smsc/smsc_smpp.c    2002-09-06 15:25:48.000000000 +0200
@@ -812,7 +812,8 @@
                             octstr_get_cstr(msg->sms.receiver), 
                             octstr_get_cstr(msg->sms.service), 
                             octstr_get_cstr(msg->sms.dlr_url), 
-                            msg->sms.dlr_mask); 
+                            msg->sms.dlr_mask, 
+                            octstr_get_cstr(msg->sms.boxc_id)); 
   
                 /* gen DLR_SMSC_SUCCESS */ 
                 if (msg->sms.dlr_mask & DLR_SMSC_SUCCESS) { 
diff -ru gateway/gwlib/cfg.def gateway-smpp/gwlib/cfg.def
--- gateway/gwlib/cfg.def       2002-09-06 13:57:38.000000000 +0200
+++ gateway-smpp/gwlib/cfg.def  2002-09-06 20:44:50.000000000 +0200
@@ -1,4 +1,4 @@
-/*
+       /*
  * cfg.def - definition of configuration groups and variables
  *
  * Lars Wirzenius
@@ -128,6 +128,7 @@
 )
 
 SINGLE_GROUP(smsbox,
+    OCTSTR(smsbox-id)
     OCTSTR(bearerbox-host)
     OCTSTR(sendsms-port)
     OCTSTR(sendsms-port-ssl)
@@ -154,6 +155,31 @@
     OCTSTR(http-queue-delay)
 )
 
+MULTI_GROUP(smsbox-route,
+    OCTSTR(smsbox-id)
+    OCTSTR(smsc-ids)
+    OCTSTR(shortcuts)
+)
+
+
+SINGLE_GROUP(smppbox,
+    OCTSTR(system-id)
+    OCTSTR(bearerbox-host)
+    OCTSTR(smppbox-port)
+    OCTSTR(redelivery-time)
+    OCTSTR(max-delivery-attempts)
+    OCTSTR(max-report-timeouts)
+    OCTSTR(status-cleanup-time)
+    OCTSTR(time-to-keep-status)
+    OCTSTR(max-status-objects)
+    OCTSTR(white-list)
+    OCTSTR(black-list)
+    OCTSTR(log-file)
+    OCTSTR(log-level)
+    OCTSTR(access-log)
+    OCTSTR(default-smsc)
+)
+
 
 MULTI_GROUP(smsc,
     OCTSTR(smsc)
@@ -289,6 +315,25 @@
 )
 
 
+MULTI_GROUP(esme-user,
+    OCTSTR(username)
+    OCTSTR(password)
+    OCTSTR(mode)
+    OCTSTR(shortcuts)
+    OCTSTR(max-instances)
+    OCTSTR(default-smsc)
+    OCTSTR(force-source)
+)
+
+
+MULTI_GROUP(esme-route,
+    OCTSTR(username)
+    OCTSTR(allowed-prefix)
+    OCTSTR(smsc-id)
+    OCTSTR(force-source)
+)
+
+
 MULTI_GROUP(ota-setting,
     OCTSTR(ota-id)
     OCTSTR(location)
diff -ru gateway/test/fakesmsc.c gateway-smpp/test/fakesmsc.c
--- gateway/test/fakesmsc.c     2001-10-08 21:43:04.000000000 +0200
+++ gateway-smpp/test/fakesmsc.c        2002-09-06 18:03:17.000000000 +0200
@@ -26,13 +26,14 @@
 * 'max' is the total number sent (-1, default, means unlimited),\n\
 * <msg> is message to send, if several are given, they are sent randomly.\n\
 \n\
-msg format: \"sender receiver type(text/data/udh) [udhdata] msgdata\"\n\
+msg format: \"sender receiver type(text/data/udh/route) [udhdata|route] msgdata\"\n\
 \n\
 Type \"text\" means plaintext msgdata, \"data\" urlcoded, \"udh\" urlcoded udh+msg\n\
-\n\
+and \"route\" means smsbox-id routed plaintext msgdata\n\
 Examples: \n\
 \n\
 fakesmsc -m 1 \"123 345 udh %04udh%3f message+data+here\"\n\
+fakesmsc -m 1 \"123 345 route smsbox1 message+data+here\"\n\
 fakesmsc -i 0.01 -m 1000 \"123 345 text nop\" \"1 2 text another message here\"\n\
 \n\
 Server replies are shown in the same message format.\n";

Reply via email to