Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
mtbatch.c File Reference
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "gwlib/gwlib.h"
#include "msg.h"
#include "sms.h"
#include "dlr.h"
#include "bb.h"
#include "shared.h"
#include "heartbeat.h"

Go to the source code of this file.

Functions

static void write_pid_file (void)
 
static void identify_to_bearerbox (void)
 
static void read_messages_from_bearerbox (void *arg)
 
static int send_message (Msg *msg)
 
static void help (void)
 
static void init_batch (Octstr *cfilename, Octstr *rfilename)
 
static unsigned long run_batch (void)
 
int main (int argc, char **argv)
 

Variables

static char * pid_file
 
static Octstrsmsbox_id = NULL
 
static Octstrcontent = NULL
 
static Listlines = NULL
 
static Octstrbb_host
 
static long bb_port
 
static int bb_ssl
 
static Countercounter
 
static Octstrservice = NULL
 
static Octstraccount = NULL
 
static Octstrfrom = NULL
 
static int dlr_mask = 0
 
static Octstrdlr_url = NULL
 
static Octstrsmsc_id = NULL
 
static double delay = 0
 
static int no_smsbox_id = 0
 

Function Documentation

static void help ( void  )
static

Definition at line 244 of file mtbatch.c.

References info().

Referenced by main().

245 {
246  info(0, "Usage: mtbatch [options] content-file receivers-file ...");
247  info(0, "where options are:");
248  info(0, "-v number");
249  info(0, " set log level for stderr logging");
250  info(0, "-b host");
251  info(0, " defines the host of bearerbox (default: localhost)");
252  info(0, "-p port");
253  info(0, " the smsbox port to connect to (default: 13001)");
254  info(0, "-s");
255  info(0, " inidicatr to use SSL for bearerbox connection (default: no)");
256  info(0, "-i smsbox-id");
257  info(0, " defines the smsbox-id to be used for bearerbox connection (default: none)");
258  info(0, "-x");
259  info(0, " indicator to not use smsbox-id in messages send to bearerbox (default: yes)");
260  info(0, "-f sender");
261  info(0, " which sender address should be used");
262  info(0, "-D dlr-mask");
263  info(0, " defines the dlr-mask");
264  info(0, "-u dlr-url");
265  info(0, " defines the dlr-url");
266  info(0, "-n service");
267  info(0, " defines which service name should be logged (default: none)");
268  info(0, "-a account");
269  info(0, " defines which account name should be logged (default: none)");
270  info(0, "-d seconds");
271  info(0, " delay between message sending to bearerbox (default: 0)");
272  info(0, "-r smsc-id");
273  info(0, " use a specific route for the MT traffic");
274 }
void info(int err, const char *fmt,...)
Definition: log.c:636
static void identify_to_bearerbox ( void  )
static

Definition at line 122 of file mtbatch.c.

References cmd_identify, msg, msg_create, octstr_duplicate, and write_to_bearerbox().

Referenced by main().

123 {
124  Msg *msg;
125 
126  msg = msg_create(admin);
127  msg->admin.command = cmd_identify;
128  msg->admin.boxc_id = octstr_duplicate(smsbox_id);
129  write_to_bearerbox(msg);
130 }
#define msg_create(type)
Definition: msg.h:136
static Octstr * smsbox_id
Definition: mtbatch.c:86
Definition: msg.h:79
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void init_batch ( Octstr cfilename,
Octstr rfilename 
)
static

Definition at line 276 of file mtbatch.c.

References counter_create(), gwlist_len(), info(), octstr_get_cstr, octstr_imm(), octstr_read_file(), octstr_split(), octstr_strip_crlfs(), and panic.

Referenced by main().

277 {
278  Octstr *receivers;
279  long lineno = 0;
280 
283  if (content == NULL)
284  panic(0,"Can not read content file `%s'.",
285  octstr_get_cstr(cfilename));
286  info(0,"SMS-Text: <%s>", octstr_get_cstr(content));
287 
288  info(0,"Loading receiver list. This may take a while...");
289  receivers = octstr_read_file(octstr_get_cstr(rfilename));
290  if (receivers == NULL)
291  panic(0,"Can not read receivers file `%s'.",
292  octstr_get_cstr(rfilename));
293 
294  lines = octstr_split(receivers, octstr_imm("\n"));
295  lineno = gwlist_len(lines);
296  if (lineno <= 0)
297  panic(0,"Receiver file seems empty!");
298 
299  info(0,"Receivers file `%s' contains %ld destination numbers.",
300  octstr_get_cstr(rfilename), lineno);
301 
303 }
void info(int err, const char *fmt,...)
Definition: log.c:636
long gwlist_len(List *list)
Definition: list.c:166
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static List * lines
Definition: mtbatch.c:88
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Counter * counter_create(void)
Definition: counter.c:94
Octstr * octstr_read_file(const char *filename)
Definition: octstr.c:1546
void octstr_strip_crlfs(Octstr *text)
Definition: octstr.c:1376
Definition: octstr.c:118
#define panic
Definition: log.h:87
static Counter * counter
Definition: mtbatch.c:92
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
int main ( int  argc,
char **  argv 
)

Definition at line 349 of file mtbatch.c.

References bb_port, bb_ssl, connect_to_bearerbox(), counter_destroy(), counter_value(), delay, DLR_IS_ENABLED, dlr_mask, error(), getopt(), gwlib_init(), gwlib_shutdown(), gwlist_destroy(), gwthread_create, gwthread_join_all(), gwthread_sleep(), help(), identify_to_bearerbox(), init_batch(), log_set_output_level(), no_smsbox_id, octstr_create, octstr_destroy(), octstr_destroy_item(), optarg, optind, panic, read_messages_from_bearerbox(), report_versions(), run_batch(), shutting_down, and write_pid_file().

350 {
351  int opt;
352  unsigned long sended = 0;
353  Octstr *cf, *rf;
354 
355  gwlib_init();
356 
357  bb_host = octstr_create("localhost");
358  bb_port = 13001;
359  bb_ssl = 0;
360 
361  while ((opt = getopt(argc, argv, "hv:b:p:si:xn:a:f:D:u:d:r:")) != EOF) {
362  switch (opt) {
363  case 'v':
365  break;
366  case 'b':
369  break;
370  case 'p':
371  bb_port = atoi(optarg);
372  break;
373  case 's':
374  bb_ssl = 1;
375  break;
376  case 'i':
378  break;
379  case 'x':
380  no_smsbox_id = 1;
381  break;
382  case 'n':
384  break;
385  case 'a':
387  break;
388  case 'f':
390  break;
391  case 'D':
392  dlr_mask = atoi(optarg);
393  break;
394  case 'u':
396  break;
397  case 'd':
398  delay = atof(optarg);
399  break;
400  case 'r':
402  break;
403  case '?':
404  default:
405  error(0, "Invalid option %c", opt);
406  help();
407  panic(0, "Stopping.");
408  }
409  }
410 
411  if (optind == argc || argc-optind < 2) {
412  help();
413  exit(1);
414  }
415 
416  /* check some mandatory elements */
417  if (from == NULL)
418  panic(0,"Sender address not specified. Use option -f to specify sender address.");
419 
420  if ((DLR_IS_ENABLED(dlr_mask) && dlr_url == NULL) || (!DLR_IS_ENABLED(dlr_mask) && dlr_url != NULL))
421  panic(0,"dlr-url address OR dlr-mask not specified. Use option -D or -u to specify dlr values");
422 
423  rf = octstr_create(argv[argc-1]);
424  cf = octstr_create(argv[argc-2]);
425 
426  report_versions("mtbatch");
427  write_pid_file();
428 
429  init_batch(cf, rf);
430 
431  connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
434 
435  sended = run_batch();
436 
437  /* avoid exiting before sending all msgs */
438  while (sended > counter_value(counter)) {
439  gwthread_sleep(0.1);
440  }
441 
444 
454 
455  gwlib_shutdown();
456 
457  return 0;
458 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void gwthread_join_all(void)
static unsigned long run_batch(void)
Definition: mtbatch.c:305
static Octstr * dlr_url
Definition: mtbatch.c:97
void counter_destroy(Counter *counter)
Definition: counter.c:110
static void write_pid_file(void)
Definition: mtbatch.c:102
static int bb_ssl
Definition: mtbatch.c:91
program_status
Definition: shared.h:79
static void help(void)
Definition: mtbatch.c:244
int optind
Definition: attgetopt.c:80
static void identify_to_bearerbox(void)
Definition: mtbatch.c:122
static Octstr * service
Definition: mtbatch.c:93
#define DLR_IS_ENABLED(dlr)
Definition: dlr.h:81
static List * lines
Definition: mtbatch.c:88
static void read_messages_from_bearerbox(void *arg)
Definition: mtbatch.c:138
int getopt(int argc, char **argv, char *opts)
Definition: attgetopt.c:84
static Octstr * from
Definition: mtbatch.c:95
static Octstr * smsbox_id
Definition: mtbatch.c:86
void log_set_output_level(enum output_level level)
Definition: log.c:217
void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:108
static Octstr * smsc_id
Definition: mtbatch.c:98
static Octstr * bb_host
Definition: mtbatch.c:89
static double delay
Definition: mtbatch.c:99
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
void gwthread_sleep(double seconds)
static void init_batch(Octstr *cfilename, Octstr *rfilename)
Definition: mtbatch.c:276
static long bb_port
Definition: mtbatch.c:90
void report_versions(const char *boxname)
Definition: utils.c:539
static int dlr_mask
Definition: mtbatch.c:96
Definition: octstr.c:118
char * optarg
Definition: attgetopt.c:82
#define panic
Definition: log.h:87
void gwlib_shutdown(void)
Definition: gwlib.c:94
void gwlib_init(void)
Definition: gwlib.c:78
static int no_smsbox_id
Definition: mtbatch.c:100
static Counter * counter
Definition: mtbatch.c:92
static Octstr * account
Definition: mtbatch.c:94
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void read_messages_from_bearerbox ( void *  arg)
static

Definition at line 138 of file mtbatch.c.

References ack_buffered, ack_failed, ack_failed_tmp, ack_success, cmd_restart, cmd_shutdown, counter_increase(), info(), msg, msg_destroy(), read_from_bearerbox(), shutting_down, start, and warning().

Referenced by main().

139 {
140  time_t start, t;
141  unsigned long secs;
142  unsigned long total_s, total_f, total_ft, total_b, total_o;
143  Msg *msg;
144 
145  total_s = total_f = total_ft = total_b = total_o = 0;
146  start = t = time(NULL);
147  while (program_status != shutting_down) {
148  int ret;
149 
150  /* block infinite for reading messages */
151  ret = read_from_bearerbox(&msg, 0.5);
152  if (ret == -1)
153  break;
154  else if (ret == 1) /* timeout */
155  continue;
156  else if (msg == NULL) /* just to be sure, may not happens */
157  break;
158 
159  if (msg_type(msg) == admin) {
160  if (msg->admin.command == cmd_shutdown ||
161  msg->admin.command == cmd_restart) {
162  info(0, "Bearerbox told us to die");
164  }
165  /*
166  * XXXX here should be suspend/resume, add RSN
167  */
168  msg_destroy(msg);
169  } else if (msg_type(msg) == ack) {
171  switch (msg->ack.nack) {
172  case ack_success:
173  total_s++;
174  break;
175  case ack_failed:
176  total_f++;
177  break;
178  case ack_failed_tmp:
179  total_ft++;
180  break;
181  case ack_buffered:
182  total_b++;
183  break;
184  }
185  msg_destroy(msg);
186  } else {
187  warning(0, "Received other message than ack/admin, ignoring!");
188  msg_destroy(msg);
189  total_o++;
190  }
191  }
192  secs = difftime(time(NULL), start);
193  info(0, "Received acks: %ld success, %ld failed, %ld failed temporarly, %ld queued, %ld other in %ld seconds "
194  "(%.2f per second)", total_s, total_f, total_ft, total_b, total_o, secs,
195  (float)(total_s+total_f+total_ft+total_b) / secs);
196 }
void info(int err, const char *fmt,...)
Definition: log.c:636
program_status
Definition: shared.h:79
int read_from_bearerbox(Msg **msg, double seconds)
Definition: shared.c:220
msg_type
Definition: msg.h:73
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Definition: msg.h:79
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:624
static Counter * counter
Definition: mtbatch.c:92
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int start
static unsigned long run_batch ( void  )
static

Definition at line 305 of file mtbatch.c.

References DC_7BIT, dlr_mask, error(), gw_isdigit(), gwlist_consume(), info(), msg, msg_create, msg_destroy(), mt_push, octstr_check_range(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, and send_message().

Referenced by main().

306 {
307  Octstr *no;
308  unsigned long linerr = 0;
309  unsigned long lineno = 0;
310 
311  while ((no = gwlist_consume(lines)) != NULL) {
312  if (octstr_check_range(no, 0, 256, gw_isdigit)) {
313  Msg *msg;
314 
315  lineno++;
316 
317  msg = msg_create(sms);
318 
319  msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
320  msg->sms.service = service ? octstr_duplicate(service) : NULL;
321  msg->sms.sms_type = mt_push;
322  msg->sms.sender = octstr_duplicate(from);
323  msg->sms.receiver = octstr_duplicate(no);
324  msg->sms.account = account ? octstr_duplicate(account) : NULL;
325  msg->sms.msgdata = content ? octstr_duplicate(content) : octstr_create("");
326  msg->sms.dlr_mask = dlr_mask;
327  msg->sms.dlr_url = octstr_duplicate(dlr_url);
328  msg->sms.udhdata = octstr_create("");
329  msg->sms.coding = DC_7BIT;
330 
331  if (send_message(msg) < 0) {
332  linerr++;
333  info(0,"Failed to send message at line <%ld> for receiver `%s' to bearerbox.",
334  lineno, octstr_get_cstr(no));
335  msg_destroy(msg);
336  }
337  }
338  else {
339  linerr++;
340  error(0, "Receiver `%s' at line <%ld> contains non-digit characters, discarded!",
341  octstr_get_cstr(no), lineno);
342  }
343  octstr_destroy(no);
344  }
345  info(0,"mtbatch has processed %ld messages with %ld errors.", lineno, linerr);
346  return lineno;
347 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
static Octstr * dlr_url
Definition: mtbatch.c:97
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:812
static Octstr * service
Definition: mtbatch.c:93
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static List * lines
Definition: mtbatch.c:88
static Octstr * from
Definition: mtbatch.c:95
Definition: msg.h:108
static int send_message(Msg *msg)
Definition: mtbatch.c:203
Definition: msg.h:79
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_isdigit(int c)
Definition: utils.c:988
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static int dlr_mask
Definition: mtbatch.c:96
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
static Octstr * account
Definition: mtbatch.c:94
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DC_7BIT
Definition: sms.h:110
static int send_message ( Msg msg)
static

Definition at line 203 of file mtbatch.c.

References debug(), delay, deliver_to_bearerbox(), gw_assert(), gwlist_destroy(), gwlist_len(), gwthread_sleep(), MAX_SMS_OCTETS, msg_destroy_item(), no_smsbox_id, octstr_duplicate, octstr_len(), and sms_split().

Referenced by run_batch().

204 {
205  unsigned long msg_count;
206  List *list;
207 
208  gw_assert(msg != NULL);
209  gw_assert(msg_type(msg) == sms);
210 
211  /*
212  * Encode our smsbox-id to the msg structure.
213  * This will allow bearerbox to return specific answers to the
214  * same smsbox, mainly for DLRs and SMS proxy modes.
215  *
216  * In addition the -x flag can be used to identify the mtbatch
217  * instance with an own smsbox-id, but let the normal smsbox
218  * daemons handle the DLRs coming back, as the mtbatch shuts down
219  * after all MTs have been injected. It's not meant to process
220  * the DLR messages.
221  */
222  if (no_smsbox_id == 0 && smsbox_id != NULL) {
223  msg->sms.boxc_id = octstr_duplicate(smsbox_id);
224  }
225 
226  list = sms_split(msg, NULL, NULL, NULL, NULL, 1, 0, 100, MAX_SMS_OCTETS);
227  msg_count = gwlist_len(list);
229 
230  debug("sms", 0, "message length %ld, sending %ld messages",
231  octstr_len(msg->sms.msgdata), msg_count);
232 
233  if (delay > 0)
235 
236  /* pass message to bearerbox */
237  if (deliver_to_bearerbox(msg) != 0)
238  return -1;
239 
240  return msg_count;
241 }
#define MAX_SMS_OCTETS
Definition: sms.h:129
long gwlist_len(List *list)
Definition: list.c:166
msg_type
Definition: msg.h:73
List * sms_split(Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
Definition: sms.c:309
void msg_destroy_item(void *msg)
Definition: msg.c:147
static Octstr * smsbox_id
Definition: mtbatch.c:86
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static double delay
Definition: mtbatch.c:99
gw_assert(wtls_machine->packet_to_send!=NULL)
void gwthread_sleep(double seconds)
int deliver_to_bearerbox(Msg *msg)
Definition: shared.c:166
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static int no_smsbox_id
Definition: mtbatch.c:100
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void write_pid_file ( void  )
static

Definition at line 102 of file mtbatch.c.

References pid_file.

Referenced by main().

102  {
103  FILE *f;
104 
105  if (pid_file != NULL) {
106  f = fopen(pid_file, "w");
107  fprintf(f, "%d\n", (int)getpid());
108  fclose(f);
109  }
110 }
static char * pid_file
Definition: mtbatch.c:85

Variable Documentation

Octstr* bb_host
static

Definition at line 89 of file mtbatch.c.

long bb_port
static

Definition at line 90 of file mtbatch.c.

Referenced by main().

int bb_ssl
static

Definition at line 91 of file mtbatch.c.

Referenced by main().

Counter* counter
static

Definition at line 92 of file mtbatch.c.

double delay = 0
static
int dlr_mask = 0
static

Definition at line 96 of file mtbatch.c.

Referenced by main(), and run_batch().

Octstr* dlr_url = NULL
static

Definition at line 97 of file mtbatch.c.

List* lines = NULL
static

Definition at line 88 of file mtbatch.c.

Referenced by cfg_read(), expand_file(), numhash_create(), and octstr_binary_to_base64().

int no_smsbox_id = 0
static

Definition at line 100 of file mtbatch.c.

Referenced by main(), and send_message().

char* pid_file
static

Definition at line 85 of file mtbatch.c.

Referenced by write_pid_file().

Octstr* service = NULL
static

Definition at line 93 of file mtbatch.c.

Octstr* smsbox_id = NULL
static

Definition at line 86 of file mtbatch.c.

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