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>