Hi list,
I'd like to introduce an easy concept where bearerbox can inform
smsbox
connections about the final smsc-id the msg has been assigned to.
Bearerbox simply re-writes the msg->sms.smsc_id value as soon as the
smsc2_rout() routing has occurred and we're drilled down to the
assigned smsc
connection.
That value is used then in a new field for the ack msg type:
mack->ack.smsc_id = octstr_duplicate(msg->sms.smsc_id);
and the ack is send as usual to the boxc connection. The smsbox can
then (as
example usage) put that final routing decision to the HTTP response
body:
answer = octstr_format("0: Accepted for delivery by smsc-id '%s'",
Please apply against CVS HEAD, test and comment.
Thanks,
Stipe
BTW, the core of the patch is pretty minimal, while the patch file
includes some
source code re-formating to comply to our CodingStyle.
--
-------------------------------------------------------------------
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: gw/bb_boxc.c
===================================================================
RCS file: /home/cvs/gateway/gw/bb_boxc.c,v
retrieving revision 1.94
diff -u -r1.94 bb_boxc.c
--- gw/bb_boxc.c 2 Mar 2009 01:35:38 -0000 1.94
+++ gw/bb_boxc.c 20 Mar 2009 02:25:47 -0000
@@ -215,8 +215,9 @@
int rc;
/*
- * save modifies ID and time, so if the smsbox uses it, save
- * it FIRST for the reply message!!!
+ * Make sure we use the same UUID and time for the
+ * ack response message towards smsbox.
+ * A smsbox connection logic may depend on it.
*/
mack = msg_create(ack);
gw_assert(mack != NULL);
@@ -225,31 +226,43 @@
store_save(msg);
+ /* call our message router */
rc = smsc2_rout(msg, 0);
- switch(rc) {
+
+ /* provide the routing information via ack
+ * to the attached smsbox connection */
+ mack->ack.smsc_id = octstr_duplicate(msg->sms.smsc_id);
+
+ switch (rc) {
case SMSCCONN_SUCCESS:
- mack->ack.nack = ack_success;
- break;
+ mack->ack.nack = ack_success;
+ break;
+
case SMSCCONN_QUEUED:
- mack->ack.nack = ack_buffered;
- break;
+ mack->ack.nack = ack_buffered;
+ break;
+
case SMSCCONN_FAILED_DISCARDED: /* no router at all */
case SMSCCONN_FAILED_QFULL: /* queue full */
- warning(0, "Message rejected by bearerbox, %s!",
- (rc == SMSCCONN_FAILED_DISCARDED) ?
"no router" : "queue full");
- /*
- * first create nack for store-file, in order to delete
- * message from store-file.
- */
- store_save_ack(msg, (rc == SMSCCONN_FAILED_QFULL ?
ack_failed_tmp : ack_failed));
- mack->ack.nack = (rc == SMSCCONN_FAILED_QFULL ?
ack_failed_tmp : ack_failed);
-
- /* destroy original message */
- msg_destroy(msg);
- break;
+ warning(0, "Message rejected by bearerbox, %s!",
+ (rc == SMSCCONN_FAILED_DISCARDED) ? "no
router" : "queue full");
+
+ /*
+ * First create nack for store-file, in order to delete
+ * message from store-file.
+ */
+ store_save_ack(msg, (rc == SMSCCONN_FAILED_QFULL ?
ack_failed_tmp : ack_failed));
+ mack->ack.nack = (rc == SMSCCONN_FAILED_QFULL ?
ack_failed_tmp : ack_failed);
+
+ /* destroy original message */
+ msg_destroy(msg);
+ break;
+
+ default:
+ break;
}
- /* put ack into incoming queue of conn */
+ /* put ack into incoming queue of conn (smsbox connection) */
send_msg(conn, mack);
msg_destroy(mack);
}
Index: gw/smsbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsbox.c,v
retrieving revision 1.282
diff -u -r1.282 smsbox.c
--- gw/smsbox.c 14 Jan 2009 11:11:46 -0000 1.282
+++ gw/smsbox.c 20 Mar 2009 02:25:50 -0000
@@ -184,33 +184,45 @@
octstr_destroy(os);
return;
}
- /* XXX this should be fixed so that we really wait for DLR
- * SMSC accept/deny before doing this - but that is far
- * more slower, a bit more complex, and is done later on
+
+ /*
+ * TODO: move from 'semi-waiting' to 'full-waiting' method.
+ *
+ * Actually this waiting mechanism is 'semi-waiting'. All that we
+ * are sure of is that bearerbox was able to assign the message
+ * in the lower smsc module layer to a specific smsc connection,
+ * and queued for delivery. This is no real ACK state from the
+ * SMSC side itself.
+ *
+ * This would imply waiting for the corresponding
submit_sm_resp PDU
+ * i.e. of the SMPP protocol. This coudl be only done
efficiently via
+ * asynchronous callback passing of the messages. -- st.
*/
switch (msg->ack.nack) {
- case ack_success:
- status = HTTP_ACCEPTED;
- answer = octstr_create("0: Accepted for delivery");
- break;
- case ack_buffered:
- status = HTTP_ACCEPTED;
- answer = octstr_create("3: Queued for later delivery");
- break;
- case ack_failed:
- status = HTTP_FORBIDDEN;
- answer = octstr_create("Not routable. Do not try again.");
- break;
- case ack_failed_tmp:
- status = HTTP_SERVICE_UNAVAILABLE;
- answer = octstr_create("Temporal failure, try again later.");
- break;
- default:
- error(0, "Strange reply from bearerbox!");
- status = HTTP_SERVICE_UNAVAILABLE;
- answer = octstr_create("Temporal failure, try again later.");
- break;
+ case ack_success:
+ status = HTTP_ACCEPTED;
+ answer = octstr_format("0: Accepted for delivery by
smsc-id '%s'",
+ octstr_get_cstr(msg->ack.smsc_id));
+ break;
+ case ack_buffered:
+ status = HTTP_ACCEPTED;
+ answer = octstr_format("3: Queued for later delivery by
smsc-id '%s'",
+ octstr_get_cstr(msg->ack.smsc_id));
+ break;
+ case ack_failed:
+ status = HTTP_FORBIDDEN;
+ answer = octstr_create("Not routable. Do not try
again.");
+ break;
+ case ack_failed_tmp:
+ status = HTTP_SERVICE_UNAVAILABLE;
+ answer = octstr_create("Temporal failure, try again
later.");
+ break;
+ default:
+ error(0, "Strange reply from bearerbox!");
+ status = HTTP_SERVICE_UNAVAILABLE;
+ answer = octstr_create("Temporal failure, try again
later.");
+ break;
}
http_send_reply(client, status, sendsms_reply_hdrs, answer);
@@ -244,32 +256,35 @@
else if (msg == NULL) /* just to be sure, may not happens */
break;
- if (msg_type(msg) == admin) {
- if (msg->admin.command == cmd_shutdown) {
- info(0, "Bearerbox told us to die");
- program_status = shutting_down;
- } else if (msg->admin.command == cmd_restart) {
- info(0, "Bearerbox told us to restart");
- restart = 1;
- program_status = shutting_down;
- }
- /*
- * XXXX here should be suspend/resume, add RSN
- */
- msg_destroy(msg);
- } else if (msg_type(msg) == sms) {
- if (total == 0)
- start = time(NULL);
- total++;
- gwlist_produce(smsbox_requests, msg);
- } else if (msg_type(msg) == ack) {
- if (!immediate_sendsms_reply)
- delayed_http_reply(msg);
- msg_destroy(msg);
- } else {
- warning(0, "Received other message than sms/admin, ignoring!");
- msg_destroy(msg);
- }
+ if (msg_type(msg) == admin) {
+ if (msg->admin.command == cmd_shutdown) {
+ info(0, "Bearerbox told us to die");
+ program_status = shutting_down;
+ } else if (msg->admin.command == cmd_restart) {
+ info(0, "Bearerbox told us to restart");
+ restart = 1;
+ program_status = shutting_down;
+ }
+ /*
+ * TODO: here should be suspend/resume, add RSN
+ */
+ msg_destroy(msg);
+ }
+ else if (msg_type(msg) == sms) {
+ if (total == 0)
+ start = time(NULL);
+ total++;
+ gwlist_produce(smsbox_requests, msg);
+ }
+ else if (msg_type(msg) == ack) {
+ if (!immediate_sendsms_reply)
+ delayed_http_reply(msg);
+ msg_destroy(msg);
+ }
+ else {
+ warning(0, "Received other message than sms/admin,
ignoring!");
+ msg_destroy(msg);
+ }
}
secs = difftime(time(NULL), start);
info(0, "Received (and handled?) %d requests in %d seconds "
Index: gw/smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/smscconn.c,v
retrieving revision 1.59
diff -u -r1.59 smscconn.c
--- gw/smscconn.c 12 Jan 2009 16:46:56 -0000 1.59
+++ gw/smscconn.c 20 Mar 2009 02:25:50 -0000
@@ -499,6 +499,7 @@
{
int ret = -1;
List *parts = NULL;
+ const Octstr *cid;
gw_assert(conn != NULL);
mutex_lock(conn->flow_mutex);
@@ -506,6 +507,17 @@
mutex_unlock(conn->flow_mutex);
return -1;
}
+
+ /*
+ * We're done now with routing and have our smsc connection
+ * assigned to be used. In order to get accurate logging of
+ * the smsc-id the messages goes, and for the ACK/NACK msg
+ * towards smsbox we replace the value here.
+ */
+ if (conn && (cid = smscconn_id(conn))) {
+ octstr_destroy(msg->sms.smsc_id);
+ msg->sms.smsc_id = octstr_duplicate(cid);
+ }
/* if this a retry of splitted message, don't unify prefix and
don't try to split */
if (msg->sms.split_parts == NULL) {
Index: gw/msg-decl.h
===================================================================
RCS file: /home/cvs/gateway/gw/msg-decl.h,v
retrieving revision 1.37
diff -u -r1.37 msg-decl.h
--- gw/msg-decl.h 14 Jan 2009 11:11:46 -0000 1.37
+++ gw/msg-decl.h 20 Mar 2009 02:25:47 -0000
@@ -118,6 +118,7 @@
INTEGER(nack);
INTEGER(time);
UUID(id);
+ OCTSTR(smsc_id);
})
MSG(wdp_datagram,