69 #include "gw-config.h" 77 #include <sys/types.h> 231 warning(0,
"Maximum retries for message exceeded, discarding it!");
236 msg->sms.resend_try = (
msg->sms.resend_try > 0 ?
msg->sms.resend_try + 1 : 1);
237 time(&
msg->sms.resend_time);
244 debug(
"bb.sms.splits", 0,
"Set split msg status to %ld", reason);
245 split->status = reason;
251 debug(
"bb.sms.splits", 0,
"Set split msg status to %ld", reason);
252 split->status = reason;
267 msg->sms.split_parts = NULL;
271 debug(
"bb.sms.splits", 0,
"Parts of concatenated message failed.");
283 if (sms->sms.split_parts != NULL) {
319 if (dlrmsg != NULL) {
331 if (sms->sms.split_parts != NULL) {
349 warning(0,
"Maximum retries for message exceeded, discarding it!");
354 sms->sms.resend_try = (sms->sms.resend_try > 0 ? sms->sms.resend_try + 1 : 1);
355 time(&sms->sms.resend_time);
404 if (dlrmsg != NULL) {
439 warning(0,
"incoming messages queue too long, dropping a message");
486 if (sms->sms.msgdata == NULL)
504 sms->sms.sms_type =
mo;
510 info(0,
"Number <%s> is not in white-list-sender, message discarded",
512 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - not white-listed SMS");
520 info(0,
"Number <%s> is not in white-list-sender, message discarded",
522 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - not white-regex-listed SMS");
530 info(0,
"Number <%s> is in black-list-sender, message discarded",
532 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - black-listed SMS");
540 info(0,
"Number <%s> is in black-list-sender, message discarded",
542 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - black-regex-listed SMS");
550 info(0,
"Number <%s> is not in white-list-receiver, message discarded",
552 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - not white-listed SMS");
560 info(0,
"Number <%s> is not in white-list-receiver, message discarded",
562 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - not white-regex-listed SMS");
570 info(0,
"Number <%s> is in black-list-receiver, message discarded",
572 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - black-listed SMS");
580 info(0,
"Number <%s> is in black-list-receiver, message discarded",
582 bb_alog_sms(conn, sms,
"REJECTED Receive SMS - black-regex-listed SMS");
619 panic(0,
"Internal error: Unhandled concat result.");
629 debug(
"bb.sms", 0,
"Reloading smsc groups list from config resource");
652 Msg *
msg, *startmsg, *newmsg;
654 time_t concat_mo_check;
659 startmsg = newmsg = NULL;
661 concat_mo_check = time(NULL);
665 if (newmsg == startmsg) {
669 debug(
"bb.sms", 0,
"sms_router: time to sleep %.2f secs.", sleep_time);
680 concat_mo_check = time(NULL);
686 newmsg = startmsg = NULL;
690 debug(
"bb.sms", 0,
"sms_router: handling message (%p vs %p)",
696 debug(
"bb.sms", 0,
"re-queing SMS not-yet-to-be resent");
705 debug(
"bb.sms", 0,
"Message routed successfully.");
706 newmsg = startmsg = NULL;
709 debug(
"bb.sms", 0,
"Routing failed, re-queued.");
713 newmsg = startmsg = NULL;
716 debug(
"bb.sms", 0,
"Routing failed, re-queuing.");
720 debug(
"bb.sms", 0,
"Routing failed, expired.");
722 newmsg = startmsg = NULL;
732 #define OCTSTR(os) octstr_imm(#os) 760 OCTSTR(preferred-smsc-
id),
770 OCTSTR(allowed-smsc-
id-regex),
771 OCTSTR(denied-smsc-
id-regex),
772 OCTSTR(preferred-smsc-
id-regex),
773 OCTSTR(allowed-prefix-regex),
774 OCTSTR(denied-prefix-regex),
775 OCTSTR(preferred-prefix-regex),
832 warning(0,
"Option 'white-list' is deprecated! Please use 'white-list-sender' instead!");
837 panic(0,
"Could not get white-list at URL <%s>",
841 warning(0,
"Option 'white-list-regex' is deprecated! Please use 'white-list-sender-regex' instead!");
851 warning(0,
"Option 'black-list' is deprecated! Please use 'black-list-sender' instead!");
856 panic(0,
"Could not get black-list at URL <%s>",
860 warning(0,
"Option 'black-list-regex' is deprecated! Please use 'black-list-sender-regex' instead!");
874 panic(0,
"Could not get white-list-receiver at URL <%s>",
886 panic(0,
"Could not get black-list-receiver at URL <%s>",
903 info(0,
"SMS resend retry set to unlimited.");
919 panic(0,
"Connot start with PDU init failed.");
927 for (j = 0; j < m; j++) {
930 panic(0,
"Cannot start with SMSC connection failing");
937 panic(0,
"Failed to start a new thread for SMS routing");
982 info(0,
"HTTP: Could not shutdown already dead smsc-id `%s'",
1023 warning(0,
"HTTP: Could not re-start already running smsc-id `%s'",
1056 if (new_conn == NULL) {
1146 for (j = 0; j < m; j++) {
1182 error(0,
"Unable to reload white_list."),
1195 error(0,
"Unable to reload black_list");
1208 error(0,
"Unable to reload white_list."),
1221 error(0,
"Unable to reload black_list");
1322 debug(
"smscconn", 0,
"final clean-up for SMSCConn");
1371 const Octstr *conn_id = NULL;
1372 const Octstr *conn_admin_id = NULL;
1373 const Octstr *conn_name = NULL;
1374 float incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2;
1375 float outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2;
1376 float incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2;
1377 float outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2;
1387 return octstr_create (
"<smscs>\n\t<count>0</count>\n</smscs>");
1389 return octstr_format(
"%sNo SMSC connections%s\n\n", para ?
"<p>" :
"",
1390 para ?
"</p>" :
"");
1394 tmp =
octstr_format(
"%sSMSC connections:%s", para ?
"<p>" :
"", lb);
1400 incoming_sms_load_0 = incoming_sms_load_1 = incoming_sms_load_2 = 0.0;
1401 outgoing_sms_load_0 = outgoing_sms_load_1 = outgoing_sms_load_2 = 0.0;
1402 incoming_dlr_load_0 = incoming_dlr_load_1 = incoming_dlr_load_2 = 0.0;
1403 outgoing_dlr_load_0 = outgoing_dlr_load_1 = outgoing_dlr_load_2 = 0.0;
1415 conn_id = conn_id ? conn_id :
octstr_imm(
"unknown");
1417 conn_admin_id = conn_admin_id ? conn_admin_id :
octstr_imm(
"unknown");
1444 switch (
info.status) {
1447 sprintf(tmp3,
"online %lds",
info.online);
1462 sprintf(tmp3,
"disconnected");
1465 sprintf(tmp3,
"connecting");
1468 sprintf(tmp3,
"re-connecting");
1471 sprintf(tmp3,
"dead");
1474 sprintf(tmp3,
"unknown");
1480 "\t\t<failed>%ld</failed>\n" 1481 "\t\t<queued>%ld</queued>\n" 1483 "\t\t\t<received>%ld</received>\n" 1484 "\t\t\t<sent>%ld</sent>\n" 1485 "\t\t\t<inbound>%.2f,%.2f,%.2f</inbound>\n" 1486 "\t\t\t<outbound>%.2f,%.2f,%.2f</outbound>\n" 1487 "\t\t</sms>\n\t\t<dlr>\n" 1488 "\t\t\t<received>%ld</received>\n" 1489 "\t\t\t<sent>%ld</sent>\n" 1490 "\t\t\t<inbound>%.2f,%.2f,%.2f</inbound>\n" 1491 "\t\t\t<outbound>%.2f,%.2f,%.2f</outbound>\n" 1493 "\t</smsc>\n", tmp3,
1495 incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2,
1496 outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2,
1498 incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2,
1499 outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2);
1502 "sent: sms %ld (%.2f,%.2f,%.2f) / dlr %ld (%.2f,%.2f,%.2f), failed %ld, " 1503 "queued %ld msgs)%s",
1506 incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2,
1508 incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2,
1510 outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2,
1512 outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2,
1534 List *keep, *add, *
remove;
1668 for (i = 0; i < m; i++) {
1672 if (conn->dead_start) {
1719 SMSCConn *conn, *best_preferred, *best_ok;
1720 long bp_load, bo_load;
1721 int i, s, ret, bad_found, full_found;
1722 long max_queue, queue_length;
1727 error(0,
"Attempt to route non SMS message through smsc2_rout!");
1746 info(0,
"Number <%s> is not in white-list-sender, message rejected",
1754 info(0,
"Number <%s> is not in white-list-sender, message rejected",
1762 info(0,
"Number <%s> is in black-list-sender, message rejected",
1770 info(0,
"Number <%s> is in black-list-sender, message rejected",
1778 info(0,
"Number <%s> is not in white-list-receiver, message rejected",
1786 info(0,
"Number <%s> is not in white-list-receiver, message rejected",
1794 info(0,
"Number <%s> is in black-list-receiver, message rejected",
1802 info(0,
"Number <%s> is in black-list-receiver, message rejected",
1814 warning(0,
"No SMSCes to receive message");
1819 best_preferred = best_ok = NULL;
1820 bad_found = full_found = 0;
1821 bp_load = bo_load = queue_length = 0;
1823 if (
msg->sms.split_parts == NULL) {
1849 if (ret != 1 && best_preferred)
1858 if (stat.
queued > max_queue) {
1863 if (best_preferred == NULL || stat.
load < bp_load) {
1864 best_preferred = conn;
1865 bp_load = stat.
load;
1869 if (best_ok == NULL || stat.
load < bo_load) {
1871 bo_load = stat.
load;
1878 debug(
"bb.sms", 0,
"sum(#queues) limit");
1892 else if (bad_found) {
1898 debug(
"bb.sms", 0,
"bad_found queue full");
1900 }
else if (full_found) {
1902 debug(
"bb.sms", 0,
"full_found queue full");
1910 warning(0,
"Cannot find SMSCConn for message to <%s>, rejected.",
1983 for (i = 0; i < l; i++) {
1986 if (r != NULL && r->
re != NULL &&
1987 gw_regex_match_pre(r->
re,
msg->sms.receiver) == 1) {
2030 for (i = 0; i <
msg->total_parts; i++) {
2031 if (
msg->parts[i]) {
2036 gw_free(
msg->parts);
2050 debug(
"bb.sms",0,
"MO concatenated message handling enabled");
2075 debug(
"bb.sms",0,
"MO concatenated message handling cleaned up");
2087 debug(
"bb.sms.splits", 0,
"clear_old_concat_parts called");
2095 int i, destroy = 1, smsc_index;
2113 if (smsc_index != -1) {
2115 warning(0,
"Time-out waiting for concatenated message '%s'. Send message parts as is.",
2117 for (i = 0; i < x->
total_parts && destroy == 1; i++) {
2118 if (x->
parts[i] == NULL)
2158 if (x->
parts[i] == NULL)
2160 if (x1->
parts[i] == NULL) {
2184 int l, iel = 0, refnum, pos, c, part, totalparts, i, sixteenbit;
2196 for (pos = 1, c = -1; pos < l - 1; pos += iel + 2) {
2205 sixteenbit = (c == 8);
2211 if (part < 1 || part > totalparts) {
2212 warning(0,
"Invalid concatenation UDH [ref = %d] in message from %s!",
2225 debug(
"bb.sms.splits", 0,
"Got part %d [ref %d, total parts %d] of message from %s. Dump follows:",
2230 key =
octstr_format(
"'%S' '%S' '%S' '%d' '%d' '%H'",
msg->sms.sender,
msg->sms.receiver, smscid, refnum, totalparts, udh);
2233 cmsg = gw_malloc(
sizeof(*cmsg));
2242 cmsg->
parts = gw_malloc(totalparts *
sizeof(*cmsg->
parts));
2251 if (cmsg->
parts[part - 1] != NULL) {
2252 error(0,
"Duplicate message part %d, ref %d, from %s, to %s. Discarded!",
2263 cmsg->
trecv = time(NULL);
2276 debug(
"bb.sms.splits",0,
"Received all concatenated message parts from %s, to %s, refnum %d",
2293 msg->sms.udhdata = cmsg->
udh;
2301 debug(
"bb.sms.splits", 0,
"Got full message [ref %d] of message from %s to %s. Dumping: ",
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
void msg_dump(Msg *msg, int level)
void error(int err, const char *fmt,...)
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
void info(int err, const char *fmt,...)
Msg * msg_duplicate(Msg *msg)
void bb_smscconn_connected(SMSCConn *conn)
static Cfg * cfg_reloaded
int smsc2_add_smsc(Octstr *id)
Counter * outgoing_sms_counter
static long concatenated_mo_timeout
long gwlist_search_equal(List *list, void *item)
static List * smsc_groups
void bb_smscconn_ready(SMSCConn *conn)
static long router_thread
int smscconn_destroy(SMSCConn *conn)
gw_assert(wtls_machine->packet_to_send !=NULL)
Counter * incoming_sms_counter
void dict_put(Dict *dict, Octstr *key, void *value)
void counter_destroy(Counter *counter)
void gwlist_append(List *list, void *item)
static regex_t * white_list_sender_regex
int smsc2_restart_smsc(Octstr *id)
char * bb_status_linebreak(int status_type)
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
void bb_smscconn_killed(void)
List * reroute_by_receiver_regex
int smsc2_graceful_restart(Cfg *cfg)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
static Mutex * concat_lock
void gwlist_produce(List *list, void *item)
static RWLock smsc_list_lock
long gwlist_len(List *list)
int(* store_save_ack)(Msg *msg, ack_status_t status)
static long route_incoming_to_smsc(SMSCConn *conn, Msg *msg)
void gw_rwlock_destroy(RWLock *lock)
int gw_rwlock_wrlock(RWLock *lock)
int smsc2_reload_lists(void)
void * gwlist_get(List *list, long pos)
Octstr * cfg_get_group_checksum(CfgGroup *grp,...)
Msg * create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat)
#define cfg_get(grp, varname)
const Octstr * smscconn_name(SMSCConn *conn)
static regex_t * black_list_receiver_regex
void uuid_generate(uuid_t out)
static long sms_resend_retry
long max_outgoing_sms_qlength
Dict * reroute_by_receiver
unsigned long counter_decrease(Counter *counter)
int gw_rwlock_rdlock(RWLock *lock)
static int cmp_conn_grp_id(void *a, void *b)
void numhash_destroy(Numhash *table)
#define DLR_IS_SMSC_FAIL(dlr)
void octstr_append_cstr(Octstr *ostr, const char *cstr)
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
double load_get(Load *load, int pos)
static long bb_smscconn_receive_internal(SMSCConn *conn, Msg *sms)
static void concat_handling_clear_old_parts(int force)
static void handle_split(SMSCConn *conn, Msg *msg, long reason, Octstr *reply)
#define octstr_get_cstr(ostr)
static RWLock white_black_list_lock
unsigned long counter_increase(Counter *counter)
unsigned int smscconn_instances(CfgGroup *grp)
Counter * incoming_dlr_counter
Cfg * cfg_create(Octstr *filename)
Numhash * numhash_create(const char *seek_url)
static Numhash * white_list_sender
const Octstr * smscconn_admin_id(SMSCConn *conn)
List * gwlist_search_all(List *list, void *pattern, int(*cmp)(void *, void *))
Counter * outgoing_dlr_counter
int smsc2_remove_smsc(Octstr *id)
static Octstr * black_list_receiver_url
int smpp_pdu_shutdown(void)
void smscconn_reconfig(SMSCConn *conn, CfgGroup *grp)
Octstr * octstr_imm(const char *cstr)
int smscconn_status(SMSCConn *conn)
void * dict_remove(Dict *dict, Octstr *key)
int numhash_find_number(Numhash *table, Octstr *nro)
Counter * counter_create(void)
void cfg_destroy(Cfg *cfg)
int smsc2_stop_smsc(Octstr *id)
void * gwlist_extract_first(List *list)
static Dict * incoming_concat_msgs
void gwlist_delete(List *list, long pos, long count)
static Numhash * black_list_sender
void * dict_get(Dict *dict, Octstr *key)
void octstr_delete(Octstr *ostr1, long pos, long len)
void gwlist_remove_producer(List *list)
int bb_reload_smsc_groups()
static int cmp_conn_grp_checksum(void *a, void *b)
long max_incoming_sms_qlength
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
int smscconn_stop(SMSCConn *conn)
static void concat_handling_init(void)
int route_incoming_to_boxc(Msg *msg)
const Octstr * smscconn_id(SMSCConn *conn)
#define octstr_duplicate(ostr)
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
static void concat_handling_cleanup(void)
static void sms_router(void *arg)
void msg_destroy(Msg *msg)
int gw_rwlock_unlock(RWLock *lock)
Counter * split_msg_counter
void warning(int err, const char *fmt,...)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
#define DLR_IS_SMSC_SUCCESS(dlr)
void gwthread_sleep(double seconds)
void mutex_destroy(Mutex *mutex)
static regex_t * white_list_receiver_regex
#define SMS_PARAM_UNDEFINED
static Octstr * white_list_sender_url
int smscconn_send(SMSCConn *conn, Msg *msg)
void gwlist_insert(List *list, long pos, void *item)
#define load_increase(load)
static Numhash * white_list_receiver
long octstr_len(const Octstr *ostr)
void dict_destroy(Dict *dict)
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
int smscconn_usable(SMSCConn *conn, Msg *msg)
static long sms_resend_frequency
static int cmp_rout_grp_checksum(void *a, void *b)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
volatile sig_atomic_t bb_status
void gwthread_wakeup(long thread)
void octstr_format_append(Octstr *os, const char *fmt,...)
int smpp_pdu_init(Cfg *cfg)
List * dict_keys(Dict *dict)
int normalize_number(char *dial_prefixes, Octstr **number)
SMSCConn * smscconn_create(CfgGroup *grp, int start_as_stopped)
int(* store_save)(Msg *msg)
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
struct ConcatMsg ConcatMsg
static void destroy_concatMsg(void *x)
void smsc2_resume(int is_init)
void gw_rwlock_init_static(RWLock *lock)
Octstr * smsc2_status(int status_type)
static Octstr * unified_prefix
static Octstr * black_list_sender_url
int smscconn_info(SMSCConn *conn, StatusInfo *infotable)
static Octstr * white_list_receiver_url
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
void gwlist_add_producer(List *list)
int smsc2_start(Cfg *cfg)
static void concat_handling_shutdown(void)
static regex_t * black_list_sender_regex
int octstr_get_char(const Octstr *ostr, long pos)
void * gwlist_timed_consume(List *list, long sec)
void octstr_set_char(Octstr *ostr, long pos, int ch)
static volatile sig_atomic_t smsc_running
static volatile sig_atomic_t handle_concatenated_mo
static Numhash * black_list_receiver
static XMLRPCDocument * msg
static int concat_handling_check_and_handle(Msg **msg, Octstr *smscid)
void smscconn_start(SMSCConn *conn)
static void reply(HTTPClient *c, List *push_headers)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
static long smsc2_find(Octstr *id, long start)
long smsc2_rout(Msg *msg, int resend)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)