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>
