Hi Stipe.

Wow..this sounds really usefull.. I can already use it, but I think we 
should have it as a separate patch for now, the CVS is relatively stable, 
and this is quite a big internal change. I would be happy to try it on our 
dev servers.

nisan

At 09:58 PM 9/6/02 +0200, Stipe Tolj wrote:
>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 arediff -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