fake smsc DLR patch

"Nikos Balkanas" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.user,gmane.comp.mobile.kannel.devel
Message-ID <002a01c95047$bccc5e60$02b2a8c0@tardis>
Dear list(s)

As you remember from a relevant question I posed a week ago, although, according to the documentation, fake smsc supports DLRs (fake) , it didn't actually work. This proposed patch to the smsc_fake.c driver, fakesmsc.c client and updated xml documentation will enable this feature.

For DLRs to work you need to specify a dlr-url in your fake smsc configuration. If you don't, no harm done, the software will remind you of this and process the sms as regular text.

Alex: The only changes from the last fakesmsc.c I sent you, are the Usage: lines. It is essentially the same client, so you might as well test this one.

BR,
Nikos
kannel.diff (application/octet-stream, 13.7 KB)
Index: test/fakesmsc.c
===================================================================
RCS file: /home/cvs/gateway/test/fakesmsc.c,v
retrieving revision 1.33
diff -a -u -r1.33 fakesmsc.c
--- test/fakesmsc.c	9 Jan 2008 20:06:53 -0000	1.33
+++ test/fakesmsc.c	27 Nov 2008 04:17:57 -0000
@@ -85,14 +85,15 @@
 *        where the given static elements in <msg> are used as constant prefixes,\n\
 * <msg> is message to send, if several are given, they are sent randomly.\n\
 \n\
-msg format: \"sender receiver type(text/data/udh/route) [udhdata|route] msgdata\"\n\
+msg format: \"sender receiver type(text/data/udh/route/dlr-mask) [udhdata|route] msgdata\"\n\
 \n\
 Type \"text\" means plaintext msgdata, \"data\" urlcoded, \"udh\" urlcoded udh+msg\n\
-and \"route\" means smsbox-id routed plaintext msgdata\n\
+\"route\" means smsbox-id routed and dlr-mask <mask> request DLR (plaintext msgdata)\n\
 Examples: \n\
 \n\
 fakesmsc -m 1 \"123 345 udh %04udh%3f message+data+here\"\n\
 fakesmsc -m 1 \"123 345 route smsbox1 message+data+here\"\n\
+fakesmsc -m 1 \"123 345 dlr-mask 3 Hello World\"\n\
 fakesmsc -i 0.01 -m 1000 \"123 345 text nop\" \"1 2 text another message here\"\n\
 fakesmsc -z 7 -m 1000 \"123<rand> 345<rand> text nop <rand>\"\n\
 \n\
@@ -226,17 +227,18 @@
     Octstr **msgs;
     int i;
     int mptr, num_msgs;
-    long num_received, num_sent;
+    long num_received, num_sent, num_stored;
     double first_received_at, last_received_at;
     double first_sent_at, last_sent_at;
     double start_time, end_time;
-    double delta;
+    double delta = 0;
     int interactive, maxfd;
     char *cptr;
     char buffer[IN_BUFSIZE];
     fd_set rset;
     struct timeval alarm;
     FILE *fp;
+	char *p, from[25], to[11];
 
     gwlib_init();
     setup_signal_handlers();
@@ -245,7 +247,7 @@
 
     mptr = get_and_set_debugs(argc, argv, check_args);
     num_msgs = argc - mptr;
-		
+
     interactive = 0;
     msgs = NULL;
     fp = NULL;
@@ -275,6 +277,7 @@
 
     num_sent = 0;
     num_received = 0;
+    num_stored = 0;
 
     first_received_at = 0;
     first_sent_at = 0;
@@ -282,7 +285,7 @@
     last_sent_at = 0;
 
     /* infinitely loop */
-    while (1) {
+    while (interactive || delta >= 0) {
         /* Are we on interactive mode? */ 
         if (interactive == 1) {
             /* Check if we need to clean things up beforehand */
@@ -325,11 +328,12 @@
                 panic(0, "write failed");
 
             ++num_sent;
-            if (num_sent == max_send)
-                info(0, "fakesmsc: sent message %ld", num_sent);
-            else
-                debug("send", 0, "fakesmsc: sent message %ld", num_sent);
-      
+				strncpy(from, octstr_get_cstr(msg), 24);
+				p = strchr(from, ' ');
+				*p = '\0';
+				strncpy(to, ++p, 10);
+				if ((p = strchr(to, ' '))) *p = '\0';
+            info(0, "fakesmsc: Sent msg %ld <%s %s>", num_sent, to, from);
             if (rnd > 0)
                 octstr_destroy(msg);
 
@@ -344,7 +348,7 @@
                 delta = 0;
             if (num_sent >= max_send)
                 delta = -1;
-            conn_wait(server, delta);
+				if (delta > 0 || interactive) conn_wait(server, delta);
             if (conn_error(server) || conn_eof(server) || sigint_received)
                 goto over;
 
@@ -353,17 +357,20 @@
                 last_received_at = get_current_time();
                 if (first_received_at == 0)
                     first_received_at = last_received_at;
-                ++num_received;
-                if (num_received == max_send) {
-                    info(0, "Got message %ld: <%s>", num_received,
-                           octstr_get_cstr(line));
-                } else {
-                    debug("receive", 0, "Got message %ld: <%s>", num_received,
-                          octstr_get_cstr(line));
-                }
+					 if (strstr(octstr_get_cstr(line), to))
+					 {
+						 ++num_received;
+						 info(0, "fakesmsc: Got message %ld: <%s>", num_received, octstr_get_cstr(line));
+						 if (num_received == max_send && !interactive) break;
+					 }
+					 else
+					 {
+						 num_stored++;
+						 info(0, "fakesmsc: Got stored msg %ld: <%s>", num_stored, octstr_get_cstr(line));
+					 }
                 octstr_destroy(line);
             }
-        } while (delta > 0 || num_sent >= max_send);
+        } while (delta > 0 || num_received < num_sent);
     }
 
 over:
@@ -376,22 +383,25 @@
 
     end_time = get_current_time();
 
-    info(0, "fakesmsc: %ld messages sent and %ld received", num_sent, num_received);
-    info(0, "fakesmsc: total running time %.1f seconds", end_time - start_time);
-    delta = last_sent_at - first_sent_at;
-    if (delta == 0)
-        delta = .01;
-    if (num_sent > 1)
-        info(0, "fakesmsc: from first to last sent message %.1f s, "
-                "%.1f msgs/s", delta, (num_sent - 1) / delta);
-    delta = last_received_at - first_received_at;
-    if (delta == 0)
-        delta = .01;
-    if (num_received > 1)
-        info(0, "fakesmsc: from first to last received message %.1f s, "
-                "%.1f msgs/s", delta, (num_received - 1) / delta);
+	 if (!interactive)
+	 {
+		 info(0, "fakesmsc: %ld messages sent and %ld received", num_sent, num_received);
+		 info(0, "fakesmsc: %ld messages retrieved from store", num_stored);
+		 info(0, "fakesmsc: total running time %.1f seconds", end_time - start_time);
+		 delta = last_sent_at - first_sent_at;
+		 if (delta == 0)
+			  delta = .01;
+		 if (num_sent > 1)
+			  info(0, "fakesmsc: from first to last sent message %.1f s, "
+						 "%.1f msgs/s", delta, (num_sent - 1) / delta);
+		 delta = last_received_at - first_received_at;
+		 if (delta == 0)
+			  delta = .01;
+		 if (num_received > 1)
+			  info(0, "fakesmsc: from first to last received message %.1f s, "
+						 "%.1f msgs/s", delta, (num_received - 1) / delta);
+	 }
     info(0, "fakesmsc: terminating");
     
     return 0;
 }
-
Index: gw/smsc/smsc_fake.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_fake.c,v
retrieving revision 1.21
diff -a -u -r1.21 smsc_fake.c
--- gw/smsc/smsc_fake.c	9 Jan 2008 20:06:52 -0000	1.21
+++ gw/smsc/smsc_fake.c	27 Nov 2008 04:17:57 -0000
@@ -84,7 +84,7 @@
     int		shutdown; /* Signal to the connection thread to shut down */
     int		listening_socket; /* File descriptor */
     int		port;		  /* Port number to listen */
-    Octstr	*allow_ip, *deny_ip;
+    Octstr	*allow_ip, *deny_ip, *dlr_url;
 } PrivData;
 
 
@@ -160,12 +160,12 @@
     return 1;
 }
 
-
 static void msg_to_bb(SMSCConn *conn, Octstr *line)
 {
     long p, p2;
-    Msg *msg;
+    Msg *msg, *copy = NULL;
     Octstr *type = NULL; /* might be destroyed after error before created */
+    PrivData *privdata = (PrivData *)conn->data;
 
     msg = msg_create(sms);
     p = octstr_search_char(line, ' ', 0);
@@ -212,7 +212,13 @@
         if (p2 == -1)
             goto error;
         tmp = octstr_copy(line, p + 1, p2 - p - 1);
-        msg->sms.dlr_mask = atoi(octstr_get_cstr(tmp));
+        if (!privdata->dlr_url || (octstr_get_char(privdata->dlr_url, 0) != 'h'))
+           warning(0, "smsc_fake: You need to specify dlr-url in smsc to use DLRs.");
+        else
+        {
+           msg->sms.dlr_mask = atoi(octstr_get_cstr(tmp));
+           msg->sms.dlr_url = octstr_duplicate(privdata->dlr_url);
+        }
         octstr_destroy(tmp);
         msg->sms.msgdata = octstr_copy(line, p2 + 1, LONG_MAX);
     }
@@ -222,10 +228,13 @@
     octstr_destroy(type);
     time(&msg->sms.time);
     msg->sms.smsc_id = octstr_duplicate(conn->id);
+    if (msg->sms.dlr_mask > DLR_NOTHING)
+       copy = msg_duplicate(msg);
 
     debug("bb.sms", 0, "smsc_fake: new message received");
 //    msg_dump(msg, 0);
     bb_smscconn_receive(conn, msg);
+    if (copy) gwlist_append(privdata->outgoing_queue, copy);
     return;
 error:
     warning(0, "smsc_fake: invalid message syntax from client, ignored");
@@ -235,7 +244,6 @@
     return;
 }
 
-
 static void main_connection_loop(SMSCConn *conn, Connection *client)
 {
     PrivData *privdata = conn->data;
@@ -256,57 +264,24 @@
         if (conn_eof(client))
             goto eof;
 
-        /* 
+        /*
          * We won't get DLRs from fakesmsc itself, due that we don't have
-         * corresponding message IDs etc. We threat the DLR receiving here. So
+         * corresponding message IDs etc. We treat the DLR receiving here. So
          * DLR "originate" from the protocol layer towards abstraction layer.
          * This is all for pure debugging and testing.
          */
 
-        while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) {
-
-            /* pass msg to fakesmsc daemon */            
-            if (sms_to_client(client, msg) == 1) {
-                Msg *copy = msg_duplicate(msg);
-                
-                /* 
-                 * Actually no quarantee of it having been really sent,
-                 * but I suppose that doesn't matter since this interface
-                 * is just for debugging anyway. The upper layer will send
-                 * a SMSC success DLR if mask is set. Be aware that msg is
-                 * destroyed in abstraction layer, that's why we use a copy
-                 * afterwards to handle the final DLR. 
-                 */
-                bb_smscconn_sent(conn, msg, NULL);
-
-                /* and now the final DLR */
-                if (DLR_IS_SUCCESS_OR_FAIL(copy->sms.dlr_mask)) {
-                    Msg *dlrmsg;
-                    Octstr *tmp;
-                    int dlrstat = DLR_SUCCESS;
-                    char id[UUID_STR_LEN + 1];
-
-                    uuid_unparse(copy->sms.id, id);
-                    tmp = octstr_create(id);
-                    dlrmsg = dlr_find(conn->id,
-                                      tmp, /* smsc message id */
-                                      copy->sms.receiver, /* destination */
-                                      dlrstat);
-                    if (dlrmsg != NULL) {
-                        /* XXX TODO: Provide a SMPP DLR text in msgdata */
-                        bb_smscconn_receive(conn, dlrmsg);
-                    } else {
-                        error(0,"smsc_fale: got DLR but could not find message or was not interested in it");
-                    }
-                    octstr_destroy(tmp);
-                }
-                msg_destroy(copy);
-
-            } else {
+        while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) 
+        {
+            if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
+               msg->sms.dlr_mask = DLR_SMSC_SUCCESS;
+            else if (sms_to_client(client, msg) != 1)
+            {
                 bb_smscconn_send_failed(conn, msg,
-		            SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));
+                      SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));
                 goto error;
             }
+            bb_smscconn_sent(conn, msg, NULL);
 
             /* obey throughput speed limit, if any */
             if (conn->throughput > 0) {
@@ -548,6 +523,7 @@
 
     privdata->outgoing_queue = gwlist_create();
     privdata->shutdown = 0;
+    privdata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url"));
 
     conn->status = SMSCCONN_CONNECTING;
     conn->connect_time = time(NULL);
Index: doc/userguide/userguide.xml
===================================================================
RCS file: /home/cvs/gateway/doc/userguide/userguide.xml,v
retrieving revision 1.340
diff -a -u -r1.340 userguide.xml
--- doc/userguide/userguide.xml	9 Oct 2008 23:58:45 -0000	1.340
+++ doc/userguide/userguide.xml	27 Nov 2008 04:18:06 -0000
@@ -8558,23 +8558,34 @@
     <para>The parts of a message are separated with spaces. As each message is
     taken as one argument, it must be put in quotation marks.</para>
 
-    <para>Message type must be one of the following: "text", "data" and "udh".
+    <para>Message type must be one of the following: "text", "data", "udh", 
+    "route" and "dlr-mask".
     Here's an example of using each:</para>
 
 <programlisting>
 test/fakesmsc -i 0.01 -v 1 -m 1000 "100 300 text echo this message"
 test/fakesmsc -i 0.01 -m 1000 "100 300 data echo+these+chars%03%04%7f"
 test/fakesmsc -m 1 "100 500 udh %0eudh+stuff+here main+message"
+test/fakesmsc -m 10 -z 3 "100 500 dlr-mask 3 Hello World"
+test/fakesmsc -m 1 "123 345 route smsbox1 Hello World"
 </programlisting>
 
     <para>For "text", the rest of the argument is taken as the literal
     message. For "data", the next part must be the url-encoded version of
     the message. Space is coded as '+'. For "udh", the next 2 parts
-    are the UDH and main message. Both must be in url-encoded form.</para>
+    are the UDH and main message. Both must be in url-encoded form.
+    For "route" the text that follows wiil be sent through the
+    specified smsbox. For "dlr-mask" you will also get a (fake) DLR
+    for your sms. To use this feature you need to specify a dlr-url in
+    smsc configuration.</para>
 
     <para>If multiple messages are given, fakesmsc randomly chooses
     one for each sending.</para>
 
+    <para>This is the batch mode in which all parameters are specified
+    in the command line. It will exit at the end of the run while
+    printing some benchmark statistics.</para>
+
 </sect3>
 <sect3>
 <title>Interactive mode</title>
@@ -8630,6 +8641,16 @@
        Using 0 can be useful to listen for messages sent via other
        channels.
      </entry></row>
+
+   <row><entry><literal>-z</literal></entry>
+     <entry><emphasis>randomize</emphasis></entry>
+     <entry valign="bottom">
+        Randomize message parts according to the bitmask:
+           1: From
+           2: To
+           3: Text
+        Usefull in batch operations where a lot of messages are generated.
+     </entry></row>
   </tbody>
   </tgroup>
  </table>
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.