Hi all,
please find attached patch that adds configurable max retries and resend
frequency for the temporarily failed messages to the core (means works
with all SMSC modules). Patch also includes changes to user guide for
how to use it.
Please give me feedback...
Thanks,
Alex
Index: gw/bb_smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_smscconn.c,v
retrieving revision 1.84
diff -a -u -p -r1.84 bb_smscconn.c
--- gw/bb_smscconn.c 26 Oct 2005 19:04:56 -0000 1.84
+++ gw/bb_smscconn.c 26 Oct 2005 20:36:52 -0000
@@ -63,7 +63,10 @@
* routing, writing actual access logs, handling failed messages etc.
*
* Kalle Marjola 2000 for project Kannel
+ * Alexander Malysh <amalysh at kannel.org> 2003, 2004, 2005
*/
+
+#include "gw-config.h"
#include <errno.h>
#include <stdlib.h>
@@ -117,6 +120,10 @@ static regex_t *black_list_regex;
static long router_thread = -1;
+/* message resend */
+static long sms_resend_frequency;
+static long sms_max_resend_retry;
+
/*
* Counter for catenated SMS messages. The counter that can be put into
* the catenated SMS message's UDH headers is actually the lowest 8 bits.
@@ -264,11 +271,32 @@ void bb_smscconn_send_failed(SMSCConn *c
}
switch (reason) {
-
- case SMSCCONN_FAILED_SHUTDOWN:
case SMSCCONN_FAILED_TEMPORARILY:
- gwlist_produce(outgoing_sms, sms);
- break;
+ /*
+ * Check if SMSC link alive and if so increase resend_try and set
resend_time.
+ * If SMSC link is not active don't increase resend_try and don't set
resend_time
+ * because we don't want to delay messages because of connection
broken.
+ */
+ if (conn && smscconn_status(conn) == SMSCCONN_ACTIVE) {
+ /*
+ * Check if sms_max_resend_retry set and this msg has exceeded a
limit also
+ * honor "single shot" with sms_max_resend_retry set to zero.
+ */
+ if (sms_max_resend_retry >= 0 && sms->sms.resend_try >=
sms_max_resend_retry) {
+ warning(0, "Maximum retries for message exceeded, discarding
it!");
+ bb_smscconn_send_failed(NULL, sms, SMSCCONN_FAILED_DISCARDED,
octstr_create("Retries Exceeded"));
+ break;
+ }
+ sms->sms.resend_try = (sms->sms.resend_try > 0 ?
sms->sms.resend_try++ : 1);
+ time(&sms->sms.resend_time);
+ }
+ gwlist_produce(outgoing_sms, sms);
+ break;
+
+ case SMSCCONN_FAILED_SHUTDOWN:
+ gwlist_produce(outgoing_sms, sms);
+ break;
+
default:
/* write NACK to store file */
store_save_ack(sms, ack_failed);
@@ -294,7 +322,9 @@ void bb_smscconn_send_failed(SMSCConn *c
bb_smscconn_receive(conn, dlrmsg);
}
}
- msg_destroy(sms);
+
+ msg_destroy(sms);
+ break;
}
octstr_destroy(reply);
@@ -424,27 +454,40 @@ static void sms_router(void *arg)
ret = 0;
while(bb_status != BB_DEAD) {
-
if (newmsg == startmsg) {
- if (ret != 1) {
- debug("bb.sms", 0, "sms_router: time to sleep");
- gwthread_sleep(600.0); /* hopefully someone wakes us up */
- debug("bb.sms", 0, "sms_router: gwlist_len = %ld",
- gwlist_len(outgoing_sms));
- }
- startmsg = gwlist_consume(outgoing_sms);
- newmsg = NULL;
- msg = startmsg;
- } else {
- newmsg = gwlist_consume(outgoing_sms);
- msg = newmsg;
- }
- /* debug("bb.sms", 0, "sms_router: handling message (%p vs %p)",
- * newmsg, startmsg); */
-
- if (msg == NULL)
+ if (ret != 1) {
+ /*
+ * In order to reduce amount of msgs to send we sleep only the
half of frequency time
+ * but at least 1 second.
+ */
+ double sleep_time = (sms_resend_frequency / 2 > 1 ?
sms_resend_frequency / 2 : sms_resend_frequency);
+ debug("bb.sms", 0, "sms_router: time to sleep %.2f secs.",
sleep_time);
+ gwthread_sleep(sleep_time);
+ debug("bb.sms", 0, "sms_router: gwlist_len = %ld",
gwlist_len(outgoing_sms));
+ }
+ startmsg = msg = gwlist_consume(outgoing_sms);
+ newmsg = NULL;
+ }
+ else {
+ newmsg = msg = gwlist_consume(outgoing_sms);
+ }
+
+ /* shutdown ? */
+ if (msg == NULL)
break;
+ debug("bb.sms", 0, "sms_router: handling message (%p vs %p)",
+ msg, startmsg);
+
+ /* handle delayed msgs */
+ if (msg->sms.resend_try > 0 && difftime(time(NULL),
msg->sms.resend_time) < sms_resend_frequency &&
+ bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
+ debug("bb.sms", 0, "re-queing SMS not-yet-to-be resent");
+ gwlist_produce(outgoing_sms, msg);
+ ret = 0;
+ continue;
+ }
+
ret = smsc2_rout(msg);
if (ret == -1) {
warning(0, "No SMSCes to receive message, discarding it!");
@@ -453,8 +496,6 @@ static void sms_router(void *arg)
} else if (ret == 1) {
newmsg = startmsg = NULL;
}
-
-
}
/* router has died, make sure that rest die, too */
@@ -512,6 +553,20 @@ int smsc2_start(Cfg *cfg)
octstr_destroy(os);
}
+ if (cfg_get_integer(&sms_resend_frequency, grp,
+ octstr_imm("sms-resend-frequency")) == -1 || sms_resend_frequency
<= 0) {
+ sms_resend_frequency = 60;
+ }
+ info(0, "Set SMS resend frequency to %ld seconds.", sms_resend_frequency);
+
+ if (cfg_get_integer(&sms_max_resend_retry, grp,
+ octstr_imm("sms-max-resend-retry")) == -1) {
+ sms_max_resend_retry = -1;
+ info(0, "SMS resend retry set to unlimited.");
+ }
+ else
+ info(0, "SMS resent retry set to %ld.", sms_max_resend_retry);
+
smsc_groups = cfg_get_multi_group(cfg, octstr_imm("smsc"));
/*
while(groups && (grp = gwlist_extract_first(groups)) != NULL) {
@@ -903,7 +958,7 @@ int smsc2_rout(Msg *msg)
if (gwlist_len(smsc_list) == 0) {
warning(0, "No SMSCes to receive message");
gw_rwlock_unlock(&smsc_list_lock);
- return SMSCCONN_FAILED_DISCARDED;
+ return -1;
}
s = gw_rand() % gwlist_len(smsc_list);
Index: gw/msg-decl.h
===================================================================
RCS file: /home/cvs/gateway/gw/msg-decl.h,v
retrieving revision 1.30
diff -a -u -p -r1.30 msg-decl.h
--- gw/msg-decl.h 11 Feb 2005 15:35:48 -0000 1.30
+++ gw/msg-decl.h 26 Oct 2005 20:36:52 -0000
@@ -106,6 +106,8 @@ MSG(sms,
INTEGER(msg_left);
VOID(split_parts);
INTEGER(priority);
+ INTEGER(resend_try);
+ INTEGER(resend_time);
})
MSG(ack,
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.112
diff -a -u -p -r1.112 cfg.def
--- gwlib/cfg.def 21 Sep 2005 02:01:22 -0000 1.112
+++ gwlib/cfg.def 26 Oct 2005 20:36:52 -0000
@@ -118,6 +118,8 @@ SINGLE_GROUP(core,
OCTSTR(dlr-storage)
OCTSTR(maximum-queue-length)
OCTSTR(sms-incoming-queue-limit)
+ OCTSTR(sms-resend-frequency)
+ OCTSTR(sms-max-resend-retry)
)
Index: doc/userguide/userguide.xml
===================================================================
RCS file: /home/cvs/gateway/doc/userguide/userguide.xml,v
retrieving revision 1.304
diff -a -u -p -r1.304 userguide.xml
--- doc/userguide/userguide.xml 19 Sep 2005 22:07:33 -0000 1.304
+++ doc/userguide/userguide.xml 26 Oct 2005 20:36:57 -0000
@@ -54,7 +54,7 @@
</author>
<author>
<firstname>Aarno</firstname>
- <surname>Syvänen</surname>
+ <surname>Syvâ°nen</surname>
<affiliation>
<jobtitle>Chief MMS Developer</jobtitle>
<orgname>Global Networks Inc.</orgname>
@@ -1479,6 +1479,22 @@ admin-password = f00bar
</entry>
</row>
+ <row><entry><literal>sms-resend-frequency</literal></entry>
+ <entry>seconds</entry>
+ <entry valign="bottom">
+ Frequency for the SMS resend thread in which temporarily failed or
queued messages will be resent.
+ Defaults to 60 seconds.
+ </entry>
+ </row>
+
+ <row><entry><literal>sms-max-resend-retry</literal></entry>
+ <entry>number</entry>
+ <entry valign="bottom">
+ Maximum retry attempts for the temporarily failed messages.
+ Defaults to -1, means: unlimited.
+ </entry>
+ </row>
+
</tbody>
</tgroup>
</table>