drive_smpp.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:12k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * drive_smpp.c - SMPP server for testing purposes
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6. #include <errno.h>
  7. #include <signal.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include "gwlib/gwlib.h"
  11. #include "gw/smsc/smpp_pdu.h"
  12. #include "gw/msg.h"
  13. static int quitting = 0;
  14. static Octstr *smsc_system_id;
  15. static Octstr *smsc_source_addr;
  16. static Counter *message_id_counter;
  17. static Octstr *bearerbox_host;
  18. static int port_for_smsbox;
  19. static Counter *num_to_esme;
  20. static long max_to_esme;
  21. static Counter *num_from_bearerbox;
  22. static Counter *num_to_bearerbox;
  23. static Counter *num_from_esme;
  24. static time_t start_time = (time_t) -1;
  25. static time_t first_to_esme = (time_t) -1;
  26. static time_t last_to_esme = (time_t) -1;
  27. static time_t last_from_esme = (time_t) -1;
  28. static time_t first_from_bb = (time_t) -1;
  29. static time_t last_to_bb = (time_t) -1;
  30. static long enquire_interval = 1; /* Measured in messages, not time. */
  31. static void quit(void)
  32. {
  33.     quitting = 1;
  34.     gwthread_wakeup_all();
  35. }
  36. typedef struct {
  37.     Connection *conn;
  38.     int transmitter;
  39.     int receiver;
  40. } ESME;
  41. static ESME *esme_create(Connection *conn)
  42. {
  43.     ESME *esme;
  44.     
  45.     esme = gw_malloc(sizeof(*esme));
  46.     esme->conn = conn;
  47.     esme->transmitter = 0;
  48.     esme->receiver = 0;
  49.     return esme;
  50. }
  51. static void esme_destroy(ESME *esme)
  52. {
  53.     if (esme != NULL) {
  54. conn_destroy(esme->conn);
  55. gw_free(esme);
  56.     }
  57. }
  58. static SMPP_PDU *handle_bind_transmitter(ESME *esme, SMPP_PDU *pdu)
  59. {
  60.     SMPP_PDU *resp;
  61.     
  62.     esme->transmitter = 1;
  63.     resp = smpp_pdu_create(bind_transmitter_resp,
  64.                    pdu->u.bind_transmitter.sequence_number);
  65. #if 0 /* XXX system_id is not implemented in the PDU at the moment */
  66.     resp->u.bind_transmitter_resp.system_id = 
  67.      octstr_duplicate(smsc_system_id);
  68. #endif
  69.     return resp;
  70. }
  71. static SMPP_PDU *handle_bind_receiver(ESME *esme, SMPP_PDU *pdu)
  72. {
  73.     SMPP_PDU *resp;
  74.     
  75.     esme->receiver = 1;
  76.     resp = smpp_pdu_create(bind_receiver_resp,
  77.                    pdu->u.bind_receiver.sequence_number);
  78. #if 0 /* XXX system_id is not implemented in the PDU at the moment */
  79.     resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
  80. #endif
  81.     return resp;
  82. }
  83. static SMPP_PDU *handle_submit_sm(ESME *esme, SMPP_PDU *pdu)
  84. {
  85.     SMPP_PDU *resp;
  86.     unsigned long id;
  87.     
  88.     debug("test.smpp", 0, "submit_sm: short_message = <%s>",
  89.        octstr_get_cstr(pdu->u.submit_sm.short_message));
  90.     id = counter_increase(num_from_esme) + 1;
  91.     if (id == max_to_esme)
  92.      info(0, "ESME has submitted all messages to SMSC.");
  93.     time(&last_from_esme);
  94.     resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
  95. #if 0 /* XXX message_id is not implemented in the PDU at the moment */
  96.     resp->u.submit_sm_resp.message_id = 
  97.      octstr_format("%ld", counter_increase(message_id_counter));
  98. #endif
  99.     return resp;
  100. }
  101. static SMPP_PDU *handle_deliver_sm_resp(ESME *esme, SMPP_PDU *pdu)
  102. {
  103.     return NULL;
  104. }
  105. static SMPP_PDU *handle_unbind(ESME *esme, SMPP_PDU *pdu)
  106. {
  107.     SMPP_PDU *resp;
  108.     
  109.     resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
  110.     return resp;
  111. }
  112. static SMPP_PDU *handle_enquire_link(ESME *esme, SMPP_PDU *pdu)
  113. {
  114.     return smpp_pdu_create(enquire_link_resp, 
  115.                   pdu->u.enquire_link.sequence_number);
  116. }
  117. static SMPP_PDU *handle_enquire_link_resp(ESME *esme, SMPP_PDU *pdu)
  118. {
  119.     return NULL;
  120. }
  121. static struct {
  122.     unsigned long type;
  123.     SMPP_PDU *(*handler)(ESME *, SMPP_PDU *);
  124. } handlers[] = {
  125.     #define HANDLER(name) { name, handle_ ## name },
  126.     HANDLER(bind_transmitter)
  127.     HANDLER(bind_receiver)
  128.     HANDLER(submit_sm)
  129.     HANDLER(deliver_sm_resp)
  130.     HANDLER(unbind)
  131.     HANDLER(enquire_link)
  132.     HANDLER(enquire_link_resp)
  133.     #undef HANDLER
  134. };
  135. static int num_handlers = sizeof(handlers) / sizeof(handlers[0]);
  136. static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
  137. {
  138.     SMPP_PDU *resp;
  139.     Octstr *os;
  140.     int i;
  141.     debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name);
  142.     for (i = 0; i < num_handlers; ++i) {
  143.      if (handlers[i].type == pdu->type) {
  144.     resp = handlers[i].handler(esme, pdu);
  145.     if (resp != NULL) {
  146.      os = smpp_pdu_pack(resp);
  147. conn_write(esme->conn, os);
  148. octstr_destroy(os);
  149. smpp_pdu_destroy(resp);
  150.     }
  151.     return;
  152. }
  153.     }
  154.     error(0, "Unhandled SMPP PDU.");
  155.     smpp_pdu_dump(pdu);
  156. }
  157. static void send_smpp_thread(void *arg)
  158. {
  159.     ESME *esme;
  160.     Octstr *os;
  161.     SMPP_PDU *pdu;
  162.     unsigned long id;
  163.     esme = arg;
  164.     
  165.     id = 0;
  166.     while (!quitting && counter_value(num_to_esme) < max_to_esme) {
  167. id = counter_increase(num_to_esme) + 1;
  168.      while (!quitting && counter_value(num_from_esme) + 500 < id)
  169.     gwthread_sleep(1.0);
  170. if (quitting)
  171.     break;
  172. pdu = smpp_pdu_create(deliver_sm,
  173.        counter_increase(message_id_counter));
  174. pdu->u.deliver_sm.source_addr = octstr_create("456");
  175. pdu->u.deliver_sm.destination_addr = octstr_create("123");
  176. pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
  177. os = smpp_pdu_pack(pdu);
  178. conn_write(esme->conn, os);
  179. octstr_destroy(os);
  180. smpp_pdu_destroy(pdu);
  181. if (first_to_esme == (time_t) -1)
  182.     time(&first_to_esme);
  183. debug("test.smpp", 0, 
  184.       "Delivered SMS %ld of %ld to bearerbox via SMPP.",
  185.       id, max_to_esme);
  186.      if ((id % enquire_interval) == 0) {
  187.     pdu = smpp_pdu_create(enquire_link, 
  188.                  counter_increase(message_id_counter));
  189.     os = smpp_pdu_pack(pdu);
  190.     conn_write(esme->conn, os);
  191.     octstr_destroy(os);
  192.     smpp_pdu_destroy(pdu);
  193.     debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
  194. }
  195.     }
  196.     time(&last_to_esme);
  197.     if (id == max_to_esme)
  198. info(0, "All messages sent to ESME.");
  199.     debug("test.smpp", 0, "%s terminates.", __func__);
  200. }
  201. static void receive_smpp_thread(void *arg)
  202. {
  203.     ESME *esme;
  204.     Octstr *os;
  205.     long len;
  206.     long sender_id;
  207.     SMPP_PDU *pdu;
  208.     esme = arg;
  209.     
  210.     sender_id = -1;
  211.     len = 0;
  212.     while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
  213.      for (;;) {
  214.     if (len == 0) {
  215. len = smpp_pdu_read_len(esme->conn);
  216. if (len == -1) {
  217.     error(0, "Client sent garbage, closing connection.");
  218.     goto error;
  219. } else if (len == 0) {
  220.     if (conn_eof(esme->conn) || conn_read_error(esme->conn))
  221.      goto error;
  222.     break;
  223. }
  224.     }
  225.     
  226.          gw_assert(len > 0);
  227.     os = smpp_pdu_read_data(esme->conn, len);
  228.     if (os != NULL) {
  229.           len = 0;
  230. pdu = smpp_pdu_unpack(os);
  231. if (pdu == NULL) {
  232.     error(0, "PDU unpacking failed!");
  233.     octstr_dump(os, 0);
  234. } else {
  235.     handle_pdu(esme, pdu);
  236.     smpp_pdu_destroy(pdu);
  237. }
  238. octstr_destroy(os);
  239.     } else if (conn_eof(esme->conn) || conn_read_error(esme->conn))
  240.      goto error;
  241.     else
  242. break;
  243. }
  244.      if (!quitting && esme->receiver && sender_id == -1)
  245.     sender_id = gwthread_create(send_smpp_thread, esme);
  246.     }
  247. error:
  248.     if (sender_id != -1) {
  249. quit();
  250. gwthread_join(sender_id);
  251.     }
  252.     esme_destroy(esme);
  253.     quit();
  254.     debug("test.smpp", 0, "%s terminates.", __func__);
  255. }
  256. static void smsbox_thread(void *arg)
  257. {
  258.     Connection *conn;
  259.     Msg *msg;
  260.     Octstr *os;
  261.     Octstr *reply_msg;
  262.     unsigned long count;
  263.     
  264.     msg = msg_create(sms);
  265.     msg->sms.sender = octstr_create("123");
  266.     msg->sms.receiver = octstr_create("456");
  267.     msg->sms.msgdata = octstr_create("hello world");
  268.     reply_msg = msg_pack(msg);
  269.     msg_destroy(msg);
  270.     gwthread_sleep(1.0);
  271.     conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
  272.     if (conn == NULL) {
  273. gwthread_sleep(2.0);
  274. conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
  275.      if (conn == NULL)
  276.     panic(0, "Couldn't connect to bearerbox as smsbox");
  277.     }
  278.     while (!quitting && conn_wait(conn, -1.0) != -1) {
  279.      for (;;) {
  280.     os = conn_read_withlen(conn);
  281.     if (os == NULL) {
  282. if (conn_eof(conn) || conn_read_error(conn))
  283.     goto error;
  284. break;
  285.     }
  286.     
  287.     msg = msg_unpack(os);
  288.     if (msg == NULL || msg->type == wdp_datagram)
  289. error(0, "Bearerbox sent garbage to smsbox");
  290.     if (msg->type == sms) {
  291. if (first_from_bb == (time_t) -1)
  292.     time(&first_from_bb);
  293. count = counter_increase(num_from_bearerbox) + 1;
  294. debug("test.smpp", 0, 
  295.       "Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
  296.       count, octstr_get_cstr(msg->sms.msgdata));
  297. if (count == max_to_esme)
  298.     info(0, "Bearerbox has sent all messages to smsbox.");
  299. conn_write_withlen(conn, reply_msg);
  300. counter_increase(num_to_bearerbox);
  301.     }
  302.     msg_destroy(msg);
  303.     octstr_destroy(os);
  304.     time(&last_to_bb);
  305. }
  306.     }
  307.     
  308. error:
  309.     conn_destroy(conn);
  310.     octstr_destroy(reply_msg);
  311.     debug("test.smpp", 0, "%s terminates.", __func__);
  312. }
  313. static void accept_thread(void *arg)
  314. {
  315.     int fd;
  316.     int new_fd;
  317.     int port;
  318.     socklen_t addrlen;
  319.     struct sockaddr addr;
  320.     long smsbox_thread_id;
  321.     
  322.     port = *(int *) arg;
  323.     fd = make_server_socket(port, NULL);
  324.     if (fd == -1)
  325.      panic(0, "Couldn't create SMPP listen port.");
  326.     
  327.     smsbox_thread_id = -1;
  328.     for (;;) {
  329. if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN)
  330.     break;
  331. addrlen = sizeof(addr);
  332. new_fd = accept(fd, &addr, &addrlen);
  333.      if (start_time == (time_t) -1)
  334.     time(&start_time);
  335. gwthread_create(receive_smpp_thread, 
  336. esme_create(conn_wrap_fd(new_fd, 0)));
  337. if (smsbox_thread_id == -1)
  338.     smsbox_thread_id = gwthread_create(smsbox_thread, NULL);
  339.     }
  340.     debug("test.smpp", 0, "%s terminates.", __func__);
  341. }
  342. static void handler(int signal)
  343. {
  344.     panic(0, "Caught signal %d.", signal);
  345. }
  346. static void help(void)
  347. {
  348.     info(0, "drive_smpp [-h] [-v level]燵-p port]");
  349. }
  350. int main(int argc, char **argv)
  351. {
  352.     struct sigaction act;
  353.     int http_port;
  354.     int port;
  355.     int opt;
  356.     double run_time;
  357.     char *log_file;
  358.     gwlib_init();
  359.     act.sa_handler = handler;
  360.     sigemptyset(&act.sa_mask);
  361.     act.sa_flags = 0;
  362.     sigaction(SIGTERM, &act, NULL);
  363.     sigaction(SIGINT, &act, NULL);
  364.     port = 2345;
  365.     http_port = 8080;
  366.     smsc_system_id = octstr_create("kannel_smpp");
  367.     smsc_source_addr = octstr_create("123456");
  368.     message_id_counter = counter_create();
  369.     bearerbox_host = octstr_create("localhost");
  370.     port_for_smsbox = 13001;
  371.     max_to_esme = 1;
  372.     num_to_esme = counter_create();
  373.     num_from_esme = counter_create();
  374.     num_to_bearerbox = counter_create();
  375.     num_from_bearerbox = counter_create();
  376.     log_file = NULL;
  377.     while ((opt = getopt(argc, argv, "hv:p:P:m:l:")) != EOF) {
  378. switch (opt) {
  379. case 'v':
  380.     log_set_output_level(atoi(optarg));
  381.     break;
  382. case 'h':
  383.     help();
  384.     exit(0);
  385. case 'm':
  386.     max_to_esme = atoi(optarg);
  387.     break;
  388. case 'p':
  389.     port = atoi(optarg);
  390.     break;
  391. case 'P':
  392.     http_port = atoi(optarg);
  393.     break;
  394.      case 'l':
  395.     log_file = optarg;
  396.     break;
  397. case '?':
  398. default:
  399.     error(0, "Invalid option %c", opt);
  400.     help();
  401.     panic(0, "Stopping.");
  402. }
  403.     }
  404.     if (log_file != NULL)
  405.      log_open(log_file, GW_DEBUG);
  406.     info(0, "Starting drive_smpp test.");
  407.     gwthread_create(accept_thread, &port);
  408.     gwthread_join_all();
  409.     debug("test.smpp", 0, "Program exiting normally.");
  410.     run_time = difftime(last_from_esme, first_to_esme);
  411.     info(0, "Number of messages sent to ESME: %ld",
  412.       counter_value(num_to_esme));
  413.     info(0, "Number of messages sent to smsbox: %ld",
  414.       counter_value(num_from_bearerbox));
  415.     info(0, "Number of messages sent to bearerbox: %ld",
  416.       counter_value(num_to_bearerbox));
  417.     info(0, "Number of messages sent to SMSC: %ld",
  418.       counter_value(num_from_esme));
  419.     info(0, "Time: %.0f secs", run_time);
  420.     info(0, "Time until all sent to ESME: %.0f secs", 
  421.       difftime(last_to_esme, start_time));
  422.     info(0, "Time from first from bb to last to bb: %.0f secs", 
  423.       difftime(last_to_bb, first_from_bb));
  424.     info(0, "Time until all sent to SMSC: %.0f secs", 
  425.       difftime(last_from_esme, start_time));
  426.     info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec",
  427.       counter_value(num_to_esme) / run_time);
  428.     info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec",
  429.       counter_value(num_from_esme) / run_time);
  430.     octstr_destroy(smsc_system_id);
  431.     octstr_destroy(smsc_source_addr);
  432.     octstr_destroy(bearerbox_host);
  433.     counter_destroy(num_to_esme);
  434.     counter_destroy(num_from_esme);
  435.     counter_destroy(num_to_bearerbox);
  436.     counter_destroy(num_from_bearerbox);
  437.     counter_destroy(message_id_counter);
  438.     gwlib_shutdown();
  439.     return 0;
  440. }