#include <errno.h>#include <signal.h>#include <sys/types.h>#include <sys/socket.h>#include "gwlib/gwlib.h"#include "gw/smsc/smpp_pdu.h"#include "gw/msg.h"Include dependency graph for drive_smpp.c:

Go to the source code of this file.
|
|
|
|
|
Definition at line 419 of file drive_smpp.c. References conn_wrap_fd(), debug(), esme_create(), gwthread_create, gwthread_pollfd(), make_server_socket(), panic, POLLIN, port, receive_smpp_thread(), smsbox_thread(), and start_time. Referenced by main(). 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 }
|
Here is the call graph for this function:

|
|
Definition at line 108 of file drive_smpp.c. References ESME::conn. Referenced by accept_thread(). 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 }
|
|
|
Definition at line 120 of file drive_smpp.c. References ESME::conn, and conn_destroy(). Referenced by receive_smpp_thread(). 00121 {
00122 if (esme != NULL) {
00123 conn_destroy(esme->conn);
00124 gw_free(esme);
00125 }
00126 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 144 of file drive_smpp.c. References bind_receiver_resp, octstr_duplicate, pdu, ESME::receiver, smpp_pdu_create(), smsc_system_id, and SMPP_PDU::u. 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 /* XXX system_id is not implemented in the PDU at the moment */
00152 resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
00153 #endif
00154 return resp;
00155 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 129 of file drive_smpp.c. References bind_transmitter_resp, octstr_duplicate, pdu, smpp_pdu_create(), smsc_system_id, ESME::transmitter, and SMPP_PDU::u. 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 /* XXX system_id is not implemented in the PDU at the moment */
00137 resp->u.bind_transmitter_resp.system_id =
00138 octstr_duplicate(smsc_system_id);
00139 #endif
00140 return resp;
00141 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 179 of file drive_smpp.c. 00180 {
00181 return NULL;
00182 }
|
|
||||||||||||
|
Definition at line 194 of file drive_smpp.c. References enquire_link_resp, pdu, smpp_pdu_create(), and SMPP_PDU::u. 00195 {
00196 return smpp_pdu_create(enquire_link_resp,
00197 pdu->u.enquire_link.sequence_number);
00198 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 201 of file drive_smpp.c. 00202 {
00203 return NULL;
00204 }
|
|
||||||||||||
|
Definition at line 224 of file drive_smpp.c. References ESME::conn, conn_write(), debug(), error(), handlers, octstr_destroy(), pdu, smpp_pdu_destroy(), smpp_pdu_dump(), smpp_pdu_pack(), SMPP_PDU::type, and SMPP_PDU::type_name. Referenced by io_thread(), receive_smpp_thread(), and smasi_thread(). 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 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 158 of file drive_smpp.c. References counter_increase(), debug(), info(), last_from_esme, message_id_counter, num_from_esme, octstr_format(), octstr_get_cstr, pdu, smpp_pdu_create(), submit_sm_resp, and SMPP_PDU::u. 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 /* XXX message_id is not implemented in the PDU at the moment */
00172 resp->u.submit_sm_resp.message_id =
00173 octstr_format("%ld", counter_increase(message_id_counter));
00174 #endif
00175 return resp;
00176 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 185 of file drive_smpp.c. References pdu, smpp_pdu_create(), SMPP_PDU::u, and unbind_resp. 00186 {
00187 SMPP_PDU *resp;
00188
00189 resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
00190 return resp;
00191 }
|
Here is the call graph for this function:

|
|
Definition at line 451 of file drive_smpp.c. References panic. 00452 {
00453 panic(0, "Caught signal %d.", signal);
00454 }
|
|
|
Definition at line 457 of file drive_smpp.c. References info(). Referenced by main(). 00458 {
00459 info(0, "drive_smpp [-h] [-v level] [-p port]");
00460 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 463 of file drive_smpp.c. References accept_thread(), bearerbox_host, counter_create(), counter_destroy(), counter_value(), debug(), error(), first_from_bb, first_to_esme, getopt(), GW_DEBUG, GW_NON_EXCL, gwlib_init(), gwlib_shutdown(), gwthread_create, gwthread_join_all(), help(), info(), last_from_esme, last_to_bb, last_to_esme, log_open(), log_set_output_level(), max_to_esme, message_id_counter, num_from_bearerbox, num_from_esme, num_to_bearerbox, num_to_esme, octstr_create, octstr_destroy(), optarg, panic, port, port_for_smsbox, smsc_source_addr, smsc_system_id, and start_time. 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 }
|
Here is the call graph for this function:

|
|
Definition at line 94 of file drive_smpp.c. References gwthread_wakeup_all(), and quitting. Referenced by receive_smpp_thread(). 00095 {
00096 quitting = 1;
00097 gwthread_wakeup_all();
00098 }
|
Here is the call graph for this function:

|
|
Definition at line 297 of file drive_smpp.c. References ESME::conn, conn_eof(), conn_error(), conn_wait(), debug(), error(), esme_destroy(), gw_assert, gwthread_create, gwthread_join(), handle_pdu(), octstr_destroy(), octstr_dump, pdu, quit(), quitting, ESME::receiver, send_smpp_thread(), smpp_pdu_destroy(), smpp_pdu_read_data(), smpp_pdu_read_len(), and smpp_pdu_unpack(). Referenced by accept_thread(). 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 }
|
Here is the call graph for this function:

|
|
Definition at line 249 of file drive_smpp.c. References ESME::conn, conn_write(), counter_increase(), counter_value(), debug(), deliver_sm, enquire_link, first_to_esme, gwthread_sleep(), info(), last_to_esme, max_to_esme, message_id_counter, num_from_esme, num_to_esme, octstr_create, octstr_destroy(), octstr_format(), pdu, quitting, smpp_pdu_create(), smpp_pdu_destroy(), smpp_pdu_pack(), and SMPP_PDU::u. Referenced by receive_smpp_thread(). 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 }
|
Here is the call graph for this function:

|
|
Definition at line 357 of file drive_smpp.c. References bearerbox_host, conn_destroy(), conn_eof(), conn_error(), conn_open_tcp(), conn_read_withlen(), conn_wait(), conn_write_withlen(), counter_increase(), debug(), error(), first_from_bb, gwthread_sleep(), info(), last_to_bb, msg_create, msg_destroy(), msg_pack(), msg_unpack, num_from_bearerbox, num_to_bearerbox, octstr_create, octstr_destroy(), octstr_get_cstr, panic, port_for_smsbox, quitting, and sms. Referenced by accept_thread(). 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 }
|
Here is the call graph for this function:

|
|
Definition at line 78 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 91 of file drive_smpp.c. |
|
|
Definition at line 89 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 86 of file drive_smpp.c. Referenced by main(), and send_smpp_thread(). |
|
|
Referenced by charset_from_utf8(), and charset_to_utf8(). |
|
|
Referenced by handle_pdu(). |
|
|
Definition at line 88 of file drive_smpp.c. Referenced by handle_submit_sm(), and main(). |
|
|
Definition at line 90 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 87 of file drive_smpp.c. Referenced by main(), and send_smpp_thread(). |
|
|
Definition at line 81 of file drive_smpp.c. Referenced by main(), and send_smpp_thread(). |
|
|
Definition at line 77 of file drive_smpp.c. Referenced by handle_submit_sm(), main(), and send_smpp_thread(). |
|
|
Definition at line 82 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 84 of file drive_smpp.c. Referenced by handle_submit_sm(), main(), and send_smpp_thread(). |
|
|
Definition at line 221 of file drive_smpp.c. |
|
|
Definition at line 83 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 80 of file drive_smpp.c. Referenced by main(), and send_smpp_thread(). |
|
|
Definition at line 79 of file drive_smpp.c. Referenced by main(), and smsbox_thread(). |
|
|
Definition at line 74 of file drive_smpp.c. Referenced by quit(), receive_smpp_thread(), send_smpp_thread(), and smsbox_thread(). |
|
|
Definition at line 76 of file drive_smpp.c. Referenced by main(). |
|
|
Definition at line 75 of file drive_smpp.c. Referenced by handle_bind_receiver(), handle_bind_transmitter(), and main(). |
|
|
Definition at line 85 of file drive_smpp.c. Referenced by accept_thread(), and main(). |
|
|
Definition at line 208 of file drive_smpp.c. |