00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <errno.h>
00065 #include <signal.h>
00066 #include <sys/types.h>
00067 #include <sys/socket.h>
00068
00069 #include "gwlib/gwlib.h"
00070 #include "gw/smsc/smpp_pdu.h"
00071 #include "gw/msg.h"
00072
00073
00074 static int quitting = 0;
00075 static Octstr *smsc_system_id;
00076 static Octstr *smsc_source_addr;
00077 static Counter *message_id_counter;
00078 static Octstr *bearerbox_host;
00079 static int port_for_smsbox;
00080 static Counter *num_to_esme;
00081 static long max_to_esme;
00082 static Counter *num_from_bearerbox;
00083 static Counter *num_to_bearerbox;
00084 static Counter *num_from_esme;
00085 static time_t start_time = (time_t) -1;
00086 static time_t first_to_esme = (time_t) -1;
00087 static time_t last_to_esme = (time_t) -1;
00088 static time_t last_from_esme = (time_t) -1;
00089 static time_t first_from_bb = (time_t) -1;
00090 static time_t last_to_bb = (time_t) -1;
00091 static long enquire_interval = 1;
00092
00093
00094 static void quit(void)
00095 {
00096 quitting = 1;
00097 gwthread_wakeup_all();
00098 }
00099
00100
00101 typedef struct {
00102 Connection *conn;
00103 int transmitter;
00104 int receiver;
00105 } ESME;
00106
00107
00108 static ESME *esme_create(Connection *conn)
00109 {
00110 ESME *esme;
00111
00112 esme = gw_malloc(sizeof(*esme));
00113 esme->conn = conn;
00114 esme->transmitter = 0;
00115 esme->receiver = 0;
00116 return esme;
00117 }
00118
00119
00120 static void esme_destroy(ESME *esme)
00121 {
00122 if (esme != NULL) {
00123 conn_destroy(esme->conn);
00124 gw_free(esme);
00125 }
00126 }
00127
00128
00129 static SMPP_PDU *handle_bind_transmitter(ESME *esme, SMPP_PDU *pdu)
00130 {
00131 SMPP_PDU *resp;
00132
00133 esme->transmitter = 1;
00134 resp = smpp_pdu_create(bind_transmitter_resp,
00135 pdu->u.bind_transmitter.sequence_number);
00136 #if 0
00137 resp->u.bind_transmitter_resp.system_id =
00138 octstr_duplicate(smsc_system_id);
00139 #endif
00140 return resp;
00141 }
00142
00143
00144 static SMPP_PDU *handle_bind_receiver(ESME *esme, SMPP_PDU *pdu)
00145 {
00146 SMPP_PDU *resp;
00147
00148 esme->receiver = 1;
00149 resp = smpp_pdu_create(bind_receiver_resp,
00150 pdu->u.bind_receiver.sequence_number);
00151 #if 0
00152 resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
00153 #endif
00154 return resp;
00155 }
00156
00157
00158 static SMPP_PDU *handle_submit_sm(ESME *esme, SMPP_PDU *pdu)
00159 {
00160 SMPP_PDU *resp;
00161 unsigned long id;
00162
00163 debug("test.smpp", 0, "submit_sm: short_message = <%s>",
00164 octstr_get_cstr(pdu->u.submit_sm.short_message));
00165 id = counter_increase(num_from_esme) + 1;
00166 if (id == max_to_esme)
00167 info(0, "ESME has submitted all messages to SMSC.");
00168 time(&last_from_esme);
00169
00170 resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
00171 #if 0
00172 resp->u.submit_sm_resp.message_id =
00173 octstr_format("%ld", counter_increase(message_id_counter));
00174 #endif
00175 return resp;
00176 }
00177
00178
00179 static SMPP_PDU *handle_deliver_sm_resp(ESME *esme, SMPP_PDU *pdu)
00180 {
00181 return NULL;
00182 }
00183
00184
00185 static SMPP_PDU *handle_unbind(ESME *esme, SMPP_PDU *pdu)
00186 {
00187 SMPP_PDU *resp;
00188
00189 resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
00190 return resp;
00191 }
00192
00193
00194 static SMPP_PDU *handle_enquire_link(ESME *esme, SMPP_PDU *pdu)
00195 {
00196 return smpp_pdu_create(enquire_link_resp,
00197 pdu->u.enquire_link.sequence_number);
00198 }
00199
00200
00201 static SMPP_PDU *handle_enquire_link_resp(ESME *esme, SMPP_PDU *pdu)
00202 {
00203 return NULL;
00204 }
00205
00206
00207 static struct {
00208 unsigned long type;
00209 SMPP_PDU *(*handler)(ESME *, SMPP_PDU *);
00210 } handlers[] = {
00211 #define HANDLER(name) { name, handle_ ## name },
00212 HANDLER(bind_transmitter)
00213 HANDLER(bind_receiver)
00214 HANDLER(submit_sm)
00215 HANDLER(deliver_sm_resp)
00216 HANDLER(unbind)
00217 HANDLER(enquire_link)
00218 HANDLER(enquire_link_resp)
00219 #undef HANDLER
00220 };
00221 static int num_handlers = sizeof(handlers) / sizeof(handlers[0]);
00222
00223
00224 static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
00225 {
00226 SMPP_PDU *resp;
00227 Octstr *os;
00228 int i;
00229
00230 debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name);
00231 for (i = 0; i < num_handlers; ++i) {
00232 if (handlers[i].type == pdu->type) {
00233 resp = handlers[i].handler(esme, pdu);
00234 if (resp != NULL) {
00235 os = smpp_pdu_pack(resp);
00236 conn_write(esme->conn, os);
00237 octstr_destroy(os);
00238 smpp_pdu_destroy(resp);
00239 }
00240 return;
00241 }
00242 }
00243
00244 error(0, "Unhandled SMPP PDU.");
00245 smpp_pdu_dump(pdu);
00246 }
00247
00248
00249 static void send_smpp_thread(void *arg)
00250 {
00251 ESME *esme;
00252 Octstr *os;
00253 SMPP_PDU *pdu;
00254 unsigned long id;
00255
00256 esme = arg;
00257
00258 id = 0;
00259 while (!quitting && counter_value(num_to_esme) < max_to_esme) {
00260 id = counter_increase(num_to_esme) + 1;
00261 while (!quitting && counter_value(num_from_esme) + 500 < id)
00262 gwthread_sleep(1.0);
00263 if (quitting)
00264 break;
00265 pdu = smpp_pdu_create(deliver_sm,
00266 counter_increase(message_id_counter));
00267 pdu->u.deliver_sm.source_addr = octstr_create("456");
00268 pdu->u.deliver_sm.destination_addr = octstr_create("123");
00269 pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
00270 os = smpp_pdu_pack(pdu);
00271 conn_write(esme->conn, os);
00272 octstr_destroy(os);
00273 smpp_pdu_destroy(pdu);
00274 if (first_to_esme == (time_t) -1)
00275 time(&first_to_esme);
00276 debug("test.smpp", 0,
00277 "Delivered SMS %ld of %ld to bearerbox via SMPP.",
00278 id, max_to_esme);
00279
00280 if ((id % enquire_interval) == 0) {
00281 pdu = smpp_pdu_create(enquire_link,
00282 counter_increase(message_id_counter));
00283 os = smpp_pdu_pack(pdu);
00284 conn_write(esme->conn, os);
00285 octstr_destroy(os);
00286 smpp_pdu_destroy(pdu);
00287 debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
00288 }
00289 }
00290 time(&last_to_esme);
00291 if (id == max_to_esme)
00292 info(0, "All messages sent to ESME.");
00293 debug("test.smpp", 0, "%s terminates.", __func__);
00294 }
00295
00296
00297 static void receive_smpp_thread(void *arg)
00298 {
00299 ESME *esme;
00300 Octstr *os;
00301 long len;
00302 long sender_id;
00303 SMPP_PDU *pdu;
00304
00305 esme = arg;
00306
00307 sender_id = -1;
00308 len = 0;
00309 while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
00310 for (;;) {
00311 if (len == 0) {
00312 len = smpp_pdu_read_len(esme->conn);
00313 if (len == -1) {
00314 error(0, "Client sent garbage, closing connection.");
00315 goto error;
00316 } else if (len == 0) {
00317 if (conn_eof(esme->conn) || conn_error(esme->conn))
00318 goto error;
00319 break;
00320 }
00321 }
00322
00323 gw_assert(len > 0);
00324 os = smpp_pdu_read_data(esme->conn, len);
00325 if (os != NULL) {
00326 len = 0;
00327 pdu = smpp_pdu_unpack(os);
00328 if (pdu == NULL) {
00329 error(0, "PDU unpacking failed!");
00330 octstr_dump(os, 0);
00331 } else {
00332 handle_pdu(esme, pdu);
00333 smpp_pdu_destroy(pdu);
00334 }
00335 octstr_destroy(os);
00336 } else if (conn_eof(esme->conn) || conn_error(esme->conn))
00337 goto error;
00338 else
00339 break;
00340 }
00341
00342 if (!quitting && esme->receiver && sender_id == -1)
00343 sender_id = gwthread_create(send_smpp_thread, esme);
00344 }
00345
00346 error:
00347 if (sender_id != -1) {
00348 quit();
00349 gwthread_join(sender_id);
00350 }
00351 esme_destroy(esme);
00352 quit();
00353 debug("test.smpp", 0, "%s terminates.", __func__);
00354 }
00355
00356
00357 static void smsbox_thread(void *arg)
00358 {
00359 Connection *conn;
00360 Msg *msg;
00361 Octstr *os;
00362 Octstr *reply_msg;
00363 unsigned long count;
00364
00365 msg = msg_create(sms);
00366 msg->sms.sender = octstr_create("123");
00367 msg->sms.receiver = octstr_create("456");
00368 msg->sms.msgdata = octstr_create("hello world");
00369 reply_msg = msg_pack(msg);
00370 msg_destroy(msg);
00371
00372 gwthread_sleep(1.0);
00373 conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
00374 if (conn == NULL) {
00375 gwthread_sleep(2.0);
00376 conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
00377 if (conn == NULL)
00378 panic(0, "Couldn't connect to bearerbox as smsbox");
00379 }
00380
00381 while (!quitting && conn_wait(conn, -1.0) != -1) {
00382 for (;;) {
00383 os = conn_read_withlen(conn);
00384 if (os == NULL) {
00385 if (conn_eof(conn) || conn_error(conn))
00386 goto error;
00387 break;
00388 }
00389
00390 msg = msg_unpack(os);
00391 if (msg == NULL || msg->type == wdp_datagram)
00392 error(0, "Bearerbox sent garbage to smsbox");
00393
00394 if (msg->type == sms) {
00395 if (first_from_bb == (time_t) -1)
00396 time(&first_from_bb);
00397 count = counter_increase(num_from_bearerbox) + 1;
00398 debug("test.smpp", 0,
00399 "Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
00400 count, octstr_get_cstr(msg->sms.msgdata));
00401 if (count == max_to_esme)
00402 info(0, "Bearerbox has sent all messages to smsbox.");
00403 conn_write_withlen(conn, reply_msg);
00404 counter_increase(num_to_bearerbox);
00405 }
00406 msg_destroy(msg);
00407 octstr_destroy(os);
00408 time(&last_to_bb);
00409 }
00410 }
00411
00412 error:
00413 conn_destroy(conn);
00414 octstr_destroy(reply_msg);
00415 debug("test.smpp", 0, "%s terminates.", __func__);
00416 }
00417
00418
00419 static void accept_thread(void *arg)
00420 {
00421 int fd;
00422 int new_fd;
00423 int port;
00424 socklen_t addrlen;
00425 struct sockaddr addr;
00426 long smsbox_thread_id;
00427
00428 port = *(int *) arg;
00429 fd = make_server_socket(port, NULL);
00430 if (fd == -1)
00431 panic(0, "Couldn't create SMPP listen port.");
00432
00433 smsbox_thread_id = -1;
00434 for (;;) {
00435 if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN)
00436 break;
00437 addrlen = sizeof(addr);
00438 new_fd = accept(fd, &addr, &addrlen);
00439 if (start_time == (time_t) -1)
00440 time(&start_time);
00441 gwthread_create(receive_smpp_thread,
00442 esme_create(conn_wrap_fd(new_fd, 0)));
00443 if (smsbox_thread_id == -1)
00444 smsbox_thread_id = gwthread_create(smsbox_thread, NULL);
00445 }
00446
00447 debug("test.smpp", 0, "%s terminates.", __func__);
00448 }
00449
00450
00451 static void handler(int signal)
00452 {
00453 panic(0, "Caught signal %d.", signal);
00454 }
00455
00456
00457 static void help(void)
00458 {
00459 info(0, "drive_smpp [-h] [-v level] [-p port]");
00460 }
00461
00462
00463 int main(int argc, char **argv)
00464 {
00465 struct sigaction act;
00466 int http_port;
00467 int port;
00468 int opt;
00469 double run_time;
00470 char *log_file;
00471
00472 gwlib_init();
00473
00474 act.sa_handler = handler;
00475 sigemptyset(&act.sa_mask);
00476 act.sa_flags = 0;
00477 sigaction(SIGTERM, &act, NULL);
00478 sigaction(SIGINT, &act, NULL);
00479
00480 port = 2345;
00481 http_port = 8080;
00482 smsc_system_id = octstr_create("kannel_smpp");
00483 smsc_source_addr = octstr_create("123456");
00484 message_id_counter = counter_create();
00485 bearerbox_host = octstr_create("127.0.0.1");
00486 port_for_smsbox = 13001;
00487 max_to_esme = 1;
00488 num_to_esme = counter_create();
00489 num_from_esme = counter_create();
00490 num_to_bearerbox = counter_create();
00491 num_from_bearerbox = counter_create();
00492 log_file = NULL;
00493
00494 while ((opt = getopt(argc, argv, "hv:p:P:m:l:")) != EOF) {
00495 switch (opt) {
00496 case 'v':
00497 log_set_output_level(atoi(optarg));
00498 break;
00499
00500 case 'h':
00501 help();
00502 exit(0);
00503
00504 case 'm':
00505 max_to_esme = atoi(optarg);
00506 break;
00507
00508 case 'p':
00509 port = atoi(optarg);
00510 break;
00511
00512 case 'P':
00513 http_port = atoi(optarg);
00514 break;
00515
00516 case 'l':
00517 log_file = optarg;
00518 break;
00519
00520 case '?':
00521 default:
00522 error(0, "Invalid option %c", opt);
00523 help();
00524 panic(0, "Stopping.");
00525 }
00526 }
00527
00528 if (log_file != NULL)
00529 log_open(log_file, GW_DEBUG, GW_NON_EXCL);
00530
00531 info(0, "Starting drive_smpp test.");
00532 gwthread_create(accept_thread, &port);
00533 gwthread_join_all();
00534 debug("test.smpp", 0, "Program exiting normally.");
00535
00536 run_time = difftime(last_from_esme, first_to_esme);
00537
00538 info(0, "Number of messages sent to ESME: %ld",
00539 counter_value(num_to_esme));
00540 info(0, "Number of messages sent to smsbox: %ld",
00541 counter_value(num_from_bearerbox));
00542 info(0, "Number of messages sent to bearerbox: %ld",
00543 counter_value(num_to_bearerbox));
00544 info(0, "Number of messages sent to SMSC: %ld",
00545 counter_value(num_from_esme));
00546 info(0, "Time: %.0f secs", run_time);
00547 info(0, "Time until all sent to ESME: %.0f secs",
00548 difftime(last_to_esme, start_time));
00549 info(0, "Time from first from bb to last to bb: %.0f secs",
00550 difftime(last_to_bb, first_from_bb));
00551 info(0, "Time until all sent to SMSC: %.0f secs",
00552 difftime(last_from_esme, start_time));
00553 info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec",
00554 counter_value(num_to_esme) / run_time);
00555 info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec",
00556 counter_value(num_from_esme) / run_time);
00557
00558 octstr_destroy(smsc_system_id);
00559 octstr_destroy(smsc_source_addr);
00560 octstr_destroy(bearerbox_host);
00561 counter_destroy(num_to_esme);
00562 counter_destroy(num_from_esme);
00563 counter_destroy(num_to_bearerbox);
00564 counter_destroy(num_from_bearerbox);
00565 counter_destroy(message_id_counter);
00566
00567 gwlib_shutdown();
00568 return 0;
00569 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.