[PATCH] SMS Box routing

"Rene Kluwen" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hereby the patch, for you guys to review.

== Rene

-----Original Message-----
From: Rene Kluwen [mailto:[email protected]] 
Sent: zondag 25 juli 2010 1:04
To: 'Rene Kluwen'; [email protected]
Subject: RE: SMS Box routing

Sorry for the double post. But my email got sent before I was finished
typing.

Two questions:

1. Testers wanted. People that have asked for this feature should stand in
line now... :) Drop me a line!
2. Any chance this patch can be in the Kannel trunk?

== Rene

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf
Of Rene Kluwen
Sent: zondag 25 juli 2010 1:00
To: [email protected]
Subject: SMS Box routing

As per popular request, I made a patch for bearerbox that enable the
following configuration:

# multi-group:
group = smsbox-route-between
smsbox-id1 = localbox1
smsbox-id2 = remotebox1
# shortcode is optional
shortcode = +1234567;+7654321


This is the opposite of "reroute" for smsc's. It routes messages from
smsbox/sqlbox/open smppbox to another box that is connected.

This allows for:

1. client-to-client routing, concerning open smppbox.
2. Call sms services from one of the boxes. Right now you can only call them
via an smsc.
3. Many more interesting things
route-between2.patch (application/octet-stream, 7.2 KB)
Index: gwlib/cfg.def
===================================================================
--- gwlib/cfg.def	(revision 4833)
+++ gwlib/cfg.def	(working copy)
@@ -293,6 +293,13 @@
 )
 
 
+MULTI_GROUP(smsbox-route-between,
+    OCTSTR(smsbox-id1)
+    OCTSTR(smsbox-id2)
+    OCTSTR(shortcode)
+)
+
+
 MULTI_GROUP(smsc,
     OCTSTR(smsc)
     OCTSTR(smsc-id)
Index: gw/bb_boxc.c
===================================================================
--- gw/bb_boxc.c	(revision 4833)
+++ gw/bb_boxc.c	(working copy)
@@ -111,6 +111,8 @@
 static Dict *smsbox_by_smsc;
 static Dict *smsbox_by_receiver;
 static Dict *smsbox_by_smsc_receiver;
+static Dict *smsbox2_by_boxc;
+static Dict *smsbox2_by_boxc_receiver;
 
 static long	smsbox_port;
 static int smsbox_port_ssl;
@@ -273,7 +275,34 @@
     msg_destroy(mack);
 }
 
+static int route_to_smsbox(Msg *msg)
+{
+    Octstr *id, *os;
+    List *boxlist;
+    Boxc *conn;
 
+    os = octstr_format("%s:%s",
+         octstr_get_cstr(msg->sms.receiver),
+         octstr_get_cstr(msg->sms.boxc_id));
+    id = dict_get(smsbox2_by_boxc_receiver, os);
+    octstr_destroy(os);
+
+    if (!id) {
+	id = dict_get(smsbox2_by_boxc, msg->sms.boxc_id);
+    }
+
+    if (id) {
+	boxlist = dict_get(smsbox_by_id, id);
+	if (NULL != boxlist && gwlist_len(boxlist) > 0) {
+	    conn = gwlist_get(boxlist, 0);
+	    gwlist_produce(conn->incoming, msg);
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
 static void boxc_receiver(void *arg)
 {
     Boxc *conn = arg;
@@ -306,14 +335,16 @@
         if (msg_type(msg) == sms && conn->is_wap == 0) {
             debug("bb.boxc", 0, "boxc_receiver: sms received");
 
-            /* deliver message to queue */
-            deliver_sms_to_queue(msg, conn);
+	    if (!route_to_smsbox(msg)) {
+            	/* deliver message to queue */
+            	deliver_sms_to_queue(msg, conn);
 
-            if (conn->routable == 0) {
-                conn->routable = 1;
-                /* wakeup the dequeue thread */
-                gwthread_wakeup(sms_dequeue_thread);
-            }
+                if (conn->routable == 0) {
+                    conn->routable = 1;
+                    /* wakeup the dequeue thread */
+                    gwthread_wakeup(sms_dequeue_thread);
+                }
+	    }
         } else if (msg_type(msg) == wdp_datagram && conn->is_wap) {
             debug("bb.boxc", 0, "boxc_receiver: got wdp from wapbox");
 
@@ -1044,6 +1075,10 @@
     smsbox_by_receiver = NULL;
     dict_destroy(smsbox_by_smsc_receiver);
     smsbox_by_smsc_receiver = NULL;
+    dict_destroy(smsbox2_by_boxc);
+    smsbox2_by_boxc = NULL;
+    dict_destroy(smsbox2_by_boxc_receiver);
+    smsbox2_by_boxc_receiver = NULL;
 
     gwlist_remove_producer(flow_threads);
 }
@@ -1196,6 +1231,96 @@
 }
 
 
+/*
+ * Populates the corresponding smsbox_by_foobar dictionary hash tables
+ */
+static void init_smsbox_between_routes(Cfg *cfg)
+{
+    CfgGroup *grp;
+    List *list, *items;
+    Octstr *boxc_id1, *boxc_id2, *shortcuts, *subitem;
+    int i, j;
+
+    boxc_id1 = boxc_id2 = shortcuts = NULL;
+
+    list = cfg_get_multi_group(cfg, octstr_imm("smsbox-route-between"));
+
+    /* loop multi-group "smsbox-route" */
+    while (list && (grp = gwlist_extract_first(list)) != NULL) {
+
+        if ((boxc_id1 = cfg_get(grp, octstr_imm("smsbox-id1"))) == NULL) {
+            grp_dump(grp);
+            panic(0,"'smsbox-route-between' group without valid 'smsbox-id1' directive!");
+        }
+
+        if ((boxc_id2 = cfg_get(grp, octstr_imm("smsbox-id2"))) == NULL) {
+            grp_dump(grp);
+            panic(0,"'smsbox-route-between' group without valid 'smsbox-id2' directive!");
+        }
+
+        shortcuts = cfg_get(grp, octstr_imm("shortcode"));
+
+        /* consider now the 2 possibilities: */
+        if (!shortcuts) {
+            /* smsbox-id2 only, so all MO traffic */
+                debug("bb.boxc",0,"Adding smsbox between routing to id <%s> for box <%s>",
+                      octstr_get_cstr(boxc_id1), octstr_get_cstr(boxc_id2));
+
+                if (!dict_put_once(smsbox2_by_boxc, boxc_id1, octstr_duplicate(boxc_id2)))
+                    panic(0, "Routing for smsbox-id <%s> already exists!",
+                          octstr_get_cstr(boxc_id2));
+
+                debug("bb.boxc",0,"Adding smsbox between routing to id <%s> for box <%s>",
+                      octstr_get_cstr(boxc_id2), octstr_get_cstr(boxc_id1));
+                if (!dict_put_once(smsbox2_by_boxc, boxc_id2, octstr_duplicate(boxc_id1)))
+                    panic(0, "Routing for smsbox-id <%s> already exists!",
+                          octstr_get_cstr(boxc_id1));
+        }
+        else {
+            /* both, so only specified MOs from specified smscs */
+            items = octstr_split(shortcuts, octstr_imm(";"));
+            for (i = 0; i < gwlist_len(items); i++) {
+                Octstr *item = gwlist_get(items, i);
+                octstr_strip_blanks(item);
+
+                debug("bb.boxc",0,"Adding smsbox routing between to id <%s> "
+                      "for receiver no <%s> and box <%s>",
+                  octstr_get_cstr(boxc_id1), octstr_get_cstr(item),
+                  octstr_get_cstr(boxc_id2));
+
+		subitem = octstr_duplicate(boxc_id2);
+                /* construct the dict key '<shortcode>:<boxc-id>' */
+                octstr_insert(subitem, item, 0);
+                octstr_insert_char(subitem, octstr_len(item), ':');
+                if (!dict_put_once(smsbox2_by_boxc_receiver, subitem, octstr_duplicate(boxc_id1)))
+                    panic(0, "Routing for receiver:box <%s> already exists!",
+                          octstr_get_cstr(subitem));
+		octstr_destroy(subitem);
+
+                debug("bb.boxc",0,"Adding smsbox routing between to id <%s> "
+                      "for receiver no <%s> and box <%s>",
+                  octstr_get_cstr(boxc_id2), octstr_get_cstr(item),
+                  octstr_get_cstr(boxc_id1));
+                /* construct the dict key '<shortcode>:<boxc-id>' */
+		subitem = octstr_duplicate(boxc_id1);
+                octstr_insert(subitem, item, 0);
+                octstr_insert_char(subitem, octstr_len(item), ':');
+                if (!dict_put_once(smsbox2_by_boxc_receiver, subitem, octstr_duplicate(boxc_id2)))
+                    panic(0, "Routing for receiver:box <%s> already exists!",
+                          octstr_get_cstr(subitem));
+		octstr_destroy(subitem);
+            }
+            gwlist_destroy(items, octstr_destroy_item);
+            octstr_destroy(shortcuts);
+        }
+        octstr_destroy(boxc_id1);
+        octstr_destroy(boxc_id2);
+    }
+
+    gwlist_destroy(list, NULL);
+}
+
+
 /*-------------------------------------------------------------
  * public functions
  *
@@ -1238,8 +1363,12 @@
     smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
     smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
 
+    smsbox2_by_boxc = dict_create(10, (void(*)(void *)) octstr_destroy);
+    smsbox2_by_boxc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
+
     /* load the defined smsbox routing rules */
     init_smsbox_routes(cfg);
+    init_smsbox_between_routes(cfg);
 
     gwlist_add_producer(outgoing_sms);
     gwlist_add_producer(smsbox_list);
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.