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)