Hi all,

at the moment we can define an explicit list of receiver numbers that we want to be re-routed to a connected smsc-id B when receiving an MO on a smsc-id A, but we can't define any number ranges or other patterns of the receiver number.

Adding now the support for 'reroute-receiver-regex' which allows to define regular expressions instead of explicit receiver numbers only.

The patchset is pretty straight forward. Please find it attached and feel free to review. I'll commit it to svn trunk in the coming days if there are no objections.

The diffstat is:
 doc/userguide/userguide.xml |   15 ++++++
 gw/bb_smscconn.c            |   64 +++++++++++++++++++----------
gw/smscconn.c | 96 +++++++++++++++++++++++++++++++++++---------
 gw/smscconn_p.h             |    8 +++
 gwlib/cfg.def               |    1
 5 files changed, 145 insertions(+), 39 deletions(-)

BTW, I would like to enroll some more changes into the svn trunk soon, which includes mainly the way how "pattern matching" and "message constraint matching" is performed. We have some sweet constructs for this here that we want to get public.

So this would be a good time to have another round of stable release declared and then go on with the changes/commits to result in a new devel release.

--
Best Regards,
Stipe Tolj

-------------------------------------------------------------------
Düsseldorf, NRW, Germany

Kannel Foundation                 tolj.org system architecture
http://www.kannel.org/            http://www.tolj.org/

st...@kannel.org                  s...@tolj.org
-------------------------------------------------------------------
Index: doc/userguide/userguide.xml
===================================================================
--- doc/userguide/userguide.xml (revision 5299)
+++ doc/userguide/userguide.xml (working copy)
@@ -2969,6 +2969,21 @@
                        to smsc-id B would look like: "A,111,222; B,333,444".
      </entry></row>
 
+    <row><entry><literal>reroute-receiver-regex</literal></entry>
+      <entry><literal>string</literal></entry>
+      <entry valign="bottom">
+            Similar to 'reroute-receiver'. Defines the explicit smsc-id routes 
+            for specific receiver number regex patterns of messages that are 
coming from 
+            this smsc connection.
+            Format is that first comes the smsc-id to route the message to, 
then 
+            all receiver numbers as regular expressions that should be routed, 
+            separated with comma (','). 
+            For example, route receivers that start with 1 and 2 to smsc-id A 
and 
+            those that start with 3 and 4 to smsc-id B would look like: 
+            "A,^1.*,^2.*; B,^3.*,^4.*". (Please ensure the reserved characters 
';' and ','
+            are not used in the regular expression to avoid parsing errors).
+     </entry></row>
+
     <row><entry><literal>reroute-dlr</literal></entry>
       <entry><literal>boolean</literal></entry>
       <entry valign="bottom">
Index: gw/bb_smscconn.c
===================================================================
--- gw/bb_smscconn.c    (revision 5299)
+++ gw/bb_smscconn.c    (working copy)
@@ -754,26 +754,27 @@
        SMSCConn *conn = a;
        Octstr *os;
 
-       os = cfg_get_group_checksum((CfgGroup*)b,
-                   OCTSTR(denied-smsc-id),
-                   OCTSTR(allowed-smsc-id),
-                   OCTSTR(preferred-smsc-id),
-                   OCTSTR(allowed-prefix),
-                   OCTSTR(denied-prefix),
-                   OCTSTR(preferred-prefix),
-                   OCTSTR(unified-prefix),
-                   OCTSTR(reroute),
-                   OCTSTR(reroute-smsc-id),
-                   OCTSTR(reroute-receiver),
-                   OCTSTR(reroute-dlr),
-                   OCTSTR(allowed-smsc-id-regex),
-                   OCTSTR(denied-smsc-id-regex),
-                   OCTSTR(preferred-smsc-id-regex),
-                   OCTSTR(allowed-prefix-regex),
-                   OCTSTR(denied-prefix-regex),
-                   OCTSTR(preferred-prefix-regex),
-                   NULL
-       );
+    os = cfg_get_group_checksum((CfgGroup*)b,
+            OCTSTR(denied-smsc-id),
+            OCTSTR(allowed-smsc-id),
+            OCTSTR(preferred-smsc-id),
+            OCTSTR(allowed-prefix),
+            OCTSTR(denied-prefix),
+            OCTSTR(preferred-prefix),
+            OCTSTR(unified-prefix),
+            OCTSTR(reroute),
+            OCTSTR(reroute-smsc-id),
+            OCTSTR(reroute-receiver),
+            OCTSTR(reroute-receiver-regex),
+            OCTSTR(reroute-dlr),
+            OCTSTR(allowed-smsc-id-regex),
+            OCTSTR(denied-smsc-id-regex),
+            OCTSTR(preferred-smsc-id-regex),
+            OCTSTR(allowed-prefix-regex),
+            OCTSTR(denied-prefix-regex),
+            OCTSTR(preferred-prefix-regex),
+            NULL
+    );
 
        ret = (octstr_compare(conn->chksum_conn, os) == 0);
        octstr_destroy(os);
@@ -1961,12 +1962,33 @@
         msg->sms.sms_type = mt_push;
         store_save(msg);
         /* route by receiver number */
-        /* XXX implement wildcard matching too! */
         octstr_destroy(msg->sms.smsc_id);
         msg->sms.smsc_id = octstr_duplicate(smsc);
         return smsc2_rout(msg, 0);
     }
 
+    if (conn->reroute_by_receiver_regex && msg->sms.receiver) {
+        int i, l;
+        pattern_route *r;
+
+        l = gwlist_len(conn->reroute_by_receiver_regex);
+        for (i = 0; i < l; i++) {
+            r = gwlist_get(conn->reroute_by_receiver_regex, i);
+            /* match against regex pattern */
+            if (r != NULL && r->re != NULL &&
+                    gw_regex_match_pre(r->re, msg->sms.receiver) == 1) {
+                /* matched, change message direction */
+                store_save_ack(msg, ack_success);
+                msg->sms.sms_type = mt_push;
+                store_save(msg);
+                /* route by receiver number */
+                octstr_destroy(msg->sms.smsc_id);
+                msg->sms.smsc_id = octstr_duplicate(r->id);
+                return smsc2_rout(msg, 0);
+            }
+        }
+    }
+
     return -1; 
 }
 
Index: gw/smscconn.c
===================================================================
--- gw/smscconn.c       (revision 5299)
+++ gw/smscconn.c       (working copy)
@@ -143,6 +143,54 @@
         octstr_destroy(rule);
         gwlist_destroy(routes, octstr_destroy_item);
     }
+
+    if ((rule = cfg_get(grp, octstr_imm("reroute-receiver-regex"))) != NULL) {
+        List *routes;
+
+        /* create list with regex patterns and smsc-id */
+        conn->reroute_by_receiver_regex = gwlist_create();
+
+        routes = octstr_split(rule, octstr_imm(";"));
+        for (i = 0; i < gwlist_len(routes); i++) {
+            Octstr *item = gwlist_get(routes, i);
+            Octstr *smsc, *receiver;
+            List *receivers;
+            regex_t *re;
+            pattern_route *r;
+
+            /* first word is the smsc-id, all other are receiver regex */
+            receivers = octstr_split(item, octstr_imm(","));
+            smsc = gwlist_extract_first(receivers);
+            if (smsc)
+                octstr_strip_blanks(smsc);
+
+            while ((receiver = gwlist_extract_first(receivers))) {
+                octstr_strip_blanks(receiver);
+
+                if ((re = gw_regex_comp(receiver, REG_EXTENDED)) == NULL) {
+                    grp_dump(grp);
+                    error(0, "Could not compile regex pattern '%s', 
skipping.", octstr_get_cstr(receiver));
+                    octstr_destroy(receiver);
+                    continue;
+                }
+
+                r = gw_malloc(sizeof(pattern_route));
+                r->id = octstr_duplicate(smsc);
+                r->re = re;
+
+                debug("smscconn",0,"Adding internal routing for smsc id <%s>: "
+                          "receiver-regex <%s> to smsc id <%s>",
+                          octstr_get_cstr(conn->id), octstr_get_cstr(receiver),
+                          octstr_get_cstr(smsc));
+                gwlist_append(conn->reroute_by_receiver_regex, r);
+                octstr_destroy(receiver);
+            }
+            octstr_destroy(smsc);
+            gwlist_destroy(receivers, octstr_destroy_item);
+        }
+        octstr_destroy(rule);
+        gwlist_destroy(routes, octstr_destroy_item);
+    }
 }
 
 
@@ -192,24 +240,25 @@
     /* checksum of the connection related part, without routing
      * and without instance multiplier */
     conn->chksum_conn = cfg_get_group_checksum(grp,
-                   OCTSTR(denied-smsc-id),
-                   OCTSTR(allowed-smsc-id),
-                   OCTSTR(preferred-smsc-id),
-                   OCTSTR(allowed-prefix),
-                   OCTSTR(denied-prefix),
-                   OCTSTR(preferred-prefix),
-                   OCTSTR(unified-prefix),
-                   OCTSTR(reroute),
-                   OCTSTR(reroute-smsc-id),
-                   OCTSTR(reroute-receiver),
-                   OCTSTR(reroute-dlr),
-                   OCTSTR(allowed-smsc-id-regex),
-                   OCTSTR(denied-smsc-id-regex),
-                   OCTSTR(preferred-smsc-id-regex),
-                   OCTSTR(allowed-prefix-regex),
-                   OCTSTR(denied-prefix-regex),
-                   OCTSTR(preferred-prefix-regex),
-                   NULL
+            OCTSTR(denied-smsc-id),
+            OCTSTR(allowed-smsc-id),
+            OCTSTR(preferred-smsc-id),
+            OCTSTR(allowed-prefix),
+            OCTSTR(denied-prefix),
+            OCTSTR(preferred-prefix),
+            OCTSTR(unified-prefix),
+            OCTSTR(reroute),
+            OCTSTR(reroute-smsc-id),
+            OCTSTR(reroute-receiver),
+            OCTSTR(reroute-receiver-regex),
+            OCTSTR(reroute-dlr),
+            OCTSTR(allowed-smsc-id-regex),
+            OCTSTR(denied-smsc-id-regex),
+            OCTSTR(preferred-smsc-id-regex),
+            OCTSTR(allowed-prefix-regex),
+            OCTSTR(denied-prefix-regex),
+            OCTSTR(preferred-prefix-regex),
+            NULL
     );
 
     conn->received = counter_create();
@@ -403,6 +452,15 @@
 }
 
 
+static void pattern_route_destroy(void *arg)
+{
+    pattern_route *r = arg;
+    gw_regex_destroy(r->re);
+    octstr_destroy(r->id);
+    gw_free(r);
+}
+
+
 int smscconn_destroy(SMSCConn *conn)
 {
     if (conn == NULL)
@@ -445,6 +503,7 @@
 
     octstr_destroy(conn->reroute_to_smsc);
     dict_destroy(conn->reroute_by_receiver);
+    gwlist_destroy(conn->reroute_by_receiver_regex, pattern_route_destroy);
 
     mutex_unlock(conn->flow_mutex);
     mutex_destroy(conn->flow_mutex);
@@ -744,6 +803,7 @@
 
     octstr_destroy(conn->reroute_to_smsc);
     dict_destroy(conn->reroute_by_receiver);
+    gwlist_destroy(conn->reroute_by_receiver_regex, pattern_route_destroy);
     init_reroute(conn, grp);
 
     /*
Index: gw/smscconn_p.h
===================================================================
--- gw/smscconn_p.h     (revision 5299)
+++ gw/smscconn_p.h     (working copy)
@@ -205,6 +205,7 @@
     /* Stores rerouting information for this specific smsc-id */
     int reroute;                /* simply turn MO into MT and process 
internally */
     Dict *reroute_by_receiver;  /* reroute receiver numbers to specific 
smsc-ids */
+    List *reroute_by_receiver_regex; /* same as above, but with regex patterns 
*/
     Octstr *reroute_to_smsc;    /* define a smsc-id to reroute to */
     int reroute_dlr;            /* should DLR's are rereouted too? */
     int dead_start;             /* don't connect this SMSC at startup time */
@@ -249,6 +250,13 @@
     void *data;                        /* SMSC specific stuff */
 };
 
+
+typedef struct pattern_route {
+    regex_t *re;
+    Octstr *id;
+} pattern_route;
+
+
 /*
  * Initializers for various SMSC connection implementations,
  * each should take same arguments and return an int,
Index: gwlib/cfg.def
===================================================================
--- gwlib/cfg.def       (revision 5299)
+++ gwlib/cfg.def       (working copy)
@@ -322,6 +322,7 @@
     OCTSTR(reroute)
     OCTSTR(reroute-smsc-id)
     OCTSTR(reroute-receiver)
+    OCTSTR(reroute-receiver-regex)
     OCTSTR(reroute-dlr)
     OCTSTR(log-file)
     OCTSTR(log-level)

Reply via email to