Re: Patch: test/drive_smpp.c
"Nikos Balkanas" <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <AD9592BDE7B845A5A3B69FEE31E1855C@drwho> |
Hi, Fixed identation. Beafed up smsbox_thread and routed most variables to configuration. Uses main kannel configuration. Just add an smpp smsc definition to 127.0.0.1 for it. It will test main kannel configuration in addition to TLVs. As already mentioned I extended its functionality to handle external messaging and concatenation. It is a FAKE smpp server, that also, benchmarks bearerbox's SMPP implementation. Anyone interested, please grab. If it makes it to kannel, i will also provide documentation. BR, Nikos
drive_smpp.diff
(application/octet-stream, 12.8 KB)
Index: test/drive_smpp.c
===================================================================
--- test/drive_smpp.c (revision 4833)
+++ test/drive_smpp.c (working copy)
@@ -69,16 +69,22 @@
#include "gwlib/gwlib.h"
#include "gw/smsc/smpp_pdu.h"
#include "gw/msg.h"
+#include "shared.h"
+#define MAX_SMS_OCTETS 140
+#define CATENATE_UDH_LEN 5
+typedef unsigned char uchar;
+
static int quitting = 0;
static Octstr *smsc_system_id;
static Octstr *smsc_source_addr;
static Counter *message_id_counter;
static Octstr *bearerbox_host;
-static int port_for_smsbox;
+static long port_for_smsbox;
static Counter *num_to_esme;
static long max_to_esme;
+static long port;
static Counter *num_from_bearerbox;
static Counter *num_to_bearerbox;
static Counter *num_from_esme;
@@ -89,6 +95,9 @@
static time_t first_from_bb = (time_t) -1;
static time_t last_to_bb = (time_t) -1;
static long enquire_interval = 1; /* Measured in messages, not time. */
+static Octstr *SMS = NULL;
+static Octstr *smsbox_id;
+static Octstr *smsc_id;
static void quit(void)
@@ -109,7 +118,7 @@
static ESME *esme_create(Connection *conn)
{
ESME *esme;
-
+
esme = gw_malloc(sizeof(*esme));
esme->conn = conn;
esme->transmitter = 0;
@@ -131,7 +140,7 @@
static SMPP_PDU *handle_bind_transmitter(ESME *esme, SMPP_PDU *pdu)
{
SMPP_PDU *resp;
-
+
esme->transmitter = 1;
esme->version = pdu->u.bind_transmitter.interface_version;
resp = smpp_pdu_create(bind_transmitter_resp,
@@ -147,7 +156,7 @@
static SMPP_PDU *handle_bind_receiver(ESME *esme, SMPP_PDU *pdu)
{
SMPP_PDU *resp;
-
+
esme->receiver = 1;
esme->version = pdu->u.bind_receiver.interface_version;
resp = smpp_pdu_create(bind_receiver_resp,
@@ -163,7 +172,7 @@
{
SMPP_PDU *resp;
unsigned long id;
-
+
debug("test.smpp", 0, "submit_sm: short_message = <%s>",
octstr_get_cstr(pdu->u.submit_sm.short_message));
id = counter_increase(num_from_esme) + 1;
@@ -189,7 +198,7 @@
static SMPP_PDU *handle_unbind(ESME *esme, SMPP_PDU *pdu)
{
SMPP_PDU *resp;
-
+
resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
return resp;
}
@@ -249,16 +258,24 @@
smpp_pdu_dump(pdu);
}
+void load_deliver_pdu(SMPP_PDU *pdu, Octstr *data, ESME *esme)
+{
+ pdu->u.deliver_sm.source_addr = octstr_create("456");
+ pdu->u.deliver_sm.destination_addr = octstr_create("123");
+ pdu->u.deliver_sm.short_message = data;
+ if (esme->version > 0x33)
+ pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
+}
static void send_smpp_thread(void *arg)
{
ESME *esme;
- Octstr *os;
+ Octstr *os, *data;
SMPP_PDU *pdu;
unsigned long id;
esme = arg;
-
+
id = 0;
while (!quitting && counter_value(num_to_esme) < max_to_esme) {
id = counter_increase(num_to_esme) + 1;
@@ -266,23 +283,67 @@
gwthread_sleep(1.0);
if (quitting)
break;
- pdu = smpp_pdu_create(deliver_sm, counter_increase(message_id_counter));
- pdu->u.deliver_sm.source_addr = octstr_create("456");
- pdu->u.deliver_sm.destination_addr = octstr_create("123");
- pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
- if (esme->version > 0x33)
- pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
+ if (SMS)
+ {
+ if (octstr_len(SMS) <= (MAX_SMS_OCTETS * 8)/7)
+ {
+ data = octstr_create(octstr_get_cstr(SMS));
+ goto single;
+ }
+ else
+ {
+ uchar *start = octstr_get_cstr(SMS), *p = start, *end, c;
+ int len = octstr_len(SMS), part = 0, num_msgs, part_len;
+
+ part_len = (MAX_SMS_OCTETS - CATENATE_UDH_LEN - 1) *8/7;
+ num_msgs = len/part_len;
+ if (len%part_len) num_msgs++;
+ while (start - p < len)
+ {
+ part++;
+ end = start + part_len;
+ if (end < p + len)
+ {
+ c = *end;
+ *end = '\0';
+ }
+ else end = p + len;
+ data = octstr_format("%c%c\3\xAF%c%c", CATENATE_UDH_LEN, 0,
+ num_msgs, part);
+ octstr_append_data(data, start, end - start);
+ if (end < p + len) *end = c;
+ pdu = smpp_pdu_create(deliver_sm, counter_increase
+ (message_id_counter));
+ load_deliver_pdu(pdu, data, esme);
+ pdu->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class |
+ ESM_CLASS_DELIVER_UDH_INDICATOR;
os = smpp_pdu_pack(NULL, pdu);
conn_write(esme->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(pdu);
+ start = end;
+ }
+ }
+ }
+ else
+ {
+ data = octstr_format("%ld", id);
+single: pdu = smpp_pdu_create(deliver_sm, counter_increase
+ (message_id_counter));
+ load_deliver_pdu(pdu, data, esme);
+ os = smpp_pdu_pack(NULL, pdu);
+ conn_write(esme->conn, os);
+ octstr_destroy(os);
+ smpp_pdu_destroy(pdu);
+ }
if (first_to_esme == (time_t) -1)
time(&first_to_esme);
debug("test.smpp", 0, "Delivered SMS %ld of %ld to bearerbox via SMPP.",
id, max_to_esme);
if ((id % enquire_interval) == 0) {
- pdu = smpp_pdu_create(enquire_link, counter_increase(message_id_counter));
+ pdu = smpp_pdu_create(enquire_link, counter_increase
+ (message_id_counter));
os = smpp_pdu_pack(NULL, pdu);
conn_write(esme->conn, os);
octstr_destroy(os);
@@ -306,7 +367,7 @@
SMPP_PDU *pdu;
esme = arg;
-
+
sender_id = -1;
len = 0;
while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
@@ -322,7 +383,7 @@
break;
}
}
-
+
gw_assert(len > 0);
os = smpp_pdu_read_data(esme->conn, len);
if (os != NULL) {
@@ -356,30 +417,53 @@
debug("test.smpp", 0, "%s terminates.", __func__);
}
+/*
+ * Identify ourself to bearerbox for smsbox-specific routing inside bearerbox.
+ * Do this even while no smsbox-id is given to unlock the sender thread in
+ * bearerbox.
+ */
+static void announce_to_bearerbox(Connection *conn)
+{
+ Msg *msg;
+ Octstr *pack;
+ debug("smpp.test", 0, "Announcing smsbox %s to bearerbox", octstr_get_cstr
+ (smsbox_id));
+ msg = msg_create(admin);
+ msg->admin.command = cmd_identify;
+ msg->admin.boxc_id = octstr_duplicate(smsbox_id);
+ pack = msg_pack(msg);
+ conn_write_withlen(conn, pack);
+ octstr_destroy(pack);
+}
+
static void smsbox_thread(void *arg)
{
Connection *conn;
- Msg *msg;
+ Msg *msg, *msgin = NULL;
Octstr *os;
- Octstr *reply_msg;
+ Octstr *reply_msg = NULL;
unsigned long count;
-
+
msg = msg_create(sms);
msg->sms.sender = octstr_create("123");
msg->sms.receiver = octstr_create("456");
msg->sms.msgdata = octstr_create("hello world");
- reply_msg = msg_pack(msg);
- msg_destroy(msg);
gwthread_sleep(1.0);
conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
- if (conn == NULL) {
+ if (conn == NULL)
+ {
gwthread_sleep(2.0);
conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
if (conn == NULL)
panic(0, "Couldn't connect to bearerbox as smsbox");
+ else debug("test.smpp", 0, "Connected as smsbox to bearerbox %s:%ld",
+ octstr_get_cstr(bearerbox_host), port_for_smsbox);
}
+ else debug("test.smpp", 0, "Connected as smsbox to bearerbox %s:%ld",
+ octstr_get_cstr(bearerbox_host), port_for_smsbox);
+ announce_to_bearerbox(conn);
while (!quitting && conn_wait(conn, -1.0) != -1) {
for (;;) {
@@ -389,32 +473,38 @@
goto error;
break;
}
-
- msg = msg_unpack(os);
- if (msg == NULL || msg->type == wdp_datagram)
+
+ msgin = msg_unpack(os);
+ if (msgin == NULL || msgin->type == wdp_datagram)
error(0, "Bearerbox sent garbage to smsbox");
- if (msg->type == sms) {
+ if (msgin->type == sms) {
if (first_from_bb == (time_t) -1)
time(&first_from_bb);
count = counter_increase(num_from_bearerbox) + 1;
debug("test.smpp", 0,
"Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
- count, octstr_get_cstr(msg->sms.msgdata));
+ count, octstr_get_cstr(msgin->sms.msgdata));
if (count == max_to_esme)
info(0, "Bearerbox has sent all messages to smsbox.");
+ octstr_destroy(msg->sms.smsc_id);
+ msg->sms.smsc_id = msgin->sms.smsc_id;
+ msgin->sms.smsc_id = NULL;
+ octstr_destroy(reply_msg);
+ reply_msg = msg_pack(msg);
+ msg_destroy(msgin);
conn_write_withlen(conn, reply_msg);
counter_increase(num_to_bearerbox);
}
- msg_destroy(msg);
octstr_destroy(os);
time(&last_to_bb);
}
}
-
-error:
+
+ error:
conn_destroy(conn);
octstr_destroy(reply_msg);
+ msg_destroy(msg);
debug("test.smpp", 0, "%s terminates.", __func__);
}
@@ -428,7 +518,7 @@
struct sockaddr addr;
long smsbox_thread_id;
- port = *(int *) arg;
+ port = *(long *) arg;
fd = make_server_socket(port, NULL);
if (fd == -1)
panic(0, "Couldn't create SMPP listen port.");
@@ -459,15 +549,50 @@
static void help(void)
{
- info(0, "drive_smpp [-h] [-v level][-l logfile][-p port][-m msgs][-c config]");
+ info(0, "drive_smpp [-h][-v level][-l logfile][-p http_port][-M SMS][-m msgs][-c config]");
}
+void smpp_init(Cfg *cfg)
+{
+ CfgGroup *grp;
+ Octstr *value;
+ List *grplist;
+ if (!(grp = cfg_get_single_group(cfg, octstr_imm("core"))))
+ panic(0, "Missing core group");
+ if (cfg_get_integer(&port_for_smsbox, grp, octstr_imm("smsbox-port")) == -1)
+ port_for_smsbox = 13001;
+ if (!(grp = cfg_get_single_group(cfg, octstr_imm("smsbox"))))
+ panic(0, "Missing smsbox definition");
+ if (!(smsbox_id = cfg_get(grp, octstr_imm("smsbox-id"))))
+ panic(0, "Missing smsbox-id definition");
+ if ((grplist = cfg_get_multi_group(cfg, octstr_imm("smsc"))))
+ {
+ while ((grp = gwlist_extract_first(grplist)))
+ {
+ if ((value = cfg_get(grp, octstr_imm("host"))) && octstr_compare
+ (value, octstr_imm("127.0.0.1")) == 0)
+ {
+ if (!(smsc_id = cfg_get(grp, octstr_imm("smsc-id"))))
+ panic(0, "Missing smsc-id in smpp smsc definition");
+ if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1)
+ port = 2345;
+ break;
+ }
+ octstr_destroy(value);
+ }
+ }
+ else panic(0, "Missing smpp smsc definition");
+ if (!smsc_id) panic(0, "Missing local (127.0.0.1) smpp smsc definition");
+ gwlist_destroy(grplist, NULL);
+ smpp_pdu_init(cfg);
+}
+
+
int main(int argc, char **argv)
{
struct sigaction act;
int http_port;
- int port;
int opt;
double run_time;
char *log_file;
@@ -481,13 +606,11 @@
sigaction(SIGTERM, &act, NULL);
sigaction(SIGINT, &act, NULL);
- port = 2345;
http_port = 8080;
smsc_system_id = octstr_create("kannel_smpp");
smsc_source_addr = octstr_create("123456");
message_id_counter = counter_create();
bearerbox_host = octstr_create("127.0.0.1");
- port_for_smsbox = 13001;
max_to_esme = 1;
num_to_esme = counter_create();
num_from_esme = counter_create();
@@ -495,7 +618,7 @@
num_from_bearerbox = counter_create();
log_file = config_file = NULL;
- while ((opt = getopt(argc, argv, "hv:p:P:m:l:c:")) != EOF) {
+ while ((opt = getopt(argc, argv, "hv:p:M:m:l:c:")) != EOF) {
switch (opt) {
case 'v':
log_set_output_level(atoi(optarg));
@@ -509,18 +632,18 @@
max_to_esme = atoi(optarg);
break;
- case 'p':
- port = atoi(optarg);
+ case 'M':
+ SMS = octstr_imm(optarg);
break;
- case 'P':
+ case 'p':
http_port = atoi(optarg);
break;
case 'l':
log_file = optarg;
break;
-
+
case 'c':
config_file = optarg;
break;
@@ -539,15 +662,15 @@
if (config_file != NULL) {
Cfg *cfg;
Octstr *tmp = octstr_create(config_file);
-
+
cfg = cfg_create(tmp);
octstr_destroy(tmp);
if (cfg_read(cfg) == -1)
panic(0, "Errors in config file.");
- smpp_pdu_init(cfg);
+ smpp_init(cfg);
cfg_destroy(cfg);
}
-
+
info(0, "Starting drive_smpp test.");
gwthread_create(accept_thread, &port);
gwthread_join_all();