drive_smpp.c
资源名称:gateway-1.2.1 [点击查看]
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:12k
源码类别:
手机WAP编程
开发平台:
WINDOWS
- /*
- * drive_smpp.c - SMPP server for testing purposes
- *
- * Lars Wirzenius
- */
- #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"
- 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 Counter *num_to_esme;
- static long max_to_esme;
- static Counter *num_from_bearerbox;
- static Counter *num_to_bearerbox;
- static Counter *num_from_esme;
- static time_t start_time = (time_t) -1;
- static time_t first_to_esme = (time_t) -1;
- static time_t last_to_esme = (time_t) -1;
- static time_t last_from_esme = (time_t) -1;
- 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 void quit(void)
- {
- quitting = 1;
- gwthread_wakeup_all();
- }
- typedef struct {
- Connection *conn;
- int transmitter;
- int receiver;
- } ESME;
- static ESME *esme_create(Connection *conn)
- {
- ESME *esme;
- esme = gw_malloc(sizeof(*esme));
- esme->conn = conn;
- esme->transmitter = 0;
- esme->receiver = 0;
- return esme;
- }
- static void esme_destroy(ESME *esme)
- {
- if (esme != NULL) {
- conn_destroy(esme->conn);
- gw_free(esme);
- }
- }
- static SMPP_PDU *handle_bind_transmitter(ESME *esme, SMPP_PDU *pdu)
- {
- SMPP_PDU *resp;
- esme->transmitter = 1;
- resp = smpp_pdu_create(bind_transmitter_resp,
- pdu->u.bind_transmitter.sequence_number);
- #if 0 /* XXX system_id is not implemented in the PDU at the moment */
- resp->u.bind_transmitter_resp.system_id =
- octstr_duplicate(smsc_system_id);
- #endif
- return resp;
- }
- static SMPP_PDU *handle_bind_receiver(ESME *esme, SMPP_PDU *pdu)
- {
- SMPP_PDU *resp;
- esme->receiver = 1;
- resp = smpp_pdu_create(bind_receiver_resp,
- pdu->u.bind_receiver.sequence_number);
- #if 0 /* XXX system_id is not implemented in the PDU at the moment */
- resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
- #endif
- return resp;
- }
- static SMPP_PDU *handle_submit_sm(ESME *esme, SMPP_PDU *pdu)
- {
- 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;
- if (id == max_to_esme)
- info(0, "ESME has submitted all messages to SMSC.");
- time(&last_from_esme);
- resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
- #if 0 /* XXX message_id is not implemented in the PDU at the moment */
- resp->u.submit_sm_resp.message_id =
- octstr_format("%ld", counter_increase(message_id_counter));
- #endif
- return resp;
- }
- static SMPP_PDU *handle_deliver_sm_resp(ESME *esme, SMPP_PDU *pdu)
- {
- return NULL;
- }
- 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;
- }
- static SMPP_PDU *handle_enquire_link(ESME *esme, SMPP_PDU *pdu)
- {
- return smpp_pdu_create(enquire_link_resp,
- pdu->u.enquire_link.sequence_number);
- }
- static SMPP_PDU *handle_enquire_link_resp(ESME *esme, SMPP_PDU *pdu)
- {
- return NULL;
- }
- static struct {
- unsigned long type;
- SMPP_PDU *(*handler)(ESME *, SMPP_PDU *);
- } handlers[] = {
- #define HANDLER(name) { name, handle_ ## name },
- HANDLER(bind_transmitter)
- HANDLER(bind_receiver)
- HANDLER(submit_sm)
- HANDLER(deliver_sm_resp)
- HANDLER(unbind)
- HANDLER(enquire_link)
- HANDLER(enquire_link_resp)
- #undef HANDLER
- };
- static int num_handlers = sizeof(handlers) / sizeof(handlers[0]);
- static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
- {
- SMPP_PDU *resp;
- Octstr *os;
- int i;
- debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name);
- for (i = 0; i < num_handlers; ++i) {
- if (handlers[i].type == pdu->type) {
- resp = handlers[i].handler(esme, pdu);
- if (resp != NULL) {
- os = smpp_pdu_pack(resp);
- conn_write(esme->conn, os);
- octstr_destroy(os);
- smpp_pdu_destroy(resp);
- }
- return;
- }
- }
- error(0, "Unhandled SMPP PDU.");
- smpp_pdu_dump(pdu);
- }
- static void send_smpp_thread(void *arg)
- {
- ESME *esme;
- Octstr *os;
- 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;
- while (!quitting && counter_value(num_from_esme) + 500 < id)
- 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);
- os = smpp_pdu_pack(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));
- os = smpp_pdu_pack(pdu);
- conn_write(esme->conn, os);
- octstr_destroy(os);
- smpp_pdu_destroy(pdu);
- debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
- }
- }
- time(&last_to_esme);
- if (id == max_to_esme)
- info(0, "All messages sent to ESME.");
- debug("test.smpp", 0, "%s terminates.", __func__);
- }
- static void receive_smpp_thread(void *arg)
- {
- ESME *esme;
- Octstr *os;
- long len;
- long sender_id;
- SMPP_PDU *pdu;
- esme = arg;
- sender_id = -1;
- len = 0;
- while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
- for (;;) {
- if (len == 0) {
- len = smpp_pdu_read_len(esme->conn);
- if (len == -1) {
- error(0, "Client sent garbage, closing connection.");
- goto error;
- } else if (len == 0) {
- if (conn_eof(esme->conn) || conn_read_error(esme->conn))
- goto error;
- break;
- }
- }
- gw_assert(len > 0);
- os = smpp_pdu_read_data(esme->conn, len);
- if (os != NULL) {
- len = 0;
- pdu = smpp_pdu_unpack(os);
- if (pdu == NULL) {
- error(0, "PDU unpacking failed!");
- octstr_dump(os, 0);
- } else {
- handle_pdu(esme, pdu);
- smpp_pdu_destroy(pdu);
- }
- octstr_destroy(os);
- } else if (conn_eof(esme->conn) || conn_read_error(esme->conn))
- goto error;
- else
- break;
- }
- if (!quitting && esme->receiver && sender_id == -1)
- sender_id = gwthread_create(send_smpp_thread, esme);
- }
- error:
- if (sender_id != -1) {
- quit();
- gwthread_join(sender_id);
- }
- esme_destroy(esme);
- quit();
- debug("test.smpp", 0, "%s terminates.", __func__);
- }
- static void smsbox_thread(void *arg)
- {
- Connection *conn;
- Msg *msg;
- Octstr *os;
- Octstr *reply_msg;
- 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) {
- 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");
- }
- while (!quitting && conn_wait(conn, -1.0) != -1) {
- for (;;) {
- os = conn_read_withlen(conn);
- if (os == NULL) {
- if (conn_eof(conn) || conn_read_error(conn))
- goto error;
- break;
- }
- msg = msg_unpack(os);
- if (msg == NULL || msg->type == wdp_datagram)
- error(0, "Bearerbox sent garbage to smsbox");
- if (msg->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));
- if (count == max_to_esme)
- info(0, "Bearerbox has sent all messages to smsbox.");
- conn_write_withlen(conn, reply_msg);
- counter_increase(num_to_bearerbox);
- }
- msg_destroy(msg);
- octstr_destroy(os);
- time(&last_to_bb);
- }
- }
- error:
- conn_destroy(conn);
- octstr_destroy(reply_msg);
- debug("test.smpp", 0, "%s terminates.", __func__);
- }
- static void accept_thread(void *arg)
- {
- int fd;
- int new_fd;
- int port;
- socklen_t addrlen;
- struct sockaddr addr;
- long smsbox_thread_id;
- port = *(int *) arg;
- fd = make_server_socket(port, NULL);
- if (fd == -1)
- panic(0, "Couldn't create SMPP listen port.");
- smsbox_thread_id = -1;
- for (;;) {
- if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN)
- break;
- addrlen = sizeof(addr);
- new_fd = accept(fd, &addr, &addrlen);
- if (start_time == (time_t) -1)
- time(&start_time);
- gwthread_create(receive_smpp_thread,
- esme_create(conn_wrap_fd(new_fd, 0)));
- if (smsbox_thread_id == -1)
- smsbox_thread_id = gwthread_create(smsbox_thread, NULL);
- }
- debug("test.smpp", 0, "%s terminates.", __func__);
- }
- static void handler(int signal)
- {
- panic(0, "Caught signal %d.", signal);
- }
- static void help(void)
- {
- info(0, "drive_smpp [-h] [-v level]燵-p port]");
- }
- int main(int argc, char **argv)
- {
- struct sigaction act;
- int http_port;
- int port;
- int opt;
- double run_time;
- char *log_file;
- gwlib_init();
- act.sa_handler = handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- 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("localhost");
- port_for_smsbox = 13001;
- max_to_esme = 1;
- num_to_esme = counter_create();
- num_from_esme = counter_create();
- num_to_bearerbox = counter_create();
- num_from_bearerbox = counter_create();
- log_file = NULL;
- while ((opt = getopt(argc, argv, "hv:p:P:m:l:")) != EOF) {
- switch (opt) {
- case 'v':
- log_set_output_level(atoi(optarg));
- break;
- case 'h':
- help();
- exit(0);
- case 'm':
- max_to_esme = atoi(optarg);
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'P':
- http_port = atoi(optarg);
- break;
- case 'l':
- log_file = optarg;
- break;
- case '?':
- default:
- error(0, "Invalid option %c", opt);
- help();
- panic(0, "Stopping.");
- }
- }
- if (log_file != NULL)
- log_open(log_file, GW_DEBUG);
- info(0, "Starting drive_smpp test.");
- gwthread_create(accept_thread, &port);
- gwthread_join_all();
- debug("test.smpp", 0, "Program exiting normally.");
- run_time = difftime(last_from_esme, first_to_esme);
- info(0, "Number of messages sent to ESME: %ld",
- counter_value(num_to_esme));
- info(0, "Number of messages sent to smsbox: %ld",
- counter_value(num_from_bearerbox));
- info(0, "Number of messages sent to bearerbox: %ld",
- counter_value(num_to_bearerbox));
- info(0, "Number of messages sent to SMSC: %ld",
- counter_value(num_from_esme));
- info(0, "Time: %.0f secs", run_time);
- info(0, "Time until all sent to ESME: %.0f secs",
- difftime(last_to_esme, start_time));
- info(0, "Time from first from bb to last to bb: %.0f secs",
- difftime(last_to_bb, first_from_bb));
- info(0, "Time until all sent to SMSC: %.0f secs",
- difftime(last_from_esme, start_time));
- info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec",
- counter_value(num_to_esme) / run_time);
- info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec",
- counter_value(num_from_esme) / run_time);
- octstr_destroy(smsc_system_id);
- octstr_destroy(smsc_source_addr);
- octstr_destroy(bearerbox_host);
- counter_destroy(num_to_esme);
- counter_destroy(num_from_esme);
- counter_destroy(num_to_bearerbox);
- counter_destroy(num_from_bearerbox);
- counter_destroy(message_id_counter);
- gwlib_shutdown();
- return 0;
- }