00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include <string.h>
00072 #include <unistd.h>
00073 #include <signal.h>
00074
00075 #include "gwlib/gwlib.h"
00076
00077 #include "msg.h"
00078 #include "sms.h"
00079 #include "bb.h"
00080 #include "shared.h"
00081 #include "heartbeat.h"
00082
00083 static char *pid_file;
00084 static Octstr *smsbox_id = NULL;
00085 static Octstr *content = NULL;
00086 static List *lines = NULL;
00087 static Octstr *bb_host;
00088 static long bb_port;
00089 static int bb_ssl;
00090 static Octstr *service = NULL;
00091 static Octstr *account = NULL;
00092 static Octstr *from = NULL;
00093 static Octstr *smsc_id = NULL;
00094 static long sms_max_length = MAX_SMS_OCTETS;
00095 static double delay = 0;
00096
00097
00098 static void write_pid_file(void) {
00099 FILE *f;
00100
00101 if (pid_file != NULL) {
00102 f = fopen(pid_file, "w");
00103 fprintf(f, "%d\n", (int)getpid());
00104 fclose(f);
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 static void identify_to_bearerbox(void)
00119 {
00120 Msg *msg;
00121
00122 msg = msg_create(admin);
00123 msg->admin.command = cmd_identify;
00124 msg->admin.boxc_id = octstr_duplicate(smsbox_id);
00125 write_to_bearerbox(msg);
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 static void read_messages_from_bearerbox(void *arg)
00135 {
00136 time_t start, t;
00137 unsigned long secs;
00138 unsigned long total_s, total_f, total_ft, total_b;
00139 Msg *msg;
00140
00141 total_s = total_f = total_ft = total_b = 0;
00142 start = t = time(NULL);
00143 while (program_status != shutting_down) {
00144 int ret;
00145
00146 ret = read_from_bearerbox(&msg, INFINITE_TIME);
00147 if (ret == -1)
00148 break;
00149 else if (ret == 1)
00150 continue;
00151 else if (msg == NULL)
00152 break;
00153
00154 if (msg_type(msg) == admin) {
00155 if (msg->admin.command == cmd_shutdown ||
00156 msg->admin.command == cmd_restart) {
00157 info(0, "Bearerbox told us to die");
00158 program_status = shutting_down;
00159 }
00160
00161
00162
00163 msg_destroy(msg);
00164 } else if (msg_type(msg) == ack) {
00165 switch (msg->ack.nack) {
00166 case ack_success:
00167 total_s++;
00168 break;
00169 case ack_failed:
00170 total_f++;
00171 break;
00172 case ack_failed_tmp:
00173 total_ft++;
00174 break;
00175 case ack_buffered:
00176 total_b++;
00177 break;
00178 }
00179 msg_destroy(msg);
00180 } else {
00181 warning(0, "Received other message than sms/admin, ignoring!");
00182 msg_destroy(msg);
00183 }
00184 }
00185 secs = difftime(time(NULL), start);
00186 info(0, "Received acks: %ld success, %ld failed, %ld failed temporarly, %ld queued in %ld seconds "
00187 "(%.2f per second)", total_s, total_f, total_ft, total_b, secs,
00188 (float)(total_s+total_f+total_ft+total_b) / secs);
00189 }
00190
00191
00192
00193
00194
00195
00196 static int send_message(Msg *msg)
00197 {
00198 unsigned long msg_count;
00199 List *list;
00200 Msg *part;
00201
00202 gw_assert(msg != NULL);
00203 gw_assert(msg_type(msg) == sms);
00204
00205
00206
00207
00208
00209
00210 if (smsbox_id != NULL) {
00211 msg->sms.boxc_id = octstr_duplicate(smsbox_id);
00212 }
00213
00214 list = sms_split(msg, NULL, NULL, NULL, NULL, 1, 0, 100, sms_max_length);
00215 msg_count = gwlist_len(list);
00216
00217 debug("sms", 0, "message length %ld, sending %ld messages",
00218 octstr_len(msg->sms.msgdata), msg_count);
00219
00220 while ((part = gwlist_extract_first(list)) != NULL) {
00221
00222 if (delay > 0)
00223 gwthread_sleep(delay);
00224
00225
00226 if (deliver_to_bearerbox(part) != 0)
00227 return -1;
00228
00229 }
00230 gwlist_destroy(list, NULL);
00231
00232 return msg_count;
00233 }
00234
00235
00236 static void help(void)
00237 {
00238 info(0, "Usage: mtbatch [options] content-file receivers-file ...");
00239 info(0, "where options are:");
00240 info(0, "-v number");
00241 info(0, " set log level for stderr logging");
00242 info(0, "-b host");
00243 info(0, " defines the host of bearerbox (default: localhost)");
00244 info(0, "-p port");
00245 info(0, " the smsbox port to connect to (default: 13002)");
00246 info(0, "-s");
00247 info(0, " inidicatr to use SSL for bearerbox connection (default: no)");
00248 info(0, "-i smsbox-id");
00249 info(0, " defines the smsbox-id to be used for bearerbox connection (default: none)");
00250 info(0, "-f sender");
00251 info(0, " which sender address should be used");
00252 info(0, "-n service");
00253 info(0, " defines which service name should be logged (default: none)");
00254 info(0, "-a account");
00255 info(0, " defines which account name should be logged (default: none)");
00256 info(0, "-d seconds");
00257 info(0, " delay between message sending to bearerbox (default: 0)");
00258 info(0, "-r smsc-id");
00259 info(0, " use a specific route for the MT traffic");
00260 }
00261
00262 static void init_batch(Octstr *cfilename, Octstr *rfilename)
00263 {
00264 Octstr *receivers;
00265 long lineno = 0;
00266
00267 content = octstr_read_file(octstr_get_cstr(cfilename));
00268 octstr_strip_crlfs(content);
00269 if (content == NULL)
00270 panic(0,"Can not read content file `%s'.",
00271 octstr_get_cstr(cfilename));
00272 info(0,"SMS-Text: <%s>", octstr_get_cstr(content));
00273
00274 info(0,"Loading receiver list. This may take a while...");
00275 receivers = octstr_read_file(octstr_get_cstr(rfilename));
00276 if (receivers == NULL)
00277 panic(0,"Can not read receivers file `%s'.",
00278 octstr_get_cstr(rfilename));
00279
00280 lines = octstr_split(receivers, octstr_imm("\n"));
00281 lineno = gwlist_len(lines);
00282 if (lineno <= 0)
00283 panic(0,"Receiver file seems empty!");
00284
00285 info(0,"Receivers file `%s' contains %ld destination numbers.",
00286 octstr_get_cstr(rfilename), lineno);
00287 }
00288
00289 static void run_batch(void)
00290 {
00291 Octstr *no;
00292 unsigned long lineno = 0;
00293
00294 while ((no = gwlist_consume(lines)) != NULL) {
00295 if (octstr_check_range(no, 0, 256, gw_isdigit)) {
00296 Msg *msg;
00297
00298 lineno++;
00299
00300 msg = msg_create(sms);
00301
00302 msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
00303 msg->sms.service = service ? octstr_duplicate(service) : NULL;
00304 msg->sms.sms_type = mt_push;
00305 msg->sms.sender = octstr_duplicate(from);
00306 msg->sms.receiver = octstr_duplicate(no);
00307 msg->sms.account = account ? octstr_duplicate(account) : NULL;
00308 msg->sms.msgdata = content ? octstr_duplicate(content) : octstr_create("");
00309 msg->sms.udhdata = octstr_create("");
00310 msg->sms.coding = DC_7BIT;
00311
00312 if (send_message(msg) < 0) {
00313 panic(0,"Failed to send message at line <%ld> for receiver `%s' to bearerbox.",
00314 lineno, octstr_get_cstr(no));
00315 }
00316 msg_destroy(msg);
00317 octstr_destroy(no);
00318 }
00319 }
00320 }
00321
00322 int main(int argc, char **argv)
00323 {
00324 int opt;
00325 Octstr *cf, *rf;
00326
00327 gwlib_init();
00328
00329 bb_host = octstr_create("localhost");
00330 bb_port = 13001;
00331 bb_ssl = 0;
00332
00333 while ((opt = getopt(argc, argv, "hv:b:p:si:n:a:f:d:r:")) != EOF) {
00334 switch (opt) {
00335 case 'v':
00336 log_set_output_level(atoi(optarg));
00337 break;
00338 case 'b':
00339 octstr_destroy(bb_host);
00340 bb_host = octstr_create(optarg);
00341 break;
00342 case 'p':
00343 bb_port = atoi(optarg);
00344 break;
00345 case 's':
00346 bb_ssl = 1;
00347 break;
00348 case 'i':
00349 smsbox_id = octstr_create(optarg);
00350 break;
00351 case 'n':
00352 service = octstr_create(optarg);
00353 break;
00354 case 'a':
00355 account = octstr_create(optarg);
00356 break;
00357 case 'f':
00358 from = octstr_create(optarg);
00359 break;
00360 case 'd':
00361 delay = atof(optarg);
00362 break;
00363 case 'r':
00364 smsc_id = octstr_create(optarg);
00365 break;
00366 case '?':
00367 default:
00368 error(0, "Invalid option %c", opt);
00369 help();
00370 panic(0, "Stopping.");
00371 }
00372 }
00373
00374 if (optind == argc || argc-optind < 2) {
00375 help();
00376 exit(0);
00377 }
00378
00379
00380 if (from == NULL)
00381 panic(0,"Sender address not specified. Use option -f to specify sender address.");
00382
00383 rf = octstr_create(argv[argc-1]);
00384 cf = octstr_create(argv[argc-2]);
00385
00386 report_versions("mtbatch");
00387 write_pid_file();
00388
00389 init_batch(cf, rf);
00390
00391 connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL );
00392 identify_to_bearerbox();
00393 gwthread_create(read_messages_from_bearerbox, NULL);
00394
00395 run_batch();
00396
00397 program_status = shutting_down;
00398 gwthread_join_all();
00399
00400 octstr_destroy(bb_host);
00401 octstr_destroy(smsbox_id);
00402 octstr_destroy(content);
00403 octstr_destroy(service);
00404 octstr_destroy(account);
00405 octstr_destroy(smsc_id);
00406 gwlist_destroy(lines, octstr_destroy_item);
00407
00408 gwlib_shutdown();
00409
00410 return 0;
00411 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.