84 #define SMPP_DEFAULT_CHARSET        "UTF-8"    85 #define SMPP_DEFAULT_UCS2_CHARSET   "UTF-16BE"   101 #define dump_pdu(msg, id, pdu, format) do{}while(0)   104 #define dump_pdu(msg, id, pdu, format)          \   106         debug("bb.sms.smpp", 0, "SMPP[%s]: %s", \   107             octstr_get_cstr(id), msg);          \   108         if (format == SMPP_PDU_DUMP_MULTILINE)  \   109             smpp_pdu_dump(id, pdu);             \   111             smpp_pdu_dump_line(id, pdu);        \   120 #define SMPP_ENQUIRE_LINK_INTERVAL  30.0   121 #define SMPP_MAX_PENDING_SUBMITS    10   122 #define SMPP_DEFAULT_VERSION        0x34   123 #define SMPP_DEFAULT_PRIORITY       0   124 #define SMPP_THROTTLING_SLEEP_TIME  1   125 #define SMPP_DEFAULT_CONNECTION_TIMEOUT  10 * SMPP_ENQUIRE_LINK_INTERVAL   126 #define SMPP_DEFAULT_WAITACK        60   127 #define SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30   128 #define SMPP_DEFAULT_PORT           2775   134 #define SMPP_WAITACK_RECONNECT      0x00   135 #define SMPP_WAITACK_REQUEUE        0x01   136 #define SMPP_WAITACK_NEVER_EXPIRE   0x02   222     if (destroy_msg && 
msg->msg != NULL)
   230                          int receive_port, 
int our_port, 
int our_receiver_port, 
Octstr *system_type,
   233                          int source_addr_ton, 
int source_addr_npi,
   234                          int dest_addr_ton, 
int dest_addr_npi,
   235                          int enquire_link_interval, 
int max_pending_submits,
   236                          int version, 
int priority, 
int validity,
   237                          Octstr *my_number, 
int smpp_msg_id_type,
   239                          Octstr *service_type, 
long connection_timeout,
   240                          long wait_ack, 
int wait_ack_action, 
int esm_class)
   244     smpp = gw_malloc(
sizeof(*smpp));
   334             error(0, 
"SMPP[%s]: Server sent garbage, ignored.",
   337         } 
else if (*len == 0) {
   354         error(0, 
"SMPP[%s]: PDU unpacking failed.",
   356         debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: Failed PDU follows.",
   386                 warning(0, 
"SMPP[%s]: Malformed addr `%s', generally expected at least 7 digits. ",
   391                 error(0, 
"SMPP[%s]: Malformed addr `%s', expected all digits. ",
   398                 error(0, 
"SMPP[%s]: Malformed addr `%s', expected all digits. ",
   416                 error(0, 
"SMPP[%s]: Malformed addr `%s', alphanumeric length greater 11 chars. ",
   422             if (alt_addr_charset) {
   426                     error(0, 
"Failed to convert address from charset <%s> to <%s>, leave as is.",
   451     switch (data_coding) {
   454                 error(0, 
"Failed to convert msgdata from %s to ASCII, will leave as is", 
internal);
   459                 error(0, 
"Failed to convert msgdata from %s to LATIN1, will leave as is", 
internal);
   467                 error(0, 
"Failed to convert msgdata from %s to Japanese (JIS-X0208-1990), "   468                          "will leave as is", 
internal);
   472                 error(0, 
"Failed to convert msgdata from %s to Cyrllic (ISO-8859-5), "   473                          "will leave as is", 
internal);
   477                 error(0, 
"Failed to convert msgdata from %s to Hebrew (ISO-8859-8), "   478                          "will leave as is", 
internal);
   482                 error(0, 
"Failed to convert msgdata from %s to Unicode (UTF-16BE), "   483                          "will leave as is", 
internal);
   487                 error(0, 
"Failed to convert msgdata from %s to Japanese (JIS-X0212-1990), "   488                          "will leave as is", 
internal);
   493                 error(0, 
"Failed to convert msgdata from %s to Korean (KSC_5601/KSC5636), "   494                          "will leave as is", 
internal);
   511     switch (data_coding) {
   519                     error(0, 
"Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
   606     ton = pdu->
u.deliver_sm.source_addr_ton;
   607     npi = pdu->
u.deliver_sm.source_addr_npi;
   611     msg->sms.sender = pdu->
u.deliver_sm.source_addr;
   612     pdu->
u.deliver_sm.source_addr = NULL;
   618     if (pdu->
u.deliver_sm.destination_addr == NULL) {
   619         error(0, 
"SMPP[%s]: Malformed destination_addr `%s', may not be empty. "   627     ton = pdu->
u.deliver_sm.dest_addr_ton;
   628     npi = pdu->
u.deliver_sm.dest_addr_npi;
   632     msg->sms.receiver = pdu->
u.deliver_sm.destination_addr;
   633     pdu->
u.deliver_sm.destination_addr = NULL;
   638     msg->sms.binfo = pdu->
u.deliver_sm.service_type;
   639     pdu->
u.deliver_sm.service_type = NULL;
   642     msg->sms.foreign_id = pdu->
u.deliver_sm.receipted_message_id;
   643     pdu->
u.deliver_sm.receipted_message_id = NULL;
   652     if (smpp->
version > 0x33 && pdu->
u.deliver_sm.sm_length == 0 && pdu->
u.deliver_sm.message_payload) {
   653         msg->sms.msgdata = pdu->
u.deliver_sm.message_payload;
   654         pdu->
u.deliver_sm.message_payload = NULL;
   657         msg->sms.msgdata = pdu->
u.deliver_sm.short_message;
   658         pdu->
u.deliver_sm.short_message = NULL;
   663         pdu->
u.deliver_sm.sar_msg_ref_num >= 0 && pdu->
u.deliver_sm.sar_segment_seqnum > 0 && pdu->
u.deliver_sm.sar_total_segments > 0) {
   671             error(0, 
"SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
   678                                pdu->
u.deliver_sm.sar_segment_seqnum,
   679                                pdu->
u.deliver_sm.sar_total_segments,
   680                                pdu->
u.deliver_sm.sar_msg_ref_num);
   690         debug(
"bb.sms.smpp",0,
"SMPP[%s]: UDH length read as %d",
   693             error(0, 
"SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "   708     msg->sms.pid = pdu->
u.deliver_sm.protocol_id;
   711     msg->sms.priority = pdu->
u.deliver_sm.priority_flag;
   713     if (
msg->sms.meta_data == NULL)
   747     ton = pdu->
u.data_sm.source_addr_ton;
   748     npi = pdu->
u.data_sm.source_addr_npi;
   752     msg->sms.sender = pdu->
u.data_sm.source_addr;
   753     pdu->
u.data_sm.source_addr = NULL;
   759     if (pdu->
u.data_sm.destination_addr == NULL) {
   760         error(0, 
"SMPP[%s]: Malformed destination_addr `%s', may not be empty. "   768     ton = pdu->
u.data_sm.dest_addr_ton;
   769     npi = pdu->
u.data_sm.dest_addr_npi;
   773     msg->sms.receiver = pdu->
u.data_sm.destination_addr;
   774     pdu->
u.data_sm.destination_addr = NULL;
   777     if (smpp->
version == 0x50 && pdu->
u.data_sm.billing_identification) {
   778         msg->sms.binfo = pdu->
u.data_sm.billing_identification;
   779         pdu->
u.data_sm.billing_identification = NULL;
   781         msg->sms.binfo = pdu->
u.data_sm.service_type;
   782         pdu->
u.data_sm.service_type = NULL;
   786     msg->sms.foreign_id = pdu->
u.data_sm.receipted_message_id;
   787     pdu->
u.data_sm.receipted_message_id = NULL;
   792     msg->sms.msgdata = pdu->
u.data_sm.message_payload;
   793     pdu->
u.data_sm.message_payload = NULL;
   796     if (pdu->
u.data_sm.sar_msg_ref_num >= 0 && pdu->
u.data_sm.sar_segment_seqnum > 0 && pdu->
u.data_sm.sar_total_segments > 0) {
   804             error(0, 
"SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
   811                                pdu->
u.data_sm.sar_segment_seqnum,
   812                                pdu->
u.data_sm.sar_total_segments,
   813                                pdu->
u.data_sm.sar_msg_ref_num);
   823         debug(
"bb.sms.smpp",0,
"SMPP[%s]: UDH length read as %d",
   826             error(0, 
"SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "   841     if (
msg->sms.meta_data == NULL)
   876     int data_coding = -1;
   901         debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
   926     if (pdu->
u.submit_sm.source_addr && !ton_npi_forced && smpp->
autodetect_addr) {
   938                         error(0, 
"Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
   956                         error(0, 
"Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
   967         debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
   991     if (!ton_npi_forced) {
  1003     if (
octstr_len(pdu->
u.submit_sm.destination_addr) > 20 ||
  1027         pdu->
u.submit_sm.protocol_id = 
msg->sms.pid;
  1033     pdu->
u.submit_sm.esm_class = smpp->
esm_class;
  1035         pdu->
u.submit_sm.esm_class = pdu->
u.submit_sm.esm_class |
  1037     if (
msg->sms.rpi > 0)
  1038         pdu->
u.submit_sm.esm_class = pdu->
u.submit_sm.esm_class |
  1066         if (pdu->
u.submit_sm.data_coding & 0xF0) {
  1068         } 
else if (pdu->
u.submit_sm.data_coding == 0 && !smpp->
alt_charset) {
  1073             if (data_coding != -1)
  1074                 pdu->
u.submit_sm.data_coding = data_coding;
  1075         } 
else if (pdu->
u.submit_sm.data_coding == 0 && smpp->
alt_charset) {
  1081                 error(0, 
"Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
  1085     else if (
msg->sms.coding == 
DC_UCS2 && data_coding > 0x04 && data_coding != 0x08) {
  1091         pdu->
u.submit_sm.data_coding = data_coding;
  1099     pdu->
u.submit_sm.sm_length = 
octstr_len(pdu->
u.submit_sm.short_message);
  1106     if (pdu->
u.submit_sm.sm_length > 254) {
  1109             pdu->
u.submit_sm.message_payload = pdu->
u.submit_sm.short_message;
  1110             pdu->
u.submit_sm.short_message = NULL;
  1111             pdu->
u.submit_sm.sm_length = 0;
  1113             error(0, 
"SMPP[%s]: Unable to send long message (%ld) Octets in smpp version < 3.4",
  1128         validity = 
msg->sms.validity;
  1133         pdu->
u.submit_sm.validity_period = 
octstr_format(
"%02d%02d%02d%02d%02d%02d000+",
  1134                 tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
  1135                 tm.tm_hour, tm.tm_min, tm.tm_sec);
  1140         pdu->
u.submit_sm.schedule_delivery_time = 
octstr_format(
"%02d%02d%02d%02d%02d%02d000+",
  1141                 tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
  1142                 tm.tm_hour, tm.tm_min, tm.tm_sec);
  1147         pdu->
u.submit_sm.registered_delivery = 2;
  1149         pdu->
u.submit_sm.registered_delivery = 1;
  1152         pdu->
u.submit_sm.registered_delivery += 16;
  1155     if (
msg->sms.priority >= 0 && 
msg->sms.priority <= 3)
  1156         pdu->
u.submit_sm.priority_flag = 
msg->sms.priority;
  1158         pdu->
u.submit_sm.priority_flag = smpp->
priority;
  1161     if (smpp->
version > 0x33 && 
msg->sms.msg_left > 0)
  1162         pdu->
u.submit_sm.more_messages_to_send = 1;
  1204     pdu->
u.generic_nack.command_status = reason;
  1248         ret = (ret == 1) ? 0 : ret;
  1262     if (*pending_submits == -1)
  1265     while (*pending_submits < smpp->max_pending_submits) {
  1268             debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: throughput limit exceeded (%.02f,%.02f)",
  1272         debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: throughput (%.02f,%.02f)",
  1287         if (
send_pdu(conn, smpp, pdu) == 0) {
  1293             ++(*pending_submits);
  1329         error(0, 
"SMPP[%s]: Couldn't connect to server.",
  1341         bind->
u.bind_transmitter.system_type =
  1343     bind->
u.bind_transmitter.interface_version = smpp->
version;
  1344     bind->
u.bind_transmitter.address_range =
  1348     if (
send_pdu(conn, smpp, bind) == -1) {
  1349         error(0, 
"SMPP[%s]: Couldn't send bind_transmitter to server.",
  1382        error(0, 
"SMPP[%s]: Couldn't connect to server.",
  1395     bind->
u.bind_transceiver.interface_version = smpp->
version;
  1399     if (
send_pdu(conn, smpp, bind) == -1) {
  1400         error(0, 
"SMPP[%s]: Couldn't send bind_transceiver to server.",
  1433         error(0, 
"SMPP[%s]: Couldn't connect to server.",
  1445         bind->
u.bind_receiver.system_type =
  1447     bind->
u.bind_receiver.interface_version = smpp->
version;
  1448     bind->
u.bind_receiver.address_range =
  1452     if (
send_pdu(conn, smpp, bind) == -1) {
  1453         error(0, 
"SMPP[%s]: Couldn't send bind_receiver to server.",
  1474     if (network_error_code == NULL || 
octstr_len(network_error_code) != 3)
  1479     err = (nec[1] << 8) | nec[2];
  1481     if ((
type >= 
'0') && (
type <= 
'9')) {
  1484         sscanf((
char*) nec, 
"%03d", &err);
  1495     Octstr *respstr = NULL, *msgid = NULL, *network_err = NULL, *dlr_err = NULL, *tmp;
  1500     if (smpp->
version > 0x33 && receipted_message_id) {
  1502         switch(message_state) {
  1528             debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: Partial SMPP v3.4, receipted_message_id present but not message_state.",
  1533             warning(0, 
"SMPP[%s]: Got DLR with unknown 'message_state' (%ld).",
  1540     if (network_error_code != NULL) {
  1547         respstr = message_payload;
  1549         respstr = short_message;
  1551     if (msgid == NULL || network_err == NULL || dlrstat == -1) {
  1554             long curr = 0, vpos = 0;
  1556             char id_cstr[65], stat_cstr[16], sub_d_cstr[15], done_d_cstr[15];
  1558             int sub, dlrvrd, ret;
  1563                          "id:%64[^ ] sub:%d dlvrd:%d submit date:%14[0-9] done "  1564                          "date:%14[0-9] stat:%15[^ ] err:%3[^ ]",
  1565                          id_cstr, &sub, &dlrvrd, sub_d_cstr, done_d_cstr,
  1566                          stat_cstr, err_cstr);
  1569                 if (msgid == NULL) {
  1575                 sscanf(err_cstr, 
"%d", &err_int);
  1579                 debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: Could not parse DLR string sscanf way, "  1583                 if (msgid == NULL) {
  1588                             msgid = 
octstr_copy(respstr, curr+3, vpos-curr-3);
  1605                         dlr_err = 
octstr_copy(respstr, curr+4, vpos-curr-4);
  1618             if (dlrstat == -1) {
  1634     if (msgid != NULL && dlrstat != -1) {
  1672     if (network_err == NULL && dlr_err != NULL) {
  1673         unsigned char ctmp[3];
  1676         ctmp[1] = (err_int >> 8) & 0xFF;
  1677         ctmp[2] = (err_int & 0xFF);
  1681     if (dlrmsg != NULL) {
  1691         if (network_err != NULL) {
  1692             if (dlrmsg->sms.meta_data == NULL) {
  1698         error(0,
"SMPP[%s]: got DLR but could not find message or was not interested "  1699                 "in it id<%s> dst<%s>, type<%d>",
  1727                       long *pending_submits)
  1731     Msg *
msg = NULL, *dlrmsg=NULL;
  1733     long reason, cmd_stat;
  1743     switch (pdu->
type) {
  1750                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  1770             if (pdu->
u.data_sm.esm_class & (0x04|0x08|0x20)) {
  1771                  debug(
"bb.sms.smpp",0,
"SMPP[%s] handle_pdu, got DLR",
  1773                  dlrmsg = 
handle_dlr(smpp, pdu->
u.data_sm.source_addr, NULL, pdu->
u.data_sm.message_payload,
  1774                                      pdu->
u.data_sm.receipted_message_id, pdu->
u.data_sm.message_state, pdu->
u.data_sm.network_error_code);
  1775                  if (dlrmsg != NULL) {
  1776                      if (dlrmsg->sms.meta_data == NULL)
  1785                          resp->
u.data_sm_resp.command_status = reason;
  1796                      resp->
u.data_sm_resp.command_status = reason;
  1804                  time(&
msg->sms.time);
  1817                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  1829                         pdu->
u.deliver_sm.sequence_number);
  1841             if (pdu->
u.deliver_sm.esm_class & (0x04|0x08|0x20)) {
  1843                 debug(
"bb.sms.smpp",0,
"SMPP[%s] handle_pdu, got DLR",
  1846                 dlrmsg = 
handle_dlr(smpp, pdu->
u.deliver_sm.source_addr, pdu->
u.deliver_sm.short_message, pdu->
u.deliver_sm.message_payload,
  1847                                     pdu->
u.deliver_sm.receipted_message_id, pdu->
u.deliver_sm.message_state, pdu->
u.deliver_sm.network_error_code);
  1848                 resp = 
smpp_pdu_create(deliver_sm_resp, pdu->
u.deliver_sm.sequence_number);
  1849                 if (dlrmsg != NULL) {
  1850                     if (dlrmsg->sms.meta_data == NULL)
  1859                         resp->
u.deliver_sm_resp.command_status = reason;
  1869                             pdu->
u.deliver_sm.sequence_number);
  1873                     resp->
u.deliver_sm_resp.command_status = reason;
  1883                 time(&
msg->sms.time);
  1897                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  1902                         pdu->
u.enquire_link.sequence_number);
  1905         case enquire_link_resp:
  1911                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  1915             if (pdu->
u.enquire_link_resp.command_status != 0) {
  1916                 error(0, 
"SMPP[%s]: SMSC got error to enquire_link PDU, code 0x%08lx (%s).",
  1918                       pdu->
u.enquire_link_resp.command_status,
  1923         case submit_sm_resp:
  1928                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  1933             os = 
octstr_format(
"%ld", pdu->
u.submit_sm_resp.sequence_number);
  1937                 warning(0, 
"SMPP[%s]: SMSC sent submit_sm_resp PDU "  1938                         "with wrong sequence number 0x%08lx",
  1940                         pdu->
u.submit_sm_resp.sequence_number);
  1947             if (
msg->sms.meta_data == NULL)
  1951             if (pdu->
u.submit_sm_resp.command_status != 0) {
  1952                 error(0, 
"SMPP[%s]: SMSC returned error code 0x%08lx (%s) "  1953                       "in response to submit_sm PDU.",
  1955                       pdu->
u.submit_sm_resp.command_status,
  1958                             pdu->
u.submit_sm_resp.command_status);
  1971                 --(*pending_submits);
  1973             else if (pdu->
u.submit_sm_resp.message_id != NULL) {
  2003                     msg->sms.foreign_id = tmp;
  2007                 --(*pending_submits);
  2010                 error(0, 
"SMPP[%s]: SMSC returned error code 0x%08lx (%s) "  2011                       "in response to submit_sm PDU, but no `message_id' value!",
  2013                       pdu->
u.submit_sm_resp.command_status,
  2016                 --(*pending_submits);
  2020         case bind_transmitter_resp:
  2026                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
  2030             if (pdu->
u.bind_transmitter_resp.command_status != 0 &&
  2032                 error(0, 
"SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
  2034                       pdu->
u.bind_transmitter_resp.command_status,
  2046                 *pending_submits = 0;
  2055         case bind_transceiver_resp:
  2061                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
  2065             if (pdu->
u.bind_transceiver_resp.command_status != 0 &&
  2067                 error(0, 
"SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
  2069                       pdu->
u.bind_transceiver_resp.command_status,
  2081                 *pending_submits = 0;
  2090         case bind_receiver_resp:
  2096                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
  2100             if (pdu->
u.bind_receiver_resp.command_status != 0 &&
  2102                 error(0, 
"SMPP[%s]: SMSC rejected login to receive, code 0x%08lx (%s).",
  2104                       pdu->
u.bind_receiver_resp.command_status,
  2132                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  2140             *pending_submits = -1;
  2149                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  2164                 warning(0, 
"SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
  2169             cmd_stat  = pdu->
u.generic_nack.command_status;
  2176                 error(0, 
"SMPP[%s]: SMSC rejected last command, code 0x%08lx (%s).",
  2184                 error(0, 
"SMPP[%s]: SMSC returned error code 0x%08lx (%s) in response to submit_sm PDU.",
  2201                 --(*pending_submits);
  2206             error(0, 
"SMPP[%s]: Unhandled %s PDU type 0x%08lx, ignored.",
  2217         ret = 
send_pdu(conn, smpp, resp) != -1 ? 0 : -1;
  2251     time_t now = time(NULL);
  2253     if (*pending_submits <= 0)
  2270                     warning(0, 
"SMPP[%s]: Not ACKED message found, reconnecting.",
  2278                         warning(0, 
"SMPP[%s]: Not ACKED message found, will retransmit."  2279                                    " SENT<%ld>sec. ago, SEQ<%s>, DST<%s>",
  2286                         (*pending_submits)--;
  2290                     error(0, 
"SMPP[%s] Unknown clenup action defined 0x%02x.",
  2318     long pending_submits;
  2322     time_t last_cleanup, last_enquire_sent, last_response, now;
  2332 #define IS_ACTIVE (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)  2343         pending_submits = -1;
  2345         last_response = last_cleanup = last_enquire_sent = time(NULL);
  2346         while(conn != NULL) {
  2349                 error(0, 
"SMPP[%s]: I/O error or other error. Re-connecting.",
  2352             } 
else if (ret == -2) {
  2356                     error(0, 
"SMPP[%s]: I/O error or other error. Re-connecting.",
  2360             } 
else if (ret == 1) { 
  2366                     error(0, 
"SMPP[%s]: I/O error or other error. Re-connecting.",
  2389                     time(&last_response);
  2400                     warning(0, 
"Got no responses within %ld sec., reconnecting...",
  2401                             (
long) difftime(time(NULL), last_response));
  2412                     timeout = timeout > tr_timeout ? tr_timeout : timeout;
  2416                     timeout = t < timeout ? t : timeout;
  2419                 if (timeout > 0 && 
conn_wait(conn, timeout) == -1)
  2431                 time(&last_cleanup);
  2448                 time(&last_response);
  2457                 debug(
"bb.sms.smpp", 0, 
"SMPP[%s]: %s: break and shutting down",
  2470             error(0, 
"SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
  2513     if (transmitter && smpp->
receiver != -1) {
  2518         debug(
"bb.smpp", 0, 
"SMSCConn %s shut down.",
  2566     debug(
"bb.smpp", 0, 
"Shutting down SMSCConn %s (%s)",
  2568           finish_sending ? 
"slow" : 
"instant");
  2609     long source_addr_ton;
  2610     long source_addr_npi;
  2614     long our_receiver_port;
  2619     int transceiver_mode;
  2621     long enquire_link_interval;
  2622     long max_pending_submits;
  2626     long smpp_msg_id_type;
  2627     int autodetect_addr;
  2629     Octstr *alt_addr_charset;
  2630     long connection_timeout, wait_ack, wait_ack_action;
  2633     my_number = alt_addr_charset = 
alt_charset = NULL;
  2634     transceiver_mode = 0;
  2635     autodetect_addr = 1;
  2646         our_receiver_port = 0;
  2657     if (system_id != NULL) {
  2658         warning(0, 
"SMPP: obsolete system-id variable is set, "  2659                "use smsc-username instead.");
  2661             warning(0, 
"SMPP: smsc-username not set, using system-id instead");
  2681         error(0, 
"SMPP: Configuration file doesn't specify host");
  2684     if (
port == 0 && receive_port == 0) {
  2686         warning(0, 
"SMPP: Configuration file doesn't specify port or receive-port. "  2687                    "Using 'port = %ld' as default.", 
port);
  2689     if (
port != 0 && receive_port != 0) {
  2690         error(0, 
"SMPP: Configuration file can only have port or receive-port. "  2691                  "Usage of both in one group is deprecated!");
  2695         error(0, 
"SMPP: Configuration file doesn't specify username.");
  2699          error(0, 
"SMPP: Configuration file doesn't specify password.");
  2702     if (system_type == NULL) {
  2703         error(0, 
"SMPP: Configuration file doesn't specify system-type.");
  2707         error(0, 
"SMPP: Service type must be 6 characters or less.");
  2710     if (transceiver_mode && receive_port != 0) {
  2711         warning(0, 
"SMPP: receive-port for transceiver mode defined, ignoring.");
  2721         source_addr_ton = -1;
  2724         source_addr_npi = -1;
  2734         autodetect_addr = 1; 
  2741         version = ((version / 10) << 4) + (version % 10);
  2746     else if (priority < 0 || priority > 3)
  2747         panic(0, 
"SMPP: Invalid value for priority directive in configuraton (allowed range 0-3).");
  2752     else if (validity < 0)
  2753         panic(0, 
"SMPP: Invalid value for validity period (allowed value >= 0).");
  2760         smpp_msg_id_type = -1;
  2762         if (smpp_msg_id_type < 0 || smpp_msg_id_type > 3)
  2763             panic(0,
"SMPP: Invalid value for msg-id-type directive in configuraton");
  2780     else if (wait_ack_action > 0x03 || wait_ack_action < 0)
  2781         panic(0, 
"SMPP: Invalid wait-ack-expire directive in configuration.");
  2789                        source_addr_ton, source_addr_npi, dest_addr_ton,
  2790                        dest_addr_npi, enquire_link_interval,
  2791                        max_pending_submits, version, priority, validity, my_number,
  2792                        smpp_msg_id_type, autodetect_addr, 
alt_charset, alt_addr_charset,
  2793                        service_type, connection_timeout, wait_ack, wait_ack_action, esm_class);
  2805         panic(0, 
"SMPP: Can not use 'use-ssl' without SSL support compiled in.");
  2813                                (!receive_port && transceiver_mode  ? 
port : receive_port),
  2844                                            (transceiver_mode ? 2 : 1)));
  2845     if (receive_port != 0)
  2849         (receive_port != 0 && smpp->
receiver == -1)) {
  2850         error(0, 
"SMPP[%s]: Couldn't start I/O threads.",
 Dict * dict_create(long size_hint, void(*destroy_value)(void *))
 
const char * smpp_error_to_string(enum SMPP_ERROR_MESSAGES error)
 
void smpp_pdu_destroy(SMPP_PDU *pdu)
 
static Connection * open_transmitter(SMPP *smpp)
 
void error(int err, const char *fmt,...)
 
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
 
static long queued_cb(SMSCConn *conn)
 
Msg * msg_duplicate(Msg *msg)
 
static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
 
void bb_smscconn_connected(SMSCConn *conn)
 
int octstr_str_case_compare(const Octstr *ostr, const char *str)
 
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
 
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
 
gw_prioqueue_t * msgs_to_send
 
gw_assert(wtls_machine->packet_to_send !=NULL)
 
void dict_put(Dict *dict, Octstr *key, void *value)
 
void counter_destroy(Counter *counter)
 
void bb_smscconn_killed(void)
 
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
 
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
 
#define DLR_IS_SUCCESS(dlr)
 
struct tm gw_gmtime(time_t t)
 
static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
 
void gwthread_join(long thread)
 
long enquire_link_interval
 
static struct io_arg * io_arg_create(SMPP *smpp, int transmitter)
 
void smpp_tlv_add_constant(Octstr *smsc_id, Dict **tlvs)
 
#define GSM_ADDR_TON_NATIONAL
 
#define SMPP_ENQUIRE_LINK_INTERVAL
 
void charset_utf8_to_gsm(Octstr *ostr)
 
int load_add_interval(Load *load, int interval)
 
#define SMPP_THROTTLING_SLEEP_TIME
 
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
 
#define SMPP_DEFAULT_CONNECTION_TIMEOUT
 
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
 
static Msg * data_sm_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
 
#define cfg_get(grp, varname)
 
#define SMPP_WAITACK_NEVER_EXPIRE
 
Load * load_create_real(int heuristic)
 
#define gw_prioqueue_produce(queue, item)
 
long smpp_pdu_read_len(Connection *conn)
 
static int do_queue_cleanup(SMPP *smpp, long *pending_submits)
 
static struct smpp_msg * smpp_msg_create(Msg *msg)
 
int conn_eof(Connection *conn)
 
time_t throttling_err_time
 
void octstr_strip_blanks(Octstr *text)
 
double load_get(Load *load, int pos)
 
#define SMPP_WAITACK_RECONNECT
 
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
 
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
 
#define octstr_get_cstr(ostr)
 
#define octstr_copy(ostr, from, len)
 
long octstr_search_char(const Octstr *ostr, int ch, long pos)
 
unsigned long counter_increase(Counter *counter)
 
#define GSM_ADDR_TON_INTERNATIONAL
 
Octstr * alt_addr_charset
 
void log_thread_to(int idx)
 
static void io_thread(void *arg)
 
smscconn_killed_t why_killed
 
static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu)
 
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset)
 
static int shutdown_cb(SMSCConn *conn, int finish_sending)
 
void msg_destroy_item(void *msg)
 
Octstr * octstr_imm(const char *cstr)
 
int conn_write(Connection *conn, Octstr *data)
 
int sms_priority_compare(const void *a, const void *b)
 
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
 
void * dict_remove(Dict *dict, Octstr *key)
 
Counter * counter_create(void)
 
#define SMPP_DEFAULT_VERSION
 
static Msg * pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
 
void * gwlist_extract_first(List *list)
 
static int send_unbind(SMPP *smpp, Connection *conn)
 
void * dict_get(Dict *dict, Octstr *key)
 
static void handle_mo_dcs(Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
 
void octstr_delete(Octstr *ostr1, long pos, long len)
 
static long smpp_status_to_smscconn_failure_reason(long status)
 
static void smpp_destroy(SMPP *smpp)
 
#define SMPP_DEFAULT_CHARSET
 
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
 
void conn_destroy(Connection *conn)
 
void octstr_insert_char(Octstr *ostr, long pos, const char c)
 
static int send_msg_cb(SMSCConn *conn, Msg *msg)
 
static SMPP * smpp_create(SMSCConn *conn, Octstr *host, int transmit_port, int receive_port, int our_port, int our_receiver_port, Octstr *system_type, Octstr *username, Octstr *password, Octstr *address_range, int source_addr_ton, int source_addr_npi, int dest_addr_ton, int dest_addr_npi, int enquire_link_interval, int max_pending_submits, int version, int priority, int validity, Octstr *my_number, int smpp_msg_id_type, int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset, Octstr *service_type, long connection_timeout, long wait_ack, int wait_ack_action, int esm_class)
 
#define ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE
 
static Connection * open_transceiver(SMPP *smpp)
 
#define octstr_duplicate(ostr)
 
#define octstr_dump(ostr, level,...)
 
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
 
#define SMPP_DEFAULT_PORT
 
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
 
void msg_destroy(Msg *msg)
 
static int handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits)
 
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
 
void warning(int err, const char *fmt,...)
 
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
 
#define SMPP_MAX_PENDING_SUBMITS
 
Octstr * octstr_format(const char *fmt,...)
 
long gw_prioqueue_len(gw_prioqueue_t *queue)
 
void octstr_destroy(Octstr *ostr)
 
#define gwthread_create(func, arg)
 
#define octstr_create(cstr)
 
void octstr_destroy_item(void *os)
 
int fields_to_dcs(Msg *msg, int mode)
 
gw_prioqueue_t * gw_prioqueue_create(int(*cmp)(const void *, const void *))
 
void gwthread_sleep(double seconds)
 
#define SMS_PARAM_UNDEFINED
 
volatile sig_atomic_t is_stopped
 
int smsc_smpp_create(SMSCConn *conn, CfgGroup *grp)
 
#define DLR_IS_BUFFERED(dlr)
 
long date_universal_now(void)
 
#define SMPP_DEFAULT_UCS2_CHARSET
 
Octstr * smpp_pdu_read_data(Connection *conn, long len)
 
#define load_increase(load)
 
long octstr_len(const Octstr *ostr)
 
#define GSM_ADDR_NPI_UNKNOWN
 
void dict_destroy(Dict *dict)
 
static int send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
 
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
 
void gw_prioqueue_destroy(gw_prioqueue_t *queue, void(*item_destroy)(void *))
 
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
 
static SMPP_PDU * msg_to_pdu(SMPP *smpp, Msg *msg)
 
int conn_wait(Connection *conn, double seconds)
 
static void handle_mt_dcs(Octstr *short_message, char *internal, int data_coding)
 
#define GSM_ADDR_NPI_E164
 
int(* shutdown)(SMSCConn *conn, int finish_sending)
 
#define ESM_CLASS_SUBMIT_RPI
 
void debug(const char *place, int err, const char *fmt,...)
 
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
 
#define SMPP_DEFAULT_WAITACK
 
void gwthread_wakeup(long thread)
 
void load_destroy(Load *load)
 
static Connection * open_receiver(SMPP *smpp)
 
List * dict_keys(Dict *dict)
 
long(* queued)(SMSCConn *conn)
 
#define dump_pdu(msg, id, pdu, format)
 
int(* send_msg)(SMSCConn *conn, Msg *msg)
 
#define SMPP_DEFAULT_PRIORITY
 
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
 
static Msg * handle_dlr(SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state, Octstr *network_error_code)
 
int dcs_to_fields(Msg **msg, int dcs)
 
int conn_error(Connection *conn)
 
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT
 
static int error_from_network_error_code(Octstr *network_error_code)
 
#define GSM_ADDR_TON_ALPHANUMERIC
 
void prepend_catenation_udh(Msg *sms, int part_no, int num_messages, int msg_sequence)
 
static long smscconn_failure_reason_to_smpp_status(long reason)
 
#define SMPP_WAITACK_REQUEUE
 
int octstr_get_char(const Octstr *ostr, long pos)
 
#define DLR_IS_ENABLED_DEVICE(dlr)
 
#define octstr_create_from_data(data, len)
 
static Octstr * alt_charset
 
#define DLR_IS_SUCCESS_OR_FAIL(dlr)
 
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
 
static XMLRPCDocument * msg
 
Counter * message_id_counter
 
static void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
 
Octstr * ssl_client_certkey_file
 
void gw_prioqueue_add_producer(gw_prioqueue_t *queue)
 
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
 
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
 
void charset_gsm_to_utf8(Octstr *ostr)
 
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)