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 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdlib.h>
00043 #include <unistd.h>
00044 #include <fcntl.h>
00045
00046 #include "../../sr_module.h"
00047 #include "../../error.h"
00048 #include "../../dprint.h"
00049 #include "../../ut.h"
00050 #include "../../globals.h"
00051 #include "../../mem/mem.h"
00052 #include "../../mem/shm_mem.h"
00053 #include "../../socket_info.h"
00054 #include "../../cfg/cfg_struct.h"
00055 #include "../../modules/tm/tm_load.h"
00056 #include "sms_funcs.h"
00057 #include "sms_report.h"
00058 #include "libsms_modem.h"
00059
00060
00061 MODULE_VERSION
00062
00063
00064 static int sms_init(void);
00065 static int sms_exit(void);
00066 static int sms_child_init(int);
00067 static int w_sms_send_msg(struct sip_msg*, char*, char* );
00068 static int w_sms_send_msg_to_net(struct sip_msg*, char*, char*);
00069 static int fixup_sms_send_msg_to_net(void** param, int param_no);
00070
00071
00072
00073
00074 char *networks_config = 0;
00075 char *modems_config = 0;
00076 char *links_config = 0;
00077 char *default_net_str = 0;
00078 char *domain_str = 0;
00079
00080
00081 int default_net = 0;
00082 int max_sms_parts = MAX_SMS_PARTS;
00083 str domain;
00084 int *queued_msgs = 0;
00085 int use_contact = 0;
00086 int sms_report_type = NO_REPORT;
00087
00088
00089 static cmd_export_t cmds[]={
00090 {"sms_send_msg_to_net", w_sms_send_msg_to_net, 1,
00091 fixup_sms_send_msg_to_net, REQUEST_ROUTE},
00092 {"sms_send_msg", w_sms_send_msg, 0,
00093 0, REQUEST_ROUTE},
00094 {0,0,0,0,0}
00095 };
00096
00097
00098 static param_export_t params[]={
00099 {"networks", STR_PARAM, &networks_config },
00100 {"modems", STR_PARAM, &modems_config },
00101 {"links", STR_PARAM, &links_config },
00102 {"default_net", STR_PARAM, &default_net_str },
00103 {"max_sms_parts", INT_PARAM, &max_sms_parts },
00104 {"domain", STR_PARAM, &domain_str },
00105 {"use_contact", INT_PARAM, &use_contact },
00106 {"sms_report_type", INT_PARAM, &sms_report_type },
00107 {0,0,0}
00108 };
00109
00110
00111 struct module_exports exports= {
00112 "sms",
00113 cmds,
00114 0,
00115 params,
00116
00117 sms_init,
00118 (response_function) 0,
00119 (destroy_function) sms_exit,
00120 0,
00121 (child_init_function) sms_child_init
00122 };
00123
00124
00125
00126
00127 static int fixup_sms_send_msg_to_net(void** param, int param_no)
00128 {
00129 long net_nr,i;
00130
00131 if (param_no==1) {
00132 for(net_nr=-1,i=0;i<nr_of_networks&&net_nr==-1;i++)
00133 if (!strcasecmp(networks[i].name,*param))
00134 net_nr = i;
00135 if (net_nr==-1) {
00136 LM_ERR("network \"%s\" not found in net list!\n",(char*)*param);
00137 return E_UNSPEC;
00138 } else {
00139 pkg_free(*param);
00140 *param=(void*)net_nr;
00141 return 0;
00142 }
00143 }
00144 return 0;
00145 }
00146
00147
00148
00149
00150
00151 #define eat_spaces(_p) \
00152 while( *(_p)==' ' || *(_p)=='\t' ){\
00153 (_p)++;}
00154
00155
00156
00157
00158 int set_modem_arg(struct modem *mdm, char *arg, char *arg_end)
00159 {
00160 int err, foo;
00161
00162 if (*(arg+1)!='=') {
00163 LM_ERR("invalid parameter syntax near [=]\n");
00164 goto error;
00165 }
00166 switch (*arg)
00167 {
00168 case 'd':
00169 memcpy(mdm->device,arg+2,arg_end-arg-2);
00170 mdm->device[arg_end-arg-2] = 0;
00171 break;
00172 case 'p':
00173 memcpy(mdm->pin,arg+2,arg_end-arg-2);
00174 mdm->pin[arg_end-arg-2] = 0;
00175 break;
00176 case 'm':
00177 if (!strncasecmp(arg+2,"OLD",3)
00178 && arg_end-arg-2==3) {
00179 mdm->mode = MODE_OLD;
00180 } else if (!strncasecmp(arg+2,"DIGICOM",7)
00181 && arg_end-arg-2==7) {
00182 mdm->mode = MODE_DIGICOM;
00183 } else if (!strncasecmp(arg+2,"ASCII",5)
00184 && arg_end-arg-2==5) {
00185 mdm->mode = MODE_ASCII;
00186 } else if (!strncasecmp(arg+2,"NEW",3)
00187 && arg_end-arg-2==3) {
00188 mdm->mode = MODE_NEW;
00189 } else {
00190 LM_ERR("invalid value \"%.*s\" for param [m]\n",
00191 (int)(arg_end-arg-2),arg+2);
00192 goto error;
00193 }
00194 break;
00195 case 'c':
00196 memcpy(mdm->smsc,arg+2,arg_end-arg-2);
00197 mdm->smsc[arg_end-arg-2] = 0;
00198 break;
00199 case 'r':
00200 foo=str2s(arg+2,arg_end-arg-2,&err);
00201 if (err) {
00202 LM_ERR("failed to convert [r] arg to integer!\n");
00203 goto error;
00204 }
00205 mdm->retry = foo;
00206 break;
00207 case 'l':
00208 foo=str2s(arg+2,arg_end-arg-2,&err);
00209 if (err) {
00210 LM_ERR("failed to convert [l] arg to integer!\n");
00211 goto error;
00212 }
00213 mdm->looping_interval = foo;
00214 break;
00215 case 'b':
00216 foo=str2s(arg+2,arg_end-arg-2,&err);
00217 if (err) {
00218 LM_ERR("failed to convert [b] arg to integer!\n");
00219 goto error;
00220 }
00221 switch (foo) {
00222 case 300: foo=B300; break;
00223 case 1200: foo=B1200; break;
00224 case 2400: foo=B2400; break;
00225 case 9600: foo=B9600; break;
00226 case 19200: foo=B19200; break;
00227 case 38400: foo=B38400; break;
00228 case 57600: foo=B57600; break;
00229 default:
00230 LM_ERR("unsupported value %d for [b] arg!\n",foo);
00231 goto error;
00232 }
00233 mdm->baudrate = foo;
00234 break;
00235 case 's':
00236 foo=str2s(arg+2,arg_end-arg-2,&err);
00237 if (err) {
00238 LM_WARN("cannot convert [s] arg to integer!, assume default mode s=%d (SCAN)\n",
00239 SMS_BODY_SCAN);
00240 foo = SMS_BODY_SCAN;
00241 }
00242 switch (foo) {
00243 case SMS_BODY_SCAN:
00244 case SMS_BODY_SCAN_NO:
00245 case SMS_BODY_SCAN_MIX:
00246 break;
00247 default:
00248 LM_WARN("unsupported value s=%d for [s] arg!, assume default mode s=%d (SCAN)\n",
00249 foo,SMS_BODY_SCAN);
00250 foo = SMS_BODY_SCAN;
00251 }
00252 mdm->scan = foo;
00253 break;
00254 case 't':
00255 memcpy(mdm->to,arg+2,arg_end-arg-2);
00256 mdm->to[arg_end-arg-2] = 0;
00257 break;
00258 default:
00259 LM_ERR("unknown param name [%c]\n",*arg);
00260 goto error;
00261 }
00262
00263 return 1;
00264 error:
00265 return -1;
00266 }
00267
00268
00269
00270
00271 int set_network_arg(struct network *net, char *arg, char *arg_end)
00272 {
00273 int err,foo;
00274
00275 if (*(arg+1)!='=') {
00276 LM_ERR("invalid parameter syntax near [=]\n");
00277 goto error;
00278 }
00279 switch (*arg)
00280 {
00281 case 'm':
00282 foo=str2s(arg+2,arg_end-arg-2,&err);
00283 if (err) {
00284 LM_ERR("cannot convert [m] arg to integer!\n");
00285 goto error;
00286 }
00287 net->max_sms_per_call = foo;
00288 break;
00289 default:
00290 LM_ERR("unknown param name [%c]\n",*arg);
00291 goto error;
00292 }
00293
00294 return 1;
00295 error:
00296 return -1;
00297 }
00298
00299
00300
00301
00302 int parse_config_lines(void)
00303 {
00304 char *p,*start;
00305 int i, k, step;
00306 int mdm_nr, net_nr;
00307
00308 nr_of_networks = 0;
00309 nr_of_modems = 0;
00310
00311 step = 1;
00312
00313 if ( (p = modems_config)==0) {
00314 LM_ERR("param \"modems\" not found\n");
00315 goto error;
00316 }
00317 while (*p)
00318 {
00319 eat_spaces(p);
00320
00321 start = p;
00322 while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
00323 p++;
00324 if ( p==start || *p==0 )
00325 goto parse_error;
00326 memcpy(modems[nr_of_modems].name, start, p-start);
00327 modems[nr_of_modems].name[p-start] = 0;
00328 modems[nr_of_modems].smsc[0] = 0;
00329 modems[nr_of_modems].device[0] = 0;
00330 modems[nr_of_modems].pin[0] = 0;
00331 modems[nr_of_modems].mode = MODE_NEW;
00332 modems[nr_of_modems].retry = 4;
00333 modems[nr_of_modems].looping_interval = 20;
00334 modems[nr_of_modems].baudrate = B9600;
00335 modems[nr_of_modems].scan = SMS_BODY_SCAN;
00336 modems[nr_of_modems].to[0] = 0;
00337 memset(modems[nr_of_modems].net_list,0XFF,
00338 sizeof(modems[nr_of_modems].net_list) );
00339
00340 eat_spaces(p);
00341 if (*p!='[')
00342 goto parse_error;
00343 p++;
00344 while (*p!=']')
00345 {
00346 eat_spaces(p);
00347 start = p;
00348 while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
00349 p++;
00350 if ( p==start || *p==0 )
00351 goto parse_error;
00352 if (set_modem_arg( &(modems[nr_of_modems]), start, p)==-1)
00353 goto error;
00354 eat_spaces(p);
00355 if (*p==';') {
00356 p++;
00357 eat_spaces(p);
00358 }
00359 }
00360 if (*p!=']')
00361 goto parse_error;
00362 p++;
00363
00364 if (modems[nr_of_modems].device[0]==0) {
00365 LM_ERR("modem %s has no device associated\n",
00366 modems[nr_of_modems].name);
00367 goto error;
00368 }
00369 if (modems[nr_of_modems].smsc[0]==0) {
00370 LM_WARN("modem %s has no sms center associated -> using"
00371 " the default one from modem\n",modems[nr_of_modems].name);
00372 }
00373 nr_of_modems++;
00374 eat_spaces(p);
00375 if (*p==';') {
00376 p++;
00377 eat_spaces(p);
00378 }
00379 }
00380 if (nr_of_modems==0)
00381 {
00382 LM_ERR("failed to parse config modems - no modem found!\n");
00383 goto error;
00384 }
00385
00386 step++;
00387
00388 if ( (p = networks_config)==0) {
00389 LM_ERR("param \"networks\" not found\n");
00390 goto error;
00391 }
00392 while (*p)
00393 {
00394 eat_spaces(p);
00395
00396 start = p;
00397 while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
00398 p++;
00399 if ( p==start || *p==0 )
00400 goto parse_error;
00401 memcpy(networks[nr_of_networks].name, start, p-start);
00402 networks[nr_of_networks].name[p-start] = 0;
00403 networks[nr_of_networks].max_sms_per_call = 10;
00404
00405 eat_spaces(p);
00406 if (*p!='[')
00407 goto parse_error;
00408 p++;
00409 while (*p!=']')
00410 {
00411 eat_spaces(p);
00412 start = p;
00413 while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
00414 p++;
00415 if ( p==start || *p==0 )
00416 goto parse_error;
00417 if (set_network_arg( &(networks[nr_of_networks]), start, p)==-1)
00418 goto error;
00419 eat_spaces(p);
00420 if (*p==';') {
00421 p++;
00422 eat_spaces(p);
00423 }
00424 }
00425 if (*p!=']')
00426 goto parse_error;
00427 p++;
00428
00429 nr_of_networks++;
00430 eat_spaces(p);
00431 if (*p==';')
00432 p++;
00433 eat_spaces(p);
00434 }
00435 if (nr_of_networks==0)
00436 {
00437 LM_ERR("no network found!\n");
00438 goto error;
00439 }
00440
00441 step++;
00442
00443 if ( (p = links_config)==0) {
00444 LM_ERR("param \"links\" not found\n");
00445 goto error;
00446 }
00447 while (*p)
00448 {
00449 eat_spaces(p);
00450
00451 start = p;
00452 while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
00453 p++;
00454 if ( p==start || *p==0 )
00455 goto parse_error;
00456
00457 for(mdm_nr=-1,i=0;i<nr_of_modems && mdm_nr==-1;i++)
00458 if (!strncasecmp(modems[i].name,start,p-start)&&
00459 modems[i].name[p-start]==0)
00460 mdm_nr = i;
00461 if (mdm_nr==-1) {
00462 LM_ERR("unknown modem %.*s \n,",(int)(p-start), start);
00463 goto error;
00464 }
00465
00466 eat_spaces(p);
00467 if (*p!='[')
00468 goto parse_error;
00469 p++;
00470 k=0;
00471 while (*p!=']')
00472 {
00473 eat_spaces(p);
00474 start = p;
00475 while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
00476 p++;
00477 if ( p==start || *p==0 )
00478 goto parse_error;
00479
00480 for(net_nr=-1,i=0;i<nr_of_networks&&net_nr==-1;i++)
00481 if (!strncasecmp(networks[i].name,start,p-start)
00482 && networks[i].name[p-start]==0)
00483 net_nr = i;
00484 if (net_nr==-1) {
00485 LM_ERR("associated net <%.*s> not found in net list\n",
00486 (int)(p-start), start);
00487 goto error;
00488 }
00489 LM_DBG("linking net \"%s\" to modem \"%s\" on pos %d.\n",
00490 networks[net_nr].name,modems[mdm_nr].name,k);
00491 modems[mdm_nr].net_list[k++]=net_nr;
00492 eat_spaces(p);
00493 if (*p==';') {
00494 p++;
00495 eat_spaces(p);
00496 }
00497 }
00498 if (*p!=']')
00499 goto parse_error;
00500 p++;
00501
00502 eat_spaces(p);
00503 if (*p==';') {
00504 p++;
00505 eat_spaces(p);
00506 }
00507 }
00508
00509
00510 if (default_net_str) {
00511 for(net_nr=-1,i=0;i<nr_of_networks&&net_nr==-1;i++)
00512 if (!strcasecmp(networks[i].name,default_net_str))
00513 net_nr = i;
00514 if (net_nr==-1) {
00515 LM_ERR("network \"%s\" not found in net list!\n",default_net_str);
00516 goto error;
00517 }
00518 default_net = net_nr;
00519 }
00520
00521 return 0;
00522 parse_error:
00523 LM_ERR("SMS %s config: parse error before chr %d [%.*s]\n",
00524 (step==1)?"modems":(step==2?"networks":"links"),
00525 (int)(p - ((step==1)?modems_config:
00526 (step==2?networks_config:links_config))),
00527 (*p==0)?4:1,(*p==0)?"NULL":p );
00528 error:
00529 return -1;
00530 }
00531
00532
00533
00534
00535 int global_init(void)
00536 {
00537 load_tm_f load_tm;
00538 int i, net_pipe[2], foo;
00539 char *p;
00540 struct socket_info* si;
00541
00542
00543 if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {
00544 LM_ERR("cannot import load_tm\n");
00545 goto error;
00546 }
00547
00548 if (load_tm( &tmb )==-1)
00549 goto error;
00550
00551
00552 if (domain_str) {
00553 domain.s = domain_str;
00554 domain.len = strlen(domain_str);
00555 } else {
00556 si=get_first_socket();
00557 if (si==0){
00558 LM_CRIT("null listen socket list\n");
00559 goto error;
00560 }
00561
00562 i = (si->port_no_str.len && si->port_no!=5060);
00563 domain.len = si->name.len + i*(si->port_no_str.len+1);
00564 domain.s = (char*)pkg_malloc(domain.len);
00565 if (!domain.s) {
00566 LM_ERR("no free pkg memory!\n");
00567 goto error;
00568 }
00569 p = domain.s;
00570 memcpy(p,si->name.s,si->name.len);
00571 p += si->name.len;
00572 if (i) {
00573 *p=':'; p++;
00574 memcpy(p,si->port_no_str.s, si->port_no_str.len);
00575 p += si->port_no_str.len;
00576 }
00577 }
00578
00579
00580 for(i=0;i<nr_of_networks;i++)
00581 {
00582
00583 if (pipe(net_pipe)==-1) {
00584 LM_ERR("failed to create pipe!\n");
00585 goto error;
00586 }
00587 networks[i].pipe_out = net_pipe[0];
00588 net_pipes_in[i] = net_pipe[1];
00589
00590 if ((foo=fcntl(net_pipe[0],F_GETFL,0))<0) {
00591 LM_ERR("failed to get flag for pipe - fcntl\n");
00592 goto error;
00593 }
00594 foo |= O_NONBLOCK;
00595 if (fcntl(net_pipe[0],F_SETFL,foo)<0) {
00596 LM_ERR("failed to set flag for pipe - fcntl\n");
00597 goto error;
00598 }
00599 }
00600
00601
00602 if (sms_report_type!=NO_REPORT && !init_report_queue()) {
00603 LM_ERR("cannot get shm memory!\n");
00604 goto error;
00605 }
00606
00607
00608 queued_msgs = (int*)shm_malloc(sizeof(int));
00609 if (!queued_msgs) {
00610 LM_ERR("cannot get shm memory!\n");
00611 goto error;
00612 }
00613 *queued_msgs = 0;
00614
00615
00616
00617 cfg_register_child(nr_of_modems);
00618
00619 return 1;
00620 error:
00621 return -1;
00622 }
00623
00624
00625
00626
00627 int sms_child_init(int rank)
00628 {
00629 int i, foo;
00630
00631
00632 if (rank != 1) goto done;
00633
00634
00635 for(i=0;i<nr_of_modems;i++)
00636 {
00637 if ( (foo=fork())<0 ) {
00638 LM_ERR("cannot fork \n");
00639 goto error;
00640 }
00641 if (!foo) {
00642
00643 if (cfg_child_init()) goto error;
00644
00645 modem_process(&(modems[i]));
00646 goto done;
00647 }
00648 }
00649
00650 done:
00651 return 0;
00652 error:
00653 return-1;
00654 }
00655
00656
00657
00658
00659 static int sms_init(void)
00660 {
00661 LM_INFO("SMS - initializing\n");
00662
00663 if (parse_config_lines()==-1)
00664 return -1;
00665 if (global_init()==-1)
00666 return -1;
00667 return 0;
00668 }
00669
00670
00671
00672
00673 static int sms_exit(void)
00674 {
00675 if ((!domain_str) && (domain.s))
00676 pkg_free(domain.s);
00677
00678 if (queued_msgs)
00679 shm_free(queued_msgs);
00680
00681 if (sms_report_type!=NO_REPORT)
00682 destroy_report_queue();
00683
00684 return 0;
00685 }
00686
00687
00688
00689
00690 static int w_sms_send_msg(struct sip_msg *msg, char *foo, char *bar)
00691 {
00692 return push_on_network(msg, default_net);
00693 }
00694
00695
00696
00697
00698 static int w_sms_send_msg_to_net(struct sip_msg *msg, char *net_nr, char *foo)
00699 {
00700 return push_on_network(msg,(unsigned int)(unsigned long)net_nr);
00701 }
00702