Hi list,

please find attached a patch against current CVS HEAD to add support for
keyword/alias based smsbox instance MO routing.

This patch was provided by a user. Unfortunately I can't recall which one it
was, so please feel free to "recall me" on this, so the appropriate people get
their credits in the ChangeLog. :)

What it allows is using this for bearerbox's MO routing towards a connected
smsbox instance:

  group = smsbox-route
  ...
  keyword = <keyword>
  aliases = "<alias1>;<alias2>;...;<aliasN>"
  smsbox-id = foobar

which will ensure (in combination if used with the other 2 directives, 'smsc-id'
and 'shortcode') that any MO with the associated keywords are routed to the
'smsbox-id' identified smsbox instance.

Please review and vote for commit to CVS.

Stipe

-- 
-------------------------------------------------------------------
Kölner Landstrasse 419
40589 Düsseldorf, NRW, Germany

tolj.org system architecture      Kannel Software Foundation (KSF)
http://www.tolj.org/              http://www.kannel.org/

mailto:st_{at}_tolj.org           mailto:stolj_{at}_kannel.org
-------------------------------------------------------------------
### Eclipse Workspace Patch 1.0
#P gateway-cvs-head
Index: doc/userguide/userguide.xml
===================================================================
RCS file: /home/cvs/gateway/doc/userguide/userguide.xml,v
retrieving revision 1.342
diff -u -r1.342 userguide.xml
--- doc/userguide/userguide.xml 7 Nov 2008 08:46:08 -0000       1.342
+++ doc/userguide/userguide.xml 18 Nov 2008 21:47:16 -0000
@@ -5596,6 +5596,32 @@
                  the connections in the smsc-id are matched against the 
shortcode list.
      </entry></row>
 
+        <row><entry><literal>keyword</literal></entry>
+     <entry>word</entry>
+     <entry valign="bottom">
+        If set, specifies which keyword for inbound messages should
+                 be routed to this smsbox instance. Value contains a single 
keyword.
+                 This rule may be used to pull keyword specific message 
streams 
+                 to an smsbox instance. If used in combination
+                 with config directive smsc-id and/or shortcode, then only 
messages 
+                 originating from the connections in the smsc-id and/or with 
shortcode
+                 destination address are matched against this keyword. If you 
need to
+                 apply the same rule for several keywords, then the 
+                 <literal>aliases</literal> directive can be used.
+     </entry></row>
+
+        <row><entry><literal>aliases</literal></entry>
+     <entry>word-list</entry>
+     <entry valign="bottom">
+        If set, specifies which keyword for inbound messages should
+                 be routed to this smsbox instance. List contains keywords 
seperated.
+                 by semicolon (";"). This rule may be used to pull keyword 
+                 specific message streams to an smsbox instance. If used in 
combination
+                 with config directive smsc-id and/or shortcode, then only 
messages 
+                 originating from the connections in the smsc-id and/or with 
shortcode
+                 destination address are matched against these keyword aliases.
+     </entry></row>
+
   </tbody>
   </tgroup>
  </table>
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.134
diff -u -r1.134 cfg.def
--- gwlib/cfg.def       26 Jul 2008 09:21:17 -0000      1.134
+++ gwlib/cfg.def       18 Nov 2008 21:47:19 -0000
@@ -287,6 +287,8 @@
     OCTSTR(smsbox-id)
     OCTSTR(smsc-id)
     OCTSTR(shortcode)
+    OCTSTR(keyword)
+    OCTSTR(aliases)
 )
 
 
Index: gw/bb_boxc.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_boxc.c,v
retrieving revision 1.91
diff -u -r1.91 bb_boxc.c
--- gw/bb_boxc.c        9 Jan 2008 20:06:58 -0000       1.91
+++ gw/bb_boxc.c        18 Nov 2008 21:47:18 -0000
@@ -64,6 +64,7 @@
  * Alexander Malysh (various fixes)
  */
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -111,6 +112,8 @@
 static Dict *smsbox_by_smsc;
 static Dict *smsbox_by_receiver;
 static Dict *smsbox_by_smsc_receiver;
+static Dict *smsbox_by_keyword_smsc_receiver;
+static Dict *smsbox_by_keyword_smsc;
 
 static long    smsbox_port;
 static int smsbox_port_ssl;
@@ -983,6 +986,10 @@
     smsbox_by_receiver = NULL;
     dict_destroy(smsbox_by_smsc_receiver);
     smsbox_by_smsc_receiver = NULL;
+    dict_destroy(smsbox_by_keyword_smsc_receiver);
+    smsbox_by_keyword_smsc_receiver = NULL;
+    dict_destroy(smsbox_by_keyword_smsc);
+    smsbox_by_keyword_smsc = NULL;
     
     gwlist_remove_producer(flow_threads);
 }
@@ -997,7 +1004,7 @@
     port = (int) *((long*)arg);
     
     fd = make_server_socket(port, NULL);
-       /* XXX add interface_name if required */
+    /* XXX add interface_name if required */
 
     if (fd < 0) {
            panic(0, "Could not open wapbox port %d", port);
@@ -1009,16 +1016,13 @@
 
     gwlist_remove_producer(outgoing_wdp);
 
-
-    /* wait for all connections to die and then remove list
-     */
-    
-    while(gwlist_wait_until_nonempty(wapbox_list) == 1)
+    /* wait for all connections to die and then remove list */
+    while (gwlist_wait_until_nonempty(wapbox_list) == 1)
         gwthread_sleep(1.0);
 
     /* wait for wdp_to_wapboxes to exit */
-    while(gwlist_consume(wapbox_list)!=NULL)
-       ;
+    while (gwlist_consume(wapbox_list) != NULL)
+        ;
     
     /* close listen socket */
     close(fd);   
@@ -1037,8 +1041,8 @@
 {
     CfgGroup *grp;
     List *list, *items;
-    Octstr *boxc_id, *smsc_ids, *shortcuts;
-    int i, j;
+    Octstr *boxc_id, *smsc_ids, *shortcuts, *keyword, *aliases;
+    int i, j, k;
 
     boxc_id = smsc_ids = shortcuts = NULL;
 
@@ -1063,9 +1067,15 @@
          */
         smsc_ids = cfg_get(grp, octstr_imm("smsc-id"));
         shortcuts = cfg_get(grp, octstr_imm("shortcode"));
+        keyword = cfg_get(grp, octstr_imm("keyword"));
+        aliases = cfg_get(grp, octstr_imm("aliases"));
+        if (keyword != NULL) {
+            octstr_convert_range(keyword, 0, octstr_len(keyword), tolower);
+            octstr_strip_blanks(keyword);
+        }
 
         /* consider now the 3 possibilities: */
-        if (smsc_ids && !shortcuts) {
+        if (smsc_ids && !shortcuts && !keyword) {
             /* smsc-id only, so all MO traffic */
             items = octstr_split(smsc_ids, octstr_imm(";"));
             for (i = 0; i < gwlist_len(items); i++) {
@@ -1082,7 +1092,7 @@
             gwlist_destroy(items, octstr_destroy_item);
             octstr_destroy(smsc_ids);
         }
-        else if (!smsc_ids && shortcuts) {
+        else if (!smsc_ids && shortcuts && !keyword) {
             /* shortcode only, so these MOs from all smscs */
             items = octstr_split(shortcuts, octstr_imm(";"));
             for (i = 0; i < gwlist_len(items); i++) {
@@ -1099,7 +1109,7 @@
             gwlist_destroy(items, octstr_destroy_item);
             octstr_destroy(shortcuts);
         }
-        else if (smsc_ids && shortcuts) {
+        else if (smsc_ids && shortcuts && !keyword) {
             /* both, so only specified MOs from specified smscs */
             items = octstr_split(shortcuts, octstr_imm(";"));
             for (i = 0; i < gwlist_len(items); i++) {
@@ -1128,6 +1138,126 @@
             gwlist_destroy(items, octstr_destroy_item);
             octstr_destroy(shortcuts);
         }
+        else if (smsc_ids && shortcuts && keyword && !aliases) {
+            /* all, so only specified MOs from specified smscs and with 
specified keyword */
+            items = octstr_split(shortcuts, octstr_imm(";"));
+            for (i = 0; i < gwlist_len(items); i++) {
+                List *subitems;
+                Octstr *item = gwlist_get(items, i);
+                octstr_strip_blanks(item);
+                subitems = octstr_split(smsc_ids, octstr_imm(";")); 
+                for (j = 0; j < gwlist_len(subitems); j++) {
+                    Octstr *subitem = gwlist_get(subitems, j);
+                    octstr_strip_blanks(subitem);
+                    
+                    debug("bb.boxc",0,"Adding smsbox routing to id <%s> "
+                          "for receiver no <%s> and smsc id <%s> and keyword 
<%s>",
+                          octstr_get_cstr(boxc_id), octstr_get_cstr(item),
+                          octstr_get_cstr(subitem), octstr_get_cstr(keyword));
+            
+                    /* construct the dict key 
'<keyword>:<shortcode>:<smsc-id>' */
+                    octstr_insert(subitem, item, 0);
+                    octstr_insert_char(subitem, octstr_len(item), ':');
+                    octstr_insert(subitem, keyword, 0);
+                    octstr_insert_char(subitem, octstr_len(keyword), ':');
+                    if (!dict_put_once(smsbox_by_keyword_smsc_receiver, 
subitem, octstr_duplicate(boxc_id)))
+                        panic(0, "Routing for keyword:receiver:smsc <%s> 
already exists!",
+                              octstr_get_cstr(subitem));
+                }
+                gwlist_destroy(subitems, octstr_destroy_item);
+            }
+            gwlist_destroy(items, octstr_destroy_item);
+            octstr_destroy(shortcuts);                 
+       }
+       else if (smsc_ids && shortcuts && keyword && aliases) {
+           /* lets add keyword to aliases list so it would be easier to parse 
it */
+            octstr_insert(aliases, keyword, 0);
+            octstr_insert_char(aliases, octstr_len(keyword), ';');             
        
+            
+            /* all, so only specified MOs from specified smscs and with 
+             * specified keyword and/or alias */
+            items = octstr_split(shortcuts, octstr_imm(";"));
+            for (i = 0; i < gwlist_len(items); i++) {
+                List *subitems;
+                Octstr *item = gwlist_get(items, i);
+                octstr_strip_blanks(item);
+                subitems = octstr_split(smsc_ids, octstr_imm(";")); 
+                for (j = 0; j < gwlist_len(subitems); j++) {
+                    Octstr *subitem = gwlist_get(subitems, j);
+                    octstr_strip_blanks(subitem);
+                    
+                    List *subsubitems;
+                    subsubitems = octstr_split(aliases, octstr_imm(";")); 
+                    
+                    for (k = 0; k < gwlist_len(subsubitems); k++) {
+                        Octstr *subsubitem = gwlist_get(subsubitems, k);    
+                        octstr_strip_blanks(subsubitem);
+                        octstr_convert_range(subsubitem, 0, 
octstr_len(subsubitem), tolower);
+                                     
+                        debug("bb.boxc",0,"Adding smsbox routing to id <%s> "
+                              "for receiver no <%s> and smsc id <%s> and 
keyword/alias <%s>",
+                              octstr_get_cstr(boxc_id), octstr_get_cstr(item),
+                              octstr_get_cstr(subitem), 
octstr_get_cstr(subsubitem));
+                             
+                        /* construct the dict key 
'<keyword>:<shortcode>:<smsc-id>' */
+                        Octstr *dictitem = octstr_duplicate(subitem);
+                        octstr_insert(dictitem, item, 0);
+                        octstr_insert_char(dictitem, octstr_len(item), ':');
+                        octstr_insert(dictitem, subsubitem, 0);
+                        octstr_insert_char(dictitem, octstr_len(subsubitem), 
':');                    
+                                                                 
+                        debug("bb.boxc",0,"Adding smsbox routing <%s> ",
+                              octstr_get_cstr(dictitem));
+                                     
+                        if (!dict_put_once(smsbox_by_keyword_smsc_receiver, 
dictitem, 
+                                           octstr_duplicate(boxc_id)))
+                            panic(0, "Routing for keyword:receiver:smsc <%s> 
already exists!",
+                                  octstr_get_cstr(dictitem));                  
         
+                    }                                        
+                    gwlist_destroy(subsubitems, octstr_destroy_item);
+                }
+                gwlist_destroy(subitems, octstr_destroy_item);
+            }
+            gwlist_destroy(items, octstr_destroy_item);
+            octstr_destroy(shortcuts);                 
+       }
+       else if (smsc_ids && !shortcuts && keyword && aliases) {
+           /* lets add keyword to aliases list so it would be easier to parse 
it */
+            octstr_insert(aliases, keyword, 0);
+            octstr_insert_char(aliases, octstr_len(keyword), ';');             
        
+            
+            /* both, so only specified MOs from specified smscs */
+            items = octstr_split(aliases, octstr_imm(";"));
+            for (i = 0; i < gwlist_len(items); i++) {
+                List *subitems;
+                Octstr *item = gwlist_get(items, i);
+                octstr_strip_blanks(item);
+                subitems = octstr_split(smsc_ids, octstr_imm(";")); 
+                for (j = 0; j < gwlist_len(subitems); j++) {
+                    Octstr *subitem = gwlist_get(subitems, j);
+                    octstr_strip_blanks(subitem);
+                    
+                    debug("bb.boxc",0,"Adding smsbox routing to id <%s> "
+                          "for smsc-id <%s> and smsc id <%s>",
+                          octstr_get_cstr(boxc_id), octstr_get_cstr(item),
+                          octstr_get_cstr(subitem));
+            
+                    /* construct the dict key '<keyword>:<smsc-id>' */
+                    octstr_insert(subitem, item, 0);
+                    octstr_insert_char(subitem, octstr_len(item), ':');
+
+                    debug("bb.boxc", 0, "Routing for keyword:smsc <%s> already 
exists!",
+                    octstr_get_cstr(subitem));
+                    
+                    if (!dict_put_once(smsbox_by_keyword_smsc, subitem, 
octstr_duplicate(boxc_id)))
+                        panic(0, "Routing for receiver:smsc <%s> already 
exists!",
+                              octstr_get_cstr(subitem));
+                }
+                gwlist_destroy(subitems, octstr_destroy_item);
+            }
+            gwlist_destroy(items, octstr_destroy_item);
+            octstr_destroy(shortcuts);
+       }
         octstr_destroy(boxc_id);
     }
 
@@ -1176,6 +1306,8 @@
     smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
     smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
     smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) 
octstr_destroy);
+    smsbox_by_keyword_smsc_receiver = dict_create(50, (void(*)(void *)) 
octstr_destroy);
+    smsbox_by_keyword_smsc = dict_create(50, (void(*)(void *)) octstr_destroy);
 
     /* load the defined smsbox routing rules */
     init_smsbox_routes(cfg);
@@ -1415,9 +1547,12 @@
 int route_incoming_to_boxc(Msg *msg)
 {
     Boxc *bc = NULL, *best = NULL;
-    Octstr *s, *r, *rs;
+    Octstr *s, *r, *rs, *krs;
     long len, b, i;
     int full_found = 0;
+    List *word_list;
+    int num_words;
+    Octstr *keyword;
 
     s = r = NULL;
     gw_assert(msg_type(msg) == sms);
@@ -1458,6 +1593,38 @@
          * Where the shortcode route has a higher priority then the smsc-id 
rule.
          * Highest priority has the combined <shortcode>:<smsc-id> route.
          */
+        
+        if (msg->sms.msgdata && octstr_len(msg->sms.msgdata)) {
+            word_list = octstr_split_words(msg->sms.msgdata);
+            num_words = gwlist_len(word_list);
+            word_list = octstr_split_words(msg->sms.msgdata);
+            num_words = gwlist_len(word_list);
+        } else {
+            word_list = gwlist_create();
+            num_words = 0;
+        }
+       
+        if (num_words >= 1) {
+            keyword = octstr_duplicate(gwlist_get(word_list, 0));
+            Octstr *kos = octstr_format("%s:%s:%s", 
+                                   octstr_get_cstr(keyword),
+                                   octstr_get_cstr(msg->sms.receiver),
+                                   octstr_get_cstr(msg->sms.smsc_id));         
 
+            krs = (kos ? dict_get(smsbox_by_keyword_smsc_receiver, kos) : 
NULL);
+            octstr_destroy(kos);
+            if (!krs) {
+                Octstr *ks = octstr_format("%s:%s", 
+                                   octstr_get_cstr(keyword),
+                                   octstr_get_cstr(msg->sms.smsc_id));         
                 
+                krs = (ks ? dict_get(smsbox_by_keyword_smsc, ks) : NULL);
+                octstr_destroy(ks);
+            }
+        } else {
+            krs = NULL;
+        }
+                
+        gwlist_destroy(word_list, octstr_destroy_item);
+        
         Octstr *os = octstr_format("%s:%s", 
                                    octstr_get_cstr(msg->sms.receiver),
                                    octstr_get_cstr(msg->sms.smsc_id));
@@ -1465,8 +1632,10 @@
         r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, 
msg->sms.receiver) : NULL);
         rs = (os ? dict_get(smsbox_by_smsc_receiver, os) : NULL);
         octstr_destroy(os); 
-        bc = rs ? dict_get(smsbox_by_id, rs) : 
-            (r ? dict_get(smsbox_by_id, r) : (s ? dict_get(smsbox_by_id, s) : 
NULL));
+        bc = krs ? dict_get(smsbox_by_id, krs) : (
+                rs ? dict_get(smsbox_by_id, rs) :
+                    (r ? dict_get(smsbox_by_id, r) : (s ? 
dict_get(smsbox_by_id, s) : NULL))
+             );
     }
 
     /* check if we found our routing */

Reply via email to