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)