[PATCH] Meta-data support for SMPP resp PDUs

Stipe Tolj <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Organization Kannel Software Foundation (KSF)
Message-ID <[email protected]>
Hi list,

this is a patchset in reference to a request that Paulo Correia made in 
the users@ mailing list, [Msg-Id: <[email protected]>].

The basic idea is: in SMPP (and other protocols too), we may have 
meta-data parts (optional TLVs in SMPP) that we get on the "Sent SMS" 
event, hence in the submit_sm_resp PDU for SMPP. At the moment we don't 
have a construct to pass this meta-data in the corresponding 
intermediate DLR SMSC SUCCESS event that we pass to smsbox.

The attached patchset allows this at least for optional TLVs coming 
inside submit_sm_resp. I don't see a clean way to do this for the bind 
resp PDUs though.

The patchset SHOULD be not intrusive, adding only the feature and not 
changing any standard behavior. Please review and vote for commit.

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
-------------------------------------------------------------------
smpp-resp-pdu-optional-tvls.diff (text/plain, 8.1 KB)
Index: gw/bb_smscconn.c
===================================================================
--- gw/bb_smscconn.c	(revision 5077)
+++ gw/bb_smscconn.c	(working copy)
@@ -268,8 +268,15 @@
 }
 
 
-void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
+void bb_smscconn_sent_real(SMSCConn *conn, Msg *sms, Octstr *reply, ...)
 {
+    va_list args;
+    Octstr *meta_data = NULL;
+
+    va_start(args, reply);
+    meta_data = va_arg(args, Octstr*);
+    va_end(args);
+
     if (sms->sms.split_parts != NULL) {
         handle_split(conn, sms, SMSCCONN_SUCCESS);
         octstr_destroy(reply);
@@ -301,12 +308,13 @@
     if (DLR_IS_SMSC_SUCCESS(sms->sms.dlr_mask)) {
         Msg *dlrmsg;
 
-	if (reply == NULL)
-	    reply = octstr_create("");
+        if (reply == NULL)
+            reply = octstr_create("");
 
-	octstr_insert_data(reply, 0, "ACK/", 4);
-        dlrmsg = create_dlr_from_msg((conn->id?conn->id:conn->name), sms,
-	                reply, DLR_SMSC_SUCCESS);
+        octstr_insert_data(reply, 0, "ACK/", 4);
+        dlrmsg = create_dlr_from_msg((conn->id?conn->id:conn->name),
+                                     sms, reply, DLR_SMSC_SUCCESS, meta_data);
+
         if (dlrmsg != NULL) {
             bb_smscconn_receive(conn, dlrmsg);
         }
@@ -317,8 +325,15 @@
 }
 
 
-void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
+void bb_smscconn_send_failed_real(SMSCConn *conn, Msg *sms, int reason, Octstr *reply, ...)
 {
+    va_list args;
+    Octstr *meta_data = NULL;
+
+    va_start(args, reply);
+    meta_data = va_arg(args, Octstr*);
+    va_end(args);
+
     if (sms->sms.split_parts != NULL) {
         handle_split(conn, sms, reason);
         octstr_destroy(reply);
@@ -340,7 +355,8 @@
            if (sms_resend_retry >= 0 && sms->sms.resend_try >= sms_resend_retry) {
                warning(0, "Maximum retries for message exceeded, discarding it!");
                bb_smscconn_send_failed(NULL, sms, SMSCCONN_FAILED_DISCARDED, 
-                                       octstr_create("Retries Exceeded"));
+                                       octstr_create("Retries Exceeded"),
+                                       octstr_duplicate(meta_data));
                break;
            }
            sms->sms.resend_try = (sms->sms.resend_try > 0 ? sms->sms.resend_try + 1 : 1);
@@ -378,16 +394,15 @@
         }
 
         /* generate relay confirmancy message */
-        if (DLR_IS_SMSC_FAIL(sms->sms.dlr_mask) ||
-	    DLR_IS_FAIL(sms->sms.dlr_mask)) {
+        if (DLR_IS_SMSC_FAIL(sms->sms.dlr_mask) || DLR_IS_FAIL(sms->sms.dlr_mask)) {
             Msg *dlrmsg;
 
-	    if (reply == NULL)
-	        reply = octstr_create("");
+            if (reply == NULL)
+                reply = octstr_create("");
 
-	    octstr_insert_data(reply, 0, "NACK/", 5);
-            dlrmsg = create_dlr_from_msg((conn ? (conn->id?conn->id:conn->name) : NULL), sms,
-	                                 reply, DLR_SMSC_FAIL);
+            octstr_insert_data(reply, 0, "NACK/", 5);
+            dlrmsg = create_dlr_from_msg((conn ? (conn->id?conn->id:conn->name) : NULL),
+                                         sms, reply, DLR_SMSC_FAIL, meta_data);
             if (dlrmsg != NULL) {
                 bb_smscconn_receive(conn, dlrmsg);
             }
Index: gw/bb_smscconn_cb.h
===================================================================
--- gw/bb_smscconn_cb.h	(revision 5077)
+++ gw/bb_smscconn_cb.h	(working copy)
@@ -90,19 +90,23 @@
 /*
  * Called after successful sending of Msg 'sms'. Generate dlr message if
  * DLR_SMSC_SUCCESS mask is set. 'reply' will be passed as msgdata to
- * generated dlr message. This callback takes
- * care of 'sms' and 'reply' and it CAN NOT be used by caller again.
+ * generated dlr message, and 'meta_data' is passed as sms.meta_data.
+ * This callback takes care of 'sms', 'reply' and 'meta_data' (if present)
+ * and it CAN NOT be used by caller again.
  */
-void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply);
+#define bb_smscconn_sent(...) bb_smscconn_sent_real( __VA_ARGS__)
+void bb_smscconn_sent_real(SMSCConn *conn, Msg *sms, Octstr *reply, ...);
 
 
 /*
  * Called after failed sending of 'sms'. Generate dlr message if
  * DLR_SMSC_FAIL or DLR_FAIL mask is set. 'reply' will be passed as
- * msgdata to generated dlr message.Reason is set accordingly.
- * callback handles 'sms' and 'reply' and MAY NOT be used by caller again
+ * msgdata to generated dlr message, and 'meta_data' is passed as sms.meta_data.
+ * Reason is set accordingly. Callback handles 'sms', 'reply' and 'meta_data'
+ * and MAY NOT be used by caller again
  */
-void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply);
+#define bb_smscconn_send_failed(...) bb_smscconn_send_failed_real( __VA_ARGS__)
+void bb_smscconn_send_failed_real(SMSCConn *conn, Msg *sms, int reason, Octstr *reply, ...);
 
 enum {
     SMSCCONN_SUCCESS = 0,
Index: gw/dlr.c
===================================================================
--- gw/dlr.c	(revision 5077)
+++ gw/dlr.c	(working copy)
@@ -492,7 +492,8 @@
 }
 
 
-Msg* create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat)
+Msg *create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply,
+                         long stat, const Octstr *meta_data)
 {
     Msg *dlrmsg;
 
@@ -501,7 +502,7 @@
 
     /* generate DLR */
     debug("dlr.dlr", 0,"SMSC[%s]: creating DLR message",
-                (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"));
+          (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"));
 
     dlrmsg = msg_create(sms);
     gw_assert(dlrmsg != NULL);
@@ -516,11 +517,12 @@
     dlrmsg->sms.msgdata = octstr_duplicate(reply);
     dlrmsg->sms.boxc_id = octstr_duplicate(msg->sms.boxc_id);
     dlrmsg->sms.foreign_id = octstr_duplicate(msg->sms.foreign_id);
+    dlrmsg->sms.meta_data = octstr_duplicate(meta_data);
     time(&dlrmsg->sms.time);
 
     debug("dlr.dlr", 0,"SMSC[%s]: DLR = %s",
-                (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"),
-                (dlrmsg->sms.dlr_url ? octstr_get_cstr(dlrmsg->sms.dlr_url) : ""));
+          (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"),
+          (dlrmsg->sms.dlr_url ? octstr_get_cstr(dlrmsg->sms.dlr_url) : ""));
 
     return dlrmsg;
 }
Index: gw/dlr.h
===================================================================
--- gw/dlr.h	(revision 5077)
+++ gw/dlr.h	(working copy)
@@ -104,7 +104,7 @@
  * Find an entry in the list. If there is one a message is returned and 
  * the entry is removed from the list otherwhise the message returned is NULL 
  */
-Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type, int use_dst);
+Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type, int use_dst);
 
 /* return the number of DLR messages in the current waiting queue */
 long dlr_messages(void);
@@ -118,12 +118,13 @@
 /*
  * Return type of dlr storage
  */
-const char* dlr_type(void);
+const char *dlr_type(void);
 
 /*
  * Helper function, create DLR from given message
  */
-Msg* create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat);
+Msg *create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply,
+                         long stat, const Octstr *meta_data);
 
 /*
  * Yet not used functions.
@@ -132,4 +133,3 @@
 void dlr_load(const char *filename);
 
 #endif /* DLR_H */
-
Index: gw/smsc/smsc_smpp.c
===================================================================
--- gw/smsc/smsc_smpp.c	(revision 5077)
+++ gw/smsc/smsc_smpp.c	(working copy)
@@ -1792,7 +1792,16 @@
                     dlr_add(smpp->conn->id, tmp, msg);
 
                 octstr_destroy(tmp);
-                bb_smscconn_sent(smpp->conn, msg, NULL);
+
+                /* handle possible optional TVLs in the PDU */
+                if (dict_key_count(pdu->u.submit_sm_resp.tlv) > 0) {
+                    tmp = octstr_create("");
+                    meta_data_set_values(tmp, pdu->u.submit_sm_resp.tlv, "smpp", 0);
+                } else {
+                    tmp = NULL;
+                }
+
+                bb_smscconn_sent(smpp->conn, msg, NULL, tmp);
                 --(*pending_submits);
             } /* end if for SMSC ACK */
             else {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.