112 fprintf(f,
"%d\n", (
int)getpid());
147 unsigned long total_s, total_f, total_ft, total_b, total_o;
150 total_s = total_f = total_ft = total_b = total_o = 0;
151 start = t = time(NULL);
161 else if (
msg == NULL)
165 debug(
"msg", 0,
"Received message from bearerbox:");
172 info(0,
"Bearerbox told us to die");
181 switch (
msg->ack.nack) {
197 warning(0,
"Received other message than ack/admin, ignoring!");
202 secs = difftime(time(NULL),
start);
203 info(0,
"Received ACKs: %ld success, %ld failed, %ld failed temporarly, %ld queued, %ld other in %ld seconds " 204 "(%.2f per second)", total_s, total_f, total_ft, total_b, total_o, secs,
205 (
float)(total_s+total_f+total_ft+total_b) / secs);
222 debug(
"msg", 0,
"Sending message to bearerbox:");
233 info(0,
"Usage: mtbatch [options] content-file receivers-file ...");
234 info(0,
"where options are:");
235 info(0,
"-v number");
236 info(0,
" set log level for stderr logging");
238 info(0,
" defines the host of bearerbox (default: localhost)");
240 info(0,
" the smsbox port to connect to (default: 13001)");
242 info(0,
" inidicator to use SSL for bearerbox connection (default: no)");
243 info(0,
"-i smsbox-id");
244 info(0,
" defines the smsbox-id to be used for bearerbox connection (default: none)");
246 info(0,
" indicator to not use smsbox-id in messages send to bearerbox (default: yes)");
247 info(0,
"-f sender");
248 info(0,
" which sender address should be used");
249 info(0,
"-D dlr-mask");
250 info(0,
" defines the dlr-mask");
251 info(0,
"-u dlr-url");
252 info(0,
" defines the dlr-url");
253 info(0,
"-n service");
254 info(0,
" defines which service name should be logged (default: none)");
255 info(0,
"-a account");
256 info(0,
" defines which account name should be logged (default: none)");
257 info(0,
"-d seconds");
258 info(0,
" delay between message sending to bearerbox (default: 0)");
259 info(0,
"-r smsc-id");
260 info(0,
" use a specific route for the MT traffic");
261 info(0,
"-M meta-data");
262 info(0,
" defines the meta-data");
263 info(0,
"-c coding (0: UTF-8, 1: binary, 2: UCS-2; default: 0)");
264 info(0,
" defines the coding");
265 info(0,
"-C charset (iconv name; default: UTF-8");
266 info(0,
" defines which character encoding is used in content-file");
268 info(0,
" indicator to dump messages exchanged with bearebrox (default: no)");
280 panic(0,
"Can not read content file `%s'.",
287 info(0,
"SMS message (binary), coding 1 (DC_8BIT):");
298 error(0,
"Failed to convert content from %s to UTF-8, will leave as is.",
304 info(0,
"SMS message (UTF-8), coding 0 (DC_7BIT):");
316 error(0,
"Failed to convert content from %s to UTF-16BE (Unicode), will leave as is.",
321 info(0,
"SMS message (UTF-16BE, Unicode), coding 2 (DCS_UCS2):");
331 info(0,
"Loading receiver list. This may take a while...");
333 if (receivers == NULL)
334 panic(0,
"Can not read receivers file `%s'.",
340 panic(0,
"Receiver file seems empty!");
342 info(0,
"Receivers file `%s' contains %ld destination address(es).",
350 return (isdigit(c) || c ==
'+');
356 unsigned long linerr = 0;
357 unsigned long lineno = 0;
359 unsigned long msg_count;
376 tmsg->sms.coding =
coding;
399 debug(
"sms", 0,
"Message length %ld octets, will send %ld concat parts for each message.",
417 info(0,
"Failed to send message at line <%ld> for receiver `%s' to bearerbox.",
424 error(0,
"Receiver `%s' at line <%ld> contains non-MSISDN characters, discarded!",
429 info(0,
"Processed batch of %ld messages with %ld send errors.", lineno, linerr);
434 int main(
int argc,
char **argv)
437 unsigned long sended = 0;
446 while ((opt =
getopt(argc, argv,
"hv:b:p:si:xn:a:f:D:u:d:r:M:c:C:m")) != EOF) {
502 error(0,
"Invalid option %c", opt);
504 panic(0,
"Stopping.");
515 panic(0,
"Sender address not specified. Use option -f to specify sender address.");
518 panic(0,
"dlr-url address OR dlr-mask not specified. Use option -D or -u to specify dlr values");
void msg_dump(Msg *msg, int level)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
Msg * msg_duplicate(Msg *msg)
void gwthread_join_all(void)
static unsigned long run_batch(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
void counter_destroy(Counter *counter)
static void write_pid_file(void)
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
long gwlist_len(List *list)
int read_from_bearerbox(Msg **msg, double seconds)
static void identify_to_bearerbox(void)
#define octstr_get_cstr(ostr)
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)
unsigned long counter_increase(Counter *counter)
static void read_messages_from_bearerbox(void *arg)
int getopt(int argc, char **argv, char *opts)
static int send_message(Msg *msg)
void msg_destroy_item(void *msg)
Octstr * octstr_imm(const char *cstr)
static Octstr * smsbox_id
Counter * counter_create(void)
void log_set_output_level(enum output_level level)
int main(int argc, char **argv)
void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
#define octstr_duplicate(ostr)
#define octstr_dump(ostr, level,...)
void msg_destroy(Msg *msg)
void warning(int err, const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
unsigned long counter_value(Counter *counter)
void gwthread_sleep(double seconds)
static void init_batch(Octstr *cfilename, Octstr *rfilename)
int deliver_to_bearerbox(Msg *msg)
Octstr * octstr_read_file(const char *filename)
void octstr_strip_crlfs(Octstr *text)
void report_versions(const char *boxname)
long octstr_len(const Octstr *ostr)
void write_to_bearerbox(Msg *pmsg)
void * gwlist_consume(List *list)
void debug(const char *place, int err, const char *fmt,...)
void gwlib_shutdown(void)
#define DLR_IS_ENABLED(dlr)
List * octstr_split(const Octstr *os, const Octstr *sep)
static int gw_ismsisdnchar(int c)
static XMLRPCDocument * msg
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)