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)