Kannel: Open Source WAP and SMS gateway  svn-r5335
drive_smpp.c File Reference
#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"

Go to the source code of this file.

Data Structures

struct  ESME
 

Macros

#define HANDLER(name)   { name, handle_ ## name },
 

Functions

static void quit (void)
 
static ESMEesme_create (Connection *conn)
 
static void esme_destroy (ESME *esme)
 
static SMPP_PDUhandle_bind_transmitter (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_bind_receiver (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_submit_sm (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_deliver_sm_resp (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_unbind (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_enquire_link (ESME *esme, SMPP_PDU *pdu)
 
static SMPP_PDUhandle_enquire_link_resp (ESME *esme, SMPP_PDU *pdu)
 
static void handle_pdu (ESME *esme, SMPP_PDU *pdu)
 
static void send_smpp_thread (void *arg)
 
static void receive_smpp_thread (void *arg)
 
static void smsbox_thread (void *arg)
 
static void accept_thread (void *arg)
 
static void handler (int signal)
 
static void help (void)
 
int main (int argc, char **argv)
 

Variables

static int quitting = 0
 
static Octstrsmsc_system_id
 
static Octstrsmsc_source_addr
 
static Countermessage_id_counter
 
static Octstrbearerbox_host
 
static int port_for_smsbox
 
static Counternum_to_esme
 
static long max_to_esme
 
static Counternum_from_bearerbox
 
static Counternum_to_bearerbox
 
static Counternum_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
 
struct {
   unsigned long   type
 
   SMPP_PDU *(*   handler )(ESME *, SMPP_PDU *)
 
handlers []
 
static int num_handlers = sizeof(handlers) / sizeof(handlers[0])
 

Macro Definition Documentation

◆ HANDLER

#define HANDLER (   name)    { name, handle_ ## name },

Function Documentation

◆ accept_thread()

static void accept_thread ( void *  arg)
static

Definition at line 422 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().

423 {
424  int fd;
425  int new_fd;
426  int port;
427  socklen_t addrlen;
428  struct sockaddr addr;
429  long smsbox_thread_id;
430 
431  port = *(int *) arg;
432  fd = make_server_socket(port, NULL);
433  if (fd == -1)
434  panic(0, "Couldn't create SMPP listen port.");
435 
436  smsbox_thread_id = -1;
437  for (;;) {
438  if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN)
439  break;
440  addrlen = sizeof(addr);
441  new_fd = accept(fd, &addr, &addrlen);
442  if (start_time == (time_t) -1)
443  time(&start_time);
445  esme_create(conn_wrap_fd(new_fd, 0)));
446  if (smsbox_thread_id == -1)
447  smsbox_thread_id = gwthread_create(smsbox_thread, NULL);
448  }
449 
450  debug("test.smpp", 0, "%s terminates.", __func__);
451 }
static time_t start_time
Definition: drive_smpp.c:85
Definition: http.c:2014
static void smsbox_thread(void *arg)
Definition: drive_smpp.c:360
static int port
Definition: fakesmsc.c:121
#define POLLIN
Definition: gwpoll.h:91
static void receive_smpp_thread(void *arg)
Definition: drive_smpp.c:300
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
#define gwthread_create(func, arg)
Definition: gwthread.h:90
int gwthread_pollfd(int fd, int events, double timeout)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define panic
Definition: log.h:87
int socklen_t
Definition: socket.h:73
static ESME * esme_create(Connection *conn)
Definition: drive_smpp.c:109
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ esme_create()

static ESME* esme_create ( Connection conn)
static

Definition at line 109 of file drive_smpp.c.

References ESME::conn, ESME::receiver, ESME::transmitter, and ESME::version.

Referenced by accept_thread().

110 {
111  ESME *esme;
112 
113  esme = gw_malloc(sizeof(*esme));
114  esme->conn = conn;
115  esme->transmitter = 0;
116  esme->receiver = 0;
117  esme->version = 0;
118  return esme;
119 }
long version
Definition: drive_smpp.c:105
int receiver
Definition: drive_smpp.c:104
int transmitter
Definition: drive_smpp.c:103
Connection * conn
Definition: drive_smpp.c:102

◆ esme_destroy()

static void esme_destroy ( ESME esme)
static

Definition at line 122 of file drive_smpp.c.

References ESME::conn, and conn_destroy().

Referenced by receive_smpp_thread().

123 {
124  if (esme != NULL) {
125  conn_destroy(esme->conn);
126  gw_free(esme);
127  }
128 }
void conn_destroy(Connection *conn)
Definition: conn.c:627
Connection * conn
Definition: drive_smpp.c:102

◆ handle_bind_receiver()

static SMPP_PDU* handle_bind_receiver ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 147 of file drive_smpp.c.

References octstr_duplicate, ESME::receiver, smpp_pdu_create(), smsc_system_id, SMPP_PDU::u, and ESME::version.

148 {
149  SMPP_PDU *resp;
150 
151  esme->receiver = 1;
152  esme->version = pdu->u.bind_receiver.interface_version;
153  resp = smpp_pdu_create(bind_receiver_resp,
154  pdu->u.bind_receiver.sequence_number);
155 #if 0 /* XXX system_id is not implemented in the PDU at the moment */
156  resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
157 #endif
158  return resp;
159 }
static Octstr * smsc_system_id
Definition: drive_smpp.c:75
long version
Definition: drive_smpp.c:105
int receiver
Definition: drive_smpp.c:104
#define octstr_duplicate(ostr)
Definition: octstr.h:187
union SMPP_PDU::@15 u
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ handle_bind_transmitter()

static SMPP_PDU* handle_bind_transmitter ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 131 of file drive_smpp.c.

References octstr_duplicate, smpp_pdu_create(), smsc_system_id, ESME::transmitter, SMPP_PDU::u, and ESME::version.

132 {
133  SMPP_PDU *resp;
134 
135  esme->transmitter = 1;
136  esme->version = pdu->u.bind_transmitter.interface_version;
137  resp = smpp_pdu_create(bind_transmitter_resp,
138  pdu->u.bind_transmitter.sequence_number);
139 #if 0 /* XXX system_id is not implemented in the PDU at the moment */
140  resp->u.bind_transmitter_resp.system_id =
142 #endif
143  return resp;
144 }
static Octstr * smsc_system_id
Definition: drive_smpp.c:75
long version
Definition: drive_smpp.c:105
int transmitter
Definition: drive_smpp.c:103
#define octstr_duplicate(ostr)
Definition: octstr.h:187
union SMPP_PDU::@15 u
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ handle_deliver_sm_resp()

static SMPP_PDU* handle_deliver_sm_resp ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 183 of file drive_smpp.c.

184 {
185  return NULL;
186 }

◆ handle_enquire_link()

static SMPP_PDU* handle_enquire_link ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 198 of file drive_smpp.c.

References smpp_pdu_create(), and SMPP_PDU::u.

199 {
200  return smpp_pdu_create(enquire_link_resp,
201  pdu->u.enquire_link.sequence_number);
202 }
union SMPP_PDU::@15 u
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ handle_enquire_link_resp()

static SMPP_PDU* handle_enquire_link_resp ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 205 of file drive_smpp.c.

206 {
207  return NULL;
208 }

◆ handle_pdu()

static void handle_pdu ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 228 of file drive_smpp.c.

References ESME::conn, conn_write(), debug(), error(), handlers, num_handlers, octstr_destroy(), octstr_imm(), smpp_pdu_destroy(), smpp_pdu_dump(), smpp_pdu_pack(), SMPP_PDU::type, type, and SMPP_PDU::type_name.

Referenced by receive_smpp_thread().

229 {
230  SMPP_PDU *resp;
231  Octstr *os;
232  int i;
233 
234  debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name);
235  for (i = 0; i < num_handlers; ++i) {
236  if (handlers[i].type == pdu->type) {
237  resp = handlers[i].handler(esme, pdu);
238  if (resp != NULL) {
239  os = smpp_pdu_pack(NULL, resp);
240  conn_write(esme->conn, os);
241  octstr_destroy(os);
242  smpp_pdu_destroy(resp);
243  }
244  return;
245  }
246  }
247 
248  error(0, "Unhandled SMPP PDU.");
249  smpp_pdu_dump(octstr_imm(""), pdu);
250 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
static struct @73 handlers[]
const char * type_name
Definition: smpp_pdu.h:92
static int num_handlers
Definition: drive_smpp.c:225
unsigned long type
Definition: smpp_pdu.h:91
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void smpp_pdu_dump(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:766
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
unsigned long type
Definition: drive_smpp.c:212
Connection * conn
Definition: drive_smpp.c:102

◆ handle_submit_sm()

static SMPP_PDU* handle_submit_sm ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 162 of file drive_smpp.c.

References counter_increase(), debug(), info(), last_from_esme, max_to_esme, message_id_counter, num_from_esme, octstr_format(), octstr_get_cstr, smpp_pdu_create(), and SMPP_PDU::u.

163 {
164  SMPP_PDU *resp;
165  unsigned long id;
166 
167  debug("test.smpp", 0, "submit_sm: short_message = <%s>",
168  octstr_get_cstr(pdu->u.submit_sm.short_message));
170  if (id == max_to_esme)
171  info(0, "ESME has submitted all messages to SMSC.");
172  time(&last_from_esme);
173 
174  resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
175 #if 0 /* XXX message_id is not implemented in the PDU at the moment */
176  resp->u.submit_sm_resp.message_id =
178 #endif
179  return resp;
180 }
void info(int err, const char *fmt,...)
Definition: log.c:672
static long max_to_esme
Definition: drive_smpp.c:81
static Counter * num_from_esme
Definition: drive_smpp.c:84
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
static Counter * message_id_counter
Definition: drive_smpp.c:77
union SMPP_PDU::@15 u
static time_t last_from_esme
Definition: drive_smpp.c:88
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ handle_unbind()

static SMPP_PDU* handle_unbind ( ESME esme,
SMPP_PDU pdu 
)
static

Definition at line 189 of file drive_smpp.c.

References smpp_pdu_create(), and SMPP_PDU::u.

190 {
191  SMPP_PDU *resp;
192 
193  resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
194  return resp;
195 }
union SMPP_PDU::@15 u
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ handler()

static void handler ( int  signal)
static

Definition at line 454 of file drive_smpp.c.

References panic.

455 {
456  panic(0, "Caught signal %d.", signal);
457 }
#define panic
Definition: log.h:87

◆ help()

static void help ( void  )
static

Definition at line 460 of file drive_smpp.c.

References info().

Referenced by main().

461 {
462  info(0, "drive_smpp [-h] [-v level][-l logfile][-p port][-m msgs][-c config]");
463 }
void info(int err, const char *fmt,...)
Definition: log.c:672

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 466 of file drive_smpp.c.

References accept_thread(), bearerbox_host, cfg, cfg_create(), cfg_destroy(), cfg_read(), 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(), handler, 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, smpp_pdu_init(), smsc_source_addr, smsc_system_id, and start_time.

467 {
468  struct sigaction act;
469  int port;
470  int opt;
471  double run_time;
472  char *log_file;
473  char *config_file;
474 
475  gwlib_init();
476 
477  act.sa_handler = handler;
478  sigemptyset(&act.sa_mask);
479  act.sa_flags = 0;
480  sigaction(SIGTERM, &act, NULL);
481  sigaction(SIGINT, &act, NULL);
482 
483  port = 2345;
484  smsc_system_id = octstr_create("kannel_smpp");
485  smsc_source_addr = octstr_create("123456");
487  bearerbox_host = octstr_create("127.0.0.1");
488  port_for_smsbox = 13001;
489  max_to_esme = 1;
494  log_file = config_file = NULL;
495 
496  while ((opt = getopt(argc, argv, "hv:p:m:l:c:")) != EOF) {
497  switch (opt) {
498  case 'v':
500  break;
501 
502  case 'h':
503  help();
504  exit(0);
505 
506  case 'm':
507  max_to_esme = atoi(optarg);
508  break;
509 
510  case 'p':
511  port = atoi(optarg);
512  break;
513 
514  case 'l':
515  log_file = optarg;
516  break;
517 
518  case 'c':
519  config_file = optarg;
520  break;
521 
522  case '?':
523  default:
524  error(0, "Invalid option %c", opt);
525  help();
526  panic(0, "Stopping.");
527  }
528  }
529 
530  if (log_file != NULL)
531  log_open(log_file, GW_DEBUG, GW_NON_EXCL);
532 
533  if (config_file != NULL) {
534  Cfg *cfg;
535  Octstr *tmp = octstr_create(config_file);
536 
537  cfg = cfg_create(tmp);
538  octstr_destroy(tmp);
539  if (cfg_read(cfg) == -1)
540  panic(0, "Errors in config file.");
542  cfg_destroy(cfg);
543  }
544 
545  info(0, "Starting drive_smpp test.");
548  debug("test.smpp", 0, "Program exiting normally.");
549 
550  run_time = difftime(last_from_esme, first_to_esme);
551 
552  info(0, "Number of messages sent to ESME: %ld",
554  info(0, "Number of messages sent to smsbox: %ld",
556  info(0, "Number of messages sent to bearerbox: %ld",
558  info(0, "Number of messages sent to SMSC: %ld",
560  info(0, "Time: %.0f secs", run_time);
561  info(0, "Time until all sent to ESME: %.0f secs",
562  difftime(last_to_esme, start_time));
563  info(0, "Time from first from bb to last to bb: %.0f secs",
564  difftime(last_to_bb, first_from_bb));
565  info(0, "Time until all sent to SMSC: %.0f secs",
566  difftime(last_from_esme, start_time));
567  info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec",
568  counter_value(num_to_esme) / run_time);
569  info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec",
570  counter_value(num_from_esme) / run_time);
571 
580 
581  gwlib_shutdown();
582  return 0;
583 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static time_t start_time
Definition: drive_smpp.c:85
static long max_to_esme
Definition: drive_smpp.c:81
void gwthread_join_all(void)
Definition: http.c:2014
static time_t last_to_bb
Definition: drive_smpp.c:90
static Octstr * smsc_source_addr
Definition: drive_smpp.c:76
static int port_for_smsbox
Definition: drive_smpp.c:79
void counter_destroy(Counter *counter)
Definition: counter.c:110
static Counter * num_from_esme
Definition: drive_smpp.c:84
static Octstr * smsc_system_id
Definition: drive_smpp.c:75
static time_t first_from_bb
Definition: drive_smpp.c:89
static Counter * num_from_bearerbox
Definition: drive_smpp.c:82
static Cfg * cfg
Definition: opensmppbox.c:95
Cfg * cfg_create(Octstr *filename)
Definition: cfg.c:318
int cfg_read(Cfg *cfg)
Definition: cfg.c:452
static int port
Definition: fakesmsc.c:121
int getopt(int argc, char **argv, char *opts)
Definition: attgetopt.c:84
Definition: cfg.c:164
Counter * counter_create(void)
Definition: counter.c:94
void cfg_destroy(Cfg *cfg)
Definition: cfg.c:331
void log_set_output_level(enum output_level level)
Definition: log.c:253
static Counter * num_to_bearerbox
Definition: drive_smpp.c:83
Definition: log.h:69
static Counter * num_to_esme
Definition: drive_smpp.c:80
static time_t first_to_esme
Definition: drive_smpp.c:86
static void accept_thread(void *arg)
Definition: drive_smpp.c:422
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
static Counter * message_id_counter
Definition: drive_smpp.c:77
static Octstr * bearerbox_host
Definition: drive_smpp.c:78
int log_open(char *filename, int level, enum excl_state excl)
Definition: log.c:375
static time_t last_from_esme
Definition: drive_smpp.c:88
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
char * optarg
Definition: attgetopt.c:82
#define panic
Definition: log.h:87
static void help(void)
Definition: drive_smpp.c:460
void gwlib_shutdown(void)
Definition: gwlib.c:94
int smpp_pdu_init(Cfg *cfg)
Definition: smpp_pdu.c:184
void gwlib_init(void)
Definition: gwlib.c:78
SMPP_PDU *(* handler)(ESME *, SMPP_PDU *)
Definition: drive_smpp.c:213
static time_t last_to_esme
Definition: drive_smpp.c:87

◆ quit()

static void quit ( void  )
static

Definition at line 94 of file drive_smpp.c.

References gwthread_wakeup_all(), and quitting.

Referenced by receive_smpp_thread().

95 {
96  quitting = 1;
98 }
static int quitting
Definition: drive_smpp.c:74
void gwthread_wakeup_all(void)

◆ receive_smpp_thread()

static void receive_smpp_thread ( void *  arg)
static

Definition at line 300 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, 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().

301 {
302  ESME *esme;
303  Octstr *os;
304  long len;
305  long sender_id;
306  SMPP_PDU *pdu;
307 
308  esme = arg;
309 
310  sender_id = -1;
311  len = 0;
312  while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
313  for (;;) {
314  if (len == 0) {
315  len = smpp_pdu_read_len(esme->conn);
316  if (len == -1) {
317  error(0, "Client sent garbage, closing connection.");
318  goto error;
319  } else if (len == 0) {
320  if (conn_eof(esme->conn) || conn_error(esme->conn))
321  goto error;
322  break;
323  }
324  }
325 
326  gw_assert(len > 0);
327  os = smpp_pdu_read_data(esme->conn, len);
328  if (os != NULL) {
329  len = 0;
330  pdu = smpp_pdu_unpack(NULL, os);
331  if (pdu == NULL) {
332  error(0, "PDU unpacking failed!");
333  octstr_dump(os, 0);
334  } else {
335  handle_pdu(esme, pdu);
336  smpp_pdu_destroy(pdu);
337  }
338  octstr_destroy(os);
339  } else if (conn_eof(esme->conn) || conn_error(esme->conn))
340  goto error;
341  else
342  break;
343  }
344 
345  if (!quitting && esme->receiver && sender_id == -1)
346  sender_id = gwthread_create(send_smpp_thread, esme);
347  }
348 
349 error:
350  if (sender_id != -1) {
351  quit();
352  gwthread_join(sender_id);
353  }
354  esme_destroy(esme);
355  quit();
356  debug("test.smpp", 0, "%s terminates.", __func__);
357 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
static void quit(void)
Definition: drive_smpp.c:94
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
static int quitting
Definition: drive_smpp.c:74
void gwthread_join(long thread)
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:869
int conn_eof(Connection *conn)
Definition: conn.c:705
int receiver
Definition: drive_smpp.c:104
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
Definition: smpp_pdu.c:597
static void send_smpp_thread(void *arg)
Definition: drive_smpp.c:253
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static void esme_destroy(ESME *esme)
Definition: drive_smpp.c:122
Octstr * smpp_pdu_read_data(Connection *conn, long len)
Definition: smpp_pdu.c:895
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
Definition: drive_smpp.c:228
int conn_error(Connection *conn)
Definition: conn.c:716
Connection * conn
Definition: drive_smpp.c:102

◆ send_smpp_thread()

static void send_smpp_thread ( void *  arg)
static

Definition at line 253 of file drive_smpp.c.

References ESME::conn, conn_write(), counter_increase(), counter_value(), debug(), enquire_interval, 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(), quitting, smpp_pdu_create(), smpp_pdu_destroy(), smpp_pdu_pack(), SMPP_PDU::u, and ESME::version.

Referenced by receive_smpp_thread().

254 {
255  ESME *esme;
256  Octstr *os;
257  SMPP_PDU *pdu;
258  unsigned long id;
259 
260  esme = arg;
261 
262  id = 0;
264  id = counter_increase(num_to_esme) + 1;
265  while (!quitting && counter_value(num_from_esme) + 500 < id)
266  gwthread_sleep(1.0);
267  if (quitting)
268  break;
270  pdu->u.deliver_sm.source_addr = octstr_create("456");
271  pdu->u.deliver_sm.destination_addr = octstr_create("123");
272  pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
273  if (esme->version > 0x33)
274  pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
275  os = smpp_pdu_pack(NULL, pdu);
276  conn_write(esme->conn, os);
277  octstr_destroy(os);
278  smpp_pdu_destroy(pdu);
279  if (first_to_esme == (time_t) -1)
280  time(&first_to_esme);
281  debug("test.smpp", 0, "Delivered SMS %ld of %ld to bearerbox via SMPP.",
282  id, max_to_esme);
283 
284  if ((id % enquire_interval) == 0) {
286  os = smpp_pdu_pack(NULL, pdu);
287  conn_write(esme->conn, os);
288  octstr_destroy(os);
289  smpp_pdu_destroy(pdu);
290  debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
291  }
292  }
293  time(&last_to_esme);
294  if (id == max_to_esme)
295  info(0, "All messages sent to ESME.");
296  debug("test.smpp", 0, "%s terminates.", __func__);
297 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void info(int err, const char *fmt,...)
Definition: log.c:672
static long max_to_esme
Definition: drive_smpp.c:81
static int quitting
Definition: drive_smpp.c:74
static Counter * num_from_esme
Definition: drive_smpp.c:84
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
long version
Definition: drive_smpp.c:105
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
static long enquire_interval
Definition: drive_smpp.c:91
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
static Counter * num_to_esme
Definition: drive_smpp.c:80
static time_t first_to_esme
Definition: drive_smpp.c:86
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
void gwthread_sleep(double seconds)
static Counter * message_id_counter
Definition: drive_smpp.c:77
union SMPP_PDU::@15 u
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Connection * conn
Definition: drive_smpp.c:102
static time_t last_to_esme
Definition: drive_smpp.c:87
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ smsbox_thread()

static void smsbox_thread ( void *  arg)
static

Definition at line 360 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, max_to_esme, msg, 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, and quitting.

Referenced by accept_thread().

361 {
362  Connection *conn;
363  Msg *msg;
364  Octstr *os;
365  Octstr *reply_msg;
366  unsigned long count;
367 
368  msg = msg_create(sms);
369  msg->sms.sender = octstr_create("123");
370  msg->sms.receiver = octstr_create("456");
371  msg->sms.msgdata = octstr_create("hello world");
372  reply_msg = msg_pack(msg);
373  msg_destroy(msg);
374 
375  gwthread_sleep(1.0);
377  if (conn == NULL) {
378  gwthread_sleep(2.0);
380  if (conn == NULL)
381  panic(0, "Couldn't connect to bearerbox as smsbox");
382  }
383 
384  while (!quitting && conn_wait(conn, -1.0) != -1) {
385  for (;;) {
386  os = conn_read_withlen(conn);
387  if (os == NULL) {
388  if (conn_eof(conn) || conn_error(conn))
389  goto error;
390  break;
391  }
392 
393  msg = msg_unpack(os);
394  if (msg == NULL || msg->type == wdp_datagram)
395  error(0, "Bearerbox sent garbage to smsbox");
396 
397  if (msg->type == sms) {
398  if (first_from_bb == (time_t) -1)
399  time(&first_from_bb);
401  debug("test.smpp", 0,
402  "Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
403  count, octstr_get_cstr(msg->sms.msgdata));
404  if (count == max_to_esme)
405  info(0, "Bearerbox has sent all messages to smsbox.");
406  conn_write_withlen(conn, reply_msg);
408  }
409  msg_destroy(msg);
410  octstr_destroy(os);
411  time(&last_to_bb);
412  }
413  }
414 
415 error:
416  conn_destroy(conn);
417  octstr_destroy(reply_msg);
418  debug("test.smpp", 0, "%s terminates.", __func__);
419 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static long max_to_esme
Definition: drive_smpp.c:81
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:496
static time_t last_to_bb
Definition: drive_smpp.c:90
static int port_for_smsbox
Definition: drive_smpp.c:79
#define msg_unpack(os)
Definition: msg.h:183
static int quitting
Definition: drive_smpp.c:74
static time_t first_from_bb
Definition: drive_smpp.c:89
#define msg_create(type)
Definition: msg.h:136
static Counter * num_from_bearerbox
Definition: drive_smpp.c:82
int conn_eof(Connection *conn)
Definition: conn.c:705
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Definition: msg.h:79
void conn_destroy(Connection *conn)
Definition: conn.c:627
static Counter * num_to_bearerbox
Definition: drive_smpp.c:83
void msg_destroy(Msg *msg)
Definition: msg.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
void gwthread_sleep(double seconds)
Octstr * conn_read_withlen(Connection *conn)
Definition: conn.c:1169
int conn_write_withlen(Connection *conn, Octstr *data)
Definition: conn.c:1075
static Octstr * bearerbox_host
Definition: drive_smpp.c:78
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define panic
Definition: log.h:87
Octstr * msg_pack(Msg *msg)
Definition: msg.c:181
int conn_error(Connection *conn)
Definition: conn.c:716
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

Variable Documentation

◆ bearerbox_host

Octstr* bearerbox_host
static

Definition at line 78 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ enquire_interval

long enquire_interval = 1
static

Definition at line 91 of file drive_smpp.c.

Referenced by send_smpp_thread().

◆ first_from_bb

time_t first_from_bb = (time_t) -1
static

Definition at line 89 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ first_to_esme

time_t first_to_esme = (time_t) -1
static

Definition at line 86 of file drive_smpp.c.

Referenced by main(), and send_smpp_thread().

◆ handler

SMPP_PDU*(* handler) (ESME *, SMPP_PDU *)

Definition at line 213 of file drive_smpp.c.

Referenced by charset_from_utf8(), charset_to_utf8(), and main().

◆ handlers

struct { ... } handlers[]
Initial value:
= {
#define HANDLER(name)
}

Referenced by handle_pdu().

◆ last_from_esme

time_t last_from_esme = (time_t) -1
static

Definition at line 88 of file drive_smpp.c.

Referenced by handle_submit_sm(), and main().

◆ last_to_bb

time_t last_to_bb = (time_t) -1
static

Definition at line 90 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ last_to_esme

time_t last_to_esme = (time_t) -1
static

Definition at line 87 of file drive_smpp.c.

Referenced by main(), and send_smpp_thread().

◆ max_to_esme

long max_to_esme
static

Definition at line 81 of file drive_smpp.c.

Referenced by handle_submit_sm(), main(), send_smpp_thread(), and smsbox_thread().

◆ message_id_counter

Counter* message_id_counter
static

Definition at line 77 of file drive_smpp.c.

Referenced by handle_submit_sm(), main(), and send_smpp_thread().

◆ num_from_bearerbox

Counter* num_from_bearerbox
static

Definition at line 82 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ num_from_esme

Counter* num_from_esme
static

Definition at line 84 of file drive_smpp.c.

Referenced by handle_submit_sm(), main(), and send_smpp_thread().

◆ num_handlers

int num_handlers = sizeof(handlers) / sizeof(handlers[0])
static

Definition at line 225 of file drive_smpp.c.

Referenced by handle_pdu().

◆ num_to_bearerbox

Counter* num_to_bearerbox
static

Definition at line 83 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ num_to_esme

Counter* num_to_esme
static

Definition at line 80 of file drive_smpp.c.

Referenced by main(), and send_smpp_thread().

◆ port_for_smsbox

int port_for_smsbox
static

Definition at line 79 of file drive_smpp.c.

Referenced by main(), and smsbox_thread().

◆ quitting

int quitting = 0
static

Definition at line 74 of file drive_smpp.c.

Referenced by quit(), receive_smpp_thread(), send_smpp_thread(), and smsbox_thread().

◆ smsc_source_addr

Octstr* smsc_source_addr
static

Definition at line 76 of file drive_smpp.c.

Referenced by main().

◆ smsc_system_id

Octstr* smsc_system_id
static

Definition at line 75 of file drive_smpp.c.

Referenced by handle_bind_receiver(), handle_bind_transmitter(), and main().

◆ start_time

time_t start_time = (time_t) -1
static

Definition at line 85 of file drive_smpp.c.

Referenced by accept_thread(), and main().

◆ type

unsigned long type

Definition at line 212 of file drive_smpp.c.

Referenced by handle_pdu().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.