Kannel: Open Source WAP and SMS gateway  svn-r5335
smsc_smpp.c File Reference
#include "gwlib/gwlib.h"
#include "msg.h"
#include "smsc_p.h"
#include "smpp_pdu.h"
#include "smscconn_p.h"
#include "bb_smscconn_cb.h"
#include "sms.h"
#include "dlr.h"
#include "bearerbox.h"
#include "meta_data.h"
#include "load.h"

Go to the source code of this file.

Data Structures

struct  SMPP
 
struct  smpp_msg
 
struct  io_arg
 

Macros

#define SMPP_DEFAULT_CHARSET   "UTF-8"
 
#define SMPP_DEFAULT_UCS2_CHARSET   "UTF-16BE"
 
#define DEBUG   1
 
#define dump_pdu(msg, id, pdu, format)
 
#define SMPP_ENQUIRE_LINK_INTERVAL   30.0
 
#define SMPP_MAX_PENDING_SUBMITS   10
 
#define SMPP_DEFAULT_VERSION   0x34
 
#define SMPP_DEFAULT_PRIORITY   0
 
#define SMPP_THROTTLING_SLEEP_TIME   1
 
#define SMPP_DEFAULT_CONNECTION_TIMEOUT   10 * SMPP_ENQUIRE_LINK_INTERVAL
 
#define SMPP_DEFAULT_WAITACK   60
 
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT   30
 
#define SMPP_DEFAULT_PORT   2775
 
#define SMPP_WAITACK_RECONNECT   0x00
 
#define SMPP_WAITACK_REQUEUE   0x01
 
#define SMPP_WAITACK_NEVER_EXPIRE   0x02
 
#define IS_ACTIVE   (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)
 

Enumerations

enum  smpp_pdu_dump_format { SMPP_PDU_DUMP_MULTILINE = 1, SMPP_PDU_DUMP_LINE = 2 }
 

Functions

static struct smpp_msgsmpp_msg_create (Msg *msg)
 
static void smpp_msg_destroy (struct smpp_msg *msg, int destroy_msg)
 
static SMPPsmpp_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)
 
static void smpp_destroy (SMPP *smpp)
 
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 void handle_mt_dcs (Octstr *short_message, char *internal, int data_coding)
 
static void handle_mo_dcs (Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
 
static Msgpdu_to_msg (SMPP *smpp, SMPP_PDU *pdu, long *reason)
 
static Msgdata_sm_to_msg (SMPP *smpp, SMPP_PDU *pdu, long *reason)
 
static long smpp_status_to_smscconn_failure_reason (long status)
 
static SMPP_PDUmsg_to_pdu (SMPP *smpp, Msg *msg)
 
static int send_enquire_link (SMPP *smpp, Connection *conn, long *last_sent)
 
static int send_gnack (SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
 
static int send_unbind (SMPP *smpp, Connection *conn)
 
static int send_pdu (Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
 
static int send_messages (SMPP *smpp, Connection *conn, long *pending_submits)
 
static Connectionopen_transmitter (SMPP *smpp)
 
static Connectionopen_transceiver (SMPP *smpp)
 
static Connectionopen_receiver (SMPP *smpp)
 
static int error_from_network_error_code (Octstr *network_error_code)
 
static Msghandle_dlr (SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state, Octstr *network_error_code)
 
static long smscconn_failure_reason_to_smpp_status (long reason)
 
static int handle_pdu (SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits)
 
static struct io_argio_arg_create (SMPP *smpp, int transmitter)
 
static int do_queue_cleanup (SMPP *smpp, long *pending_submits)
 
static void io_thread (void *arg)
 
static long queued_cb (SMSCConn *conn)
 
static int send_msg_cb (SMSCConn *conn, Msg *msg)
 
static int shutdown_cb (SMSCConn *conn, int finish_sending)
 
int smsc_smpp_create (SMSCConn *conn, CfgGroup *grp)
 

Macro Definition Documentation

◆ DEBUG

#define DEBUG   1

Definition at line 98 of file smsc_smpp.c.

◆ dump_pdu

#define dump_pdu (   msg,
  id,
  pdu,
  format 
)
Value:
do { \
debug("bb.sms.smpp", 0, "SMPP[%s]: %s", \
smpp_pdu_dump(id, pdu); \
} while(0)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
void smpp_pdu_dump_line(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:816

This version does dump.

Definition at line 104 of file smsc_smpp.c.

Referenced by io_thread(), send_enquire_link(), send_gnack(), send_pdu(), and send_unbind().

◆ IS_ACTIVE

#define IS_ACTIVE   (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)

Referenced by io_thread().

◆ SMPP_DEFAULT_CHARSET

#define SMPP_DEFAULT_CHARSET   "UTF-8"

Definition at line 84 of file smsc_smpp.c.

Referenced by convert_addr_from_pdu(), handle_mo_dcs(), and msg_to_pdu().

◆ SMPP_DEFAULT_CONNECTION_TIMEOUT

#define SMPP_DEFAULT_CONNECTION_TIMEOUT   10 * SMPP_ENQUIRE_LINK_INTERVAL

Definition at line 125 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_DEFAULT_PORT

#define SMPP_DEFAULT_PORT   2775

Definition at line 128 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_DEFAULT_PRIORITY

#define SMPP_DEFAULT_PRIORITY   0

Definition at line 123 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_DEFAULT_SHUTDOWN_TIMEOUT

#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT   30

Definition at line 127 of file smsc_smpp.c.

Referenced by io_thread().

◆ SMPP_DEFAULT_UCS2_CHARSET

#define SMPP_DEFAULT_UCS2_CHARSET   "UTF-16BE"

Definition at line 85 of file smsc_smpp.c.

Referenced by handle_mt_dcs(), and msg_to_pdu().

◆ SMPP_DEFAULT_VERSION

#define SMPP_DEFAULT_VERSION   0x34

Definition at line 122 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_DEFAULT_WAITACK

#define SMPP_DEFAULT_WAITACK   60

Definition at line 126 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_ENQUIRE_LINK_INTERVAL

#define SMPP_ENQUIRE_LINK_INTERVAL   30.0

Definition at line 120 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_MAX_PENDING_SUBMITS

#define SMPP_MAX_PENDING_SUBMITS   10

Definition at line 121 of file smsc_smpp.c.

Referenced by smsc_smpp_create().

◆ SMPP_THROTTLING_SLEEP_TIME

#define SMPP_THROTTLING_SLEEP_TIME   1

Definition at line 124 of file smsc_smpp.c.

Referenced by io_thread().

◆ SMPP_WAITACK_NEVER_EXPIRE

#define SMPP_WAITACK_NEVER_EXPIRE   0x02

Definition at line 136 of file smsc_smpp.c.

Referenced by do_queue_cleanup().

◆ SMPP_WAITACK_RECONNECT

#define SMPP_WAITACK_RECONNECT   0x00

Definition at line 134 of file smsc_smpp.c.

Referenced by do_queue_cleanup().

◆ SMPP_WAITACK_REQUEUE

#define SMPP_WAITACK_REQUEUE   0x01

Definition at line 135 of file smsc_smpp.c.

Referenced by do_queue_cleanup(), and smsc_smpp_create().

Enumeration Type Documentation

◆ smpp_pdu_dump_format

Enumerator
SMPP_PDU_DUMP_MULTILINE 
SMPP_PDU_DUMP_LINE 

Definition at line 87 of file smsc_smpp.c.

Function Documentation

◆ convert_addr_from_pdu()

static long convert_addr_from_pdu ( Octstr id,
Octstr addr,
long  ton,
long  npi,
Octstr alt_addr_charset 
)
static

Definition at line 368 of file smsc_smpp.c.

References charset_convert(), charset_gsm_to_utf8(), error(), GSM_ADDR_TON_ALPHANUMERIC, GSM_ADDR_TON_INTERNATIONAL, gw_isdigit(), octstr_check_range(), octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_insert_char(), octstr_len(), octstr_search(), octstr_str_case_compare(), SMPP_DEFAULT_CHARSET, SMPP_ESME_RINVSRCADR, SMPP_ESME_ROK, and warning().

Referenced by data_sm_to_msg(), and pdu_to_msg().

369 {
370  long reason = SMPP_ESME_ROK;
371 
372  if (addr == NULL)
373  return reason;
374 
375  switch(ton) {
377  /*
378  * Checks to perform:
379  * 1) assume international number has at least 7 chars
380  * 2) the whole source addr consist of digits, exception '+' in front
381  */
382  if (octstr_len(addr) < 7) {
383  /* We consider this as a "non-hard" condition, since there "may"
384  * be international numbers routable that are < 7 digits. Think
385  * of 2 digit country code + 3 digit emergency code. */
386  warning(0, "SMPP[%s]: Malformed addr `%s', generally expected at least 7 digits. ",
387  octstr_get_cstr(id),
388  octstr_get_cstr(addr));
389  } else if (octstr_get_char(addr, 0) == '+' &&
390  !octstr_check_range(addr, 1, 256, gw_isdigit)) {
391  error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ",
392  octstr_get_cstr(id),
393  octstr_get_cstr(addr));
394  reason = SMPP_ESME_RINVSRCADR;
395  goto error;
396  } else if (octstr_get_char(addr, 0) != '+' &&
397  !octstr_check_range(addr, 0, 256, gw_isdigit)) {
398  error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ",
399  octstr_get_cstr(id),
400  octstr_get_cstr(addr));
401  reason = SMPP_ESME_RINVSRCADR;
402  goto error;
403  }
404  /* check if we received leading '00', then remove it*/
405  if (octstr_search(addr, octstr_imm("00"), 0) == 0)
406  octstr_delete(addr, 0, 2);
407 
408  /* international, insert '+' if not already here */
409  if (octstr_get_char(addr, 0) != '+')
410  octstr_insert_char(addr, 0, '+');
411 
412  break;
414  if (octstr_len(addr) > 11) {
415  /* alphanum sender, max. allowed length is 11 (according to GSM specs) */
416  error(0, "SMPP[%s]: Malformed addr `%s', alphanumeric length greater 11 chars. ",
417  octstr_get_cstr(id),
418  octstr_get_cstr(addr));
419  reason = SMPP_ESME_RINVSRCADR;
420  goto error;
421  }
422  if (alt_addr_charset) {
423  if (octstr_str_case_compare(alt_addr_charset, "gsm") == 0)
424  charset_gsm_to_utf8(addr);
425  else if (charset_convert(addr, octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET) != 0)
426  error(0, "Failed to convert address from charset <%s> to <%s>, leave as is.",
427  octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET);
428  }
429  break;
430  default: /* otherwise don't touch addr, user should handle it */
431  break;
432  }
433 
434 error:
435  return reason;
436 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int octstr_str_case_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:986
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define SMPP_DEFAULT_CHARSET
Definition: smsc_smpp.c:84
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1481
int gw_isdigit(int c)
Definition: utils.c:988
void warning(int err, const char *fmt,...)
Definition: log.c:660
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define GSM_ADDR_TON_ALPHANUMERIC
Definition: smasi_pdu.h:107
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
void charset_gsm_to_utf8(Octstr *ostr)
Definition: charset.c:220

◆ data_sm_to_msg()

static Msg* data_sm_to_msg ( SMPP smpp,
SMPP_PDU pdu,
long *  reason 
)
static

Definition at line 731 of file smsc_smpp.c.

References SMPP::alt_addr_charset, SMPP::alt_charset, SMPP::conn, convert_addr_from_pdu(), dcs_to_fields(), debug(), error(), ESM_CLASS_SUBMIT_RPI, ESM_CLASS_SUBMIT_UDH_INDICATOR, gw_assert(), handle_mo_dcs(), smscconn::id, meta_data_set_values(), msg, msg_create, msg_destroy(), octstr_copy, octstr_create, octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_len(), prepend_catenation_udh(), SMPP_ESME_RINVDSTADR, SMPP_ESME_RINVESMCLASS, SMPP_ESME_RINVTLVVAL, SMPP_ESME_ROK, SMPP_PDU::type, SMPP_PDU::u, and SMPP::version.

Referenced by handle_pdu().

732 {
733  Msg *msg;
734  int ton, npi;
735 
736  gw_assert(pdu->type == data_sm);
737 
738  msg = msg_create(sms);
739  gw_assert(msg != NULL);
740  *reason = SMPP_ESME_ROK;
741 
742  /*
743  * Reset source addr to have a prefixed '+' in case we have an
744  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
745  * between national and international numbers.
746  */
747  ton = pdu->u.data_sm.source_addr_ton;
748  npi = pdu->u.data_sm.source_addr_npi;
749  /* check source addr */
750  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
751  goto error;
752  msg->sms.sender = pdu->u.data_sm.source_addr;
753  pdu->u.data_sm.source_addr = NULL;
754 
755  /*
756  * Follows SMPP spec. v3.4. issue 1.2
757  * it's not allowed to have destination_addr NULL
758  */
759  if (pdu->u.data_sm.destination_addr == NULL) {
760  error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. "
761  "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
762  octstr_get_cstr(pdu->u.data_sm.destination_addr));
763  *reason = SMPP_ESME_RINVDSTADR;
764  goto error;
765  }
766 
767  /* Same reset of destination number as for source */
768  ton = pdu->u.data_sm.dest_addr_ton;
769  npi = pdu->u.data_sm.dest_addr_npi;
770  /* check destination addr */
771  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
772  goto error;
773  msg->sms.receiver = pdu->u.data_sm.destination_addr;
774  pdu->u.data_sm.destination_addr = NULL;
775 
776  /* SMSCs use service_type for billing information */
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;
780  } else {
781  msg->sms.binfo = pdu->u.data_sm.service_type;
782  pdu->u.data_sm.service_type = NULL;
783  }
784 
785  /* Foreign ID on MO */
786  msg->sms.foreign_id = pdu->u.data_sm.receipted_message_id;
787  pdu->u.data_sm.receipted_message_id = NULL;
788 
789  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
790  msg->sms.rpi = 1;
791 
792  msg->sms.msgdata = pdu->u.data_sm.message_payload;
793  pdu->u.data_sm.message_payload = NULL;
794 
795  /* check sar_msg_ref_num, sar_segment_seqnum, sar_total_segments */
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) {
797  /*
798  For GSM networks, the concatenation related TLVs (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum)
799  or port addressing related TLVs
800  (source_port, dest_port) cannot be used in conjunction with encoded User Data Header in the short_message
801  (user data) field. This means that the above listed TLVs cannot be used if the User Data Header Indicator flag is set.
802  */
803  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
804  error(0, "SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
805  octstr_get_cstr(smpp->conn->id));
806  *reason = SMPP_ESME_RINVTLVVAL;
807  goto error;
808  }
809  /* create multipart UDH */
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);
814  }
815 
816  /*
817  * Encode udh if udhi set
818  * for reference see GSM03.40, section 9.2.3.24
819  */
820  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
821  int udhl;
822  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
823  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
824  octstr_get_cstr(smpp->conn->id), udhl);
825  if (udhl > octstr_len(msg->sms.msgdata)) {
826  error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "
827  "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
828  udhl, octstr_len(msg->sms.msgdata));
829  *reason = SMPP_ESME_RINVESMCLASS;
830  goto error;
831  }
832  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
833  octstr_delete(msg->sms.msgdata, 0, udhl);
834  }
835 
836  dcs_to_fields(&msg, pdu->u.data_sm.data_coding);
837 
838  /* handle default data coding */
839  handle_mo_dcs(msg, smpp->alt_charset, pdu->u.data_sm.data_coding, pdu->u.data_sm.esm_class);
840 
841  if (msg->sms.meta_data == NULL)
842  msg->sms.meta_data = octstr_create("");
843  meta_data_set_values(msg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 1);
844 
845  return msg;
846 
847 error:
848  msg_destroy(msg);
849  return NULL;
850 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
Octstr * id
Definition: smscconn_p.h:174
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
unsigned long type
Definition: smpp_pdu.h:91
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Octstr * alt_addr_charset
Definition: smsc_smpp.c:180
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset)
Definition: smsc_smpp.c:368
Definition: msg.h:79
Octstr * alt_charset
Definition: smsc_smpp.c:179
static void handle_mo_dcs(Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
Definition: smsc_smpp.c:509
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void msg_destroy(Msg *msg)
Definition: msg.c:132
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
void prepend_catenation_udh(Msg *sms, int part_no, int num_messages, int msg_sequence)
Definition: sms.c:224
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273

◆ do_queue_cleanup()

static int do_queue_cleanup ( SMPP smpp,
long *  pending_submits 
)
static

Definition at line 2246 of file smsc_smpp.c.

References bb_smscconn_send_failed(), SMPP::conn, dict_get(), dict_keys(), dict_remove(), error(), gwlist_destroy(), gwlist_extract_first(), smscconn::id, smpp_msg::msg, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, SMPP::sent_msgs, smpp_msg::sent_time, smpp_msg_destroy(), SMPP_WAITACK_NEVER_EXPIRE, SMPP_WAITACK_RECONNECT, SMPP_WAITACK_REQUEUE, SMSCCONN_FAILED_TEMPORARILY, SMPP::wait_ack, SMPP::wait_ack_action, and warning().

Referenced by io_thread().

2247 {
2248  List *keys;
2249  Octstr *key;
2250  struct smpp_msg *smpp_msg;
2251  time_t now = time(NULL);
2252 
2253  if (*pending_submits <= 0)
2254  return 0;
2255 
2256  /* check if action set to wait ack for ever */
2258  return 0;
2259 
2260  keys = dict_keys(smpp->sent_msgs);
2261  if (keys == NULL)
2262  return 0;
2263 
2264  while ((key = gwlist_extract_first(keys)) != NULL) {
2265  smpp_msg = dict_get(smpp->sent_msgs, key);
2266  if (smpp_msg != NULL && difftime(now, smpp_msg->sent_time) > smpp->wait_ack) {
2267  switch(smpp->wait_ack_action) {
2268  case SMPP_WAITACK_RECONNECT: /* reconnect */
2269  /* found at least one not acked msg */
2270  warning(0, "SMPP[%s]: Not ACKED message found, reconnecting.",
2271  octstr_get_cstr(smpp->conn->id));
2272  octstr_destroy(key);
2274  return 1; /* io_thread will reconnect */
2275  case SMPP_WAITACK_REQUEUE: /* requeue */
2276  smpp_msg = dict_remove(smpp->sent_msgs, key);
2277  if (smpp_msg != NULL) {
2278  warning(0, "SMPP[%s]: Not ACKED message found, will retransmit."
2279  " SENT<%ld>sec. ago, SEQ<%s>, DST<%s>",
2280  octstr_get_cstr(smpp->conn->id),
2281  (long)difftime(now, smpp_msg->sent_time) ,
2282  octstr_get_cstr(key),
2283  octstr_get_cstr(smpp_msg->msg->sms.receiver));
2286  (*pending_submits)--;
2287  }
2288  break;
2289  default:
2290  error(0, "SMPP[%s] Unknown clenup action defined 0x%02x.",
2291  octstr_get_cstr(smpp->conn->id), smpp->wait_ack_action);
2292  octstr_destroy(key);
2294  return 0;
2295  }
2296  }
2297  octstr_destroy(key);
2298  }
2300 
2301  return 0;
2302 }
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
#define SMPP_WAITACK_NEVER_EXPIRE
Definition: smsc_smpp.c:136
#define SMPP_WAITACK_RECONNECT
Definition: smsc_smpp.c:134
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
time_t sent_time
Definition: smsc_smpp.c:193
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * gwlist_extract_first(List *list)
Definition: list.c:305
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
long wait_ack
Definition: smsc_smpp.c:183
Msg * msg
Definition: smsc_smpp.c:194
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
int wait_ack_action
Definition: smsc_smpp.c:184
List * dict_keys(Dict *dict)
Definition: dict.c:347
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
#define SMPP_WAITACK_REQUEUE
Definition: smsc_smpp.c:135
Definition: list.c:102
static void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
Definition: smsc_smpp.c:216
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ error_from_network_error_code()

static int error_from_network_error_code ( Octstr network_error_code)
static

Definition at line 1468 of file smsc_smpp.c.

References octstr_get_cstr, octstr_len(), and type.

Referenced by handle_dlr().

1469 {
1470  unsigned char *nec;
1471  int type;
1472  int err;
1473 
1474  if (network_error_code == NULL || octstr_len(network_error_code) != 3)
1475  return 0;
1476 
1477  nec = (unsigned char*) octstr_get_cstr(network_error_code);
1478  type = nec[0];
1479  err = (nec[1] << 8) | nec[2];
1480 
1481  if ((type >= '0') && (type <= '9')) {
1482  /* this is a bogous SMSC sending back network_error_code as
1483  * 3 digit string instead as in the delivery report. */
1484  sscanf((char*) nec, "%03d", &err);
1485  return err;
1486  }
1487 
1488  return err;
1489 }
int type
Definition: smsc_cimd2.c:215
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ handle_dlr()

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 
)
static

Definition at line 1492 of file smsc_smpp.c.

References SMPP::conn, debug(), DLR_BUFFERED, DLR_EXPIRED, DLR_FAIL, dlr_find(), DLR_SUCCESS, error(), error_from_network_error_code(), gw_isdigit(), smscconn::id, meta_data_set_value(), octstr_check_range(), octstr_compare(), octstr_copy, octstr_create, octstr_create_from_data, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_search(), octstr_search_char(), octstr_strip_blanks(), report_mo, SMPP::smpp_msg_id_type, SMPP::username, SMPP::version, and warning().

Referenced by handle_pdu().

1493 {
1494  Msg *dlrmsg = NULL;
1495  Octstr *respstr = NULL, *msgid = NULL, *network_err = NULL, *dlr_err = NULL, *tmp;
1496  int dlrstat = -1;
1497  int err_int = 0;
1498 
1499  /* first check for SMPP v3.4 and above */
1500  if (smpp->version > 0x33 && receipted_message_id) {
1501  msgid = octstr_duplicate(receipted_message_id);
1502  switch(message_state) {
1503  case 0: /* SCHEDULED, defined in SMPP v5.0, sec. 4.7.15, page 127 */
1504  if (smpp->version == 0x50) /* being very pedantic here */
1505  dlrstat = DLR_BUFFERED;
1506  break;
1507  case 1: /* ENROUTE */
1508  case 6: /* ACCEPTED */
1509  dlrstat = DLR_BUFFERED;
1510  break;
1511  case 2: /* DELIVERED */
1512  dlrstat = DLR_SUCCESS;
1513  break;
1514  case 3: /* EXPIRED */
1515  dlrstat = DLR_EXPIRED;
1516  break;
1517  case 4: /* DELETED */
1518  case 5: /* UNDELIVERABLE */
1519  case 7: /* UNKNOWN */
1520  case 8: /* REJECTED */
1521  dlrstat = DLR_FAIL;
1522  break;
1523  case 9: /* SKIPPED, defined in SMPP v5.0, sec. 4.7.15, page 127 */
1524  if (smpp->version == 0x50)
1525  dlrstat = DLR_FAIL;
1526  break;
1527  case -1: /* message state is not present, partial SMPP v3.4 */
1528  debug("bb.sms.smpp", 0, "SMPP[%s]: Partial SMPP v3.4, receipted_message_id present but not message_state.",
1529  octstr_get_cstr(smpp->conn->id));
1530  dlrstat = -1;
1531  break;
1532  default:
1533  warning(0, "SMPP[%s]: Got DLR with unknown 'message_state' (%ld).",
1534  octstr_get_cstr(smpp->conn->id), message_state);
1535  dlrstat = DLR_FAIL;
1536  break;
1537  }
1538  }
1539 
1540  if (network_error_code != NULL) {
1541  err_int = error_from_network_error_code(network_error_code);
1542  network_err = octstr_duplicate(network_error_code);
1543  }
1544 
1545  /* check for SMPP v.3.4. and message_payload */
1546  if (smpp->version > 0x33 && octstr_len(short_message) == 0)
1547  respstr = message_payload;
1548  else
1549  respstr = short_message;
1550 
1551  if (msgid == NULL || network_err == NULL || dlrstat == -1) {
1552  /* parse the respstr if it exists */
1553  if (respstr) {
1554  long curr = 0, vpos = 0;
1555  Octstr *stat = NULL;
1556  char id_cstr[65], stat_cstr[16], sub_d_cstr[15], done_d_cstr[15];
1557  char err_cstr[4];
1558  int sub, dlrvrd, ret;
1559 
1560  /* get server message id */
1561  /* first try sscanf way if thus failed then old way */
1562  ret = sscanf(octstr_get_cstr(respstr),
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);
1567  if (ret == 7) {
1568  /* only if not already here */
1569  if (msgid == NULL) {
1570  msgid = octstr_create(id_cstr);
1571  octstr_strip_blanks(msgid);
1572  }
1573  stat = octstr_create(stat_cstr);
1574  octstr_strip_blanks(stat);
1575  sscanf(err_cstr, "%d", &err_int);
1576  dlr_err = octstr_create(err_cstr);
1577  octstr_strip_blanks(dlr_err);
1578  } else {
1579  debug("bb.sms.smpp", 0, "SMPP[%s]: Could not parse DLR string sscanf way, "
1580  "fallback to old way. Please report!", octstr_get_cstr(smpp->conn->id));
1581 
1582  /* only if not already here */
1583  if (msgid == NULL) {
1584  if ((curr = octstr_search(respstr, octstr_imm("id:"), 0)) != -1) {
1585  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1586  vpos = octstr_len(respstr);
1587  if (vpos-curr > 0)
1588  msgid = octstr_copy(respstr, curr+3, vpos-curr-3);
1589  }
1590  }
1591 
1592  /* get err & status code */
1593  if ((curr = octstr_search(respstr, octstr_imm("stat:"), 0)) != -1) {
1594  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1595  vpos = octstr_len(respstr);
1596  if (vpos-curr > 0)
1597  stat = octstr_copy(respstr, curr+5, vpos-curr-5);
1598  } else {
1599  stat = NULL;
1600  }
1601  if ((curr = octstr_search(respstr, octstr_imm("err:"), 0)) != -1) {
1602  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1603  vpos = octstr_len(respstr);
1604  if (vpos-curr > 0)
1605  dlr_err = octstr_copy(respstr, curr+4, vpos-curr-4);
1606  } else {
1607  dlr_err = NULL;
1608  }
1609  }
1610 
1611  /*
1612  * we get the following status:
1613  * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD
1614  *
1615  * Note: some buggy SMSC's send us immediately delivery notifications although
1616  * we doesn't requested these.
1617  */
1618  if (dlrstat == -1) {
1619  if (stat != NULL && octstr_compare(stat, octstr_imm("DELIVRD")) == 0)
1620  dlrstat = DLR_SUCCESS;
1621  else if (stat != NULL && (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0 ||
1622  octstr_compare(stat, octstr_imm("ACKED")) == 0 ||
1623  octstr_compare(stat, octstr_imm("BUFFRED")) == 0 ||
1624  octstr_compare(stat, octstr_imm("BUFFERD")) == 0 ||
1625  octstr_compare(stat, octstr_imm("ENROUTE")) == 0))
1626  dlrstat = DLR_BUFFERED;
1627  else
1628  dlrstat = DLR_FAIL;
1629  }
1630  octstr_destroy(stat);
1631  }
1632  }
1633 
1634  if (msgid != NULL && dlrstat != -1) {
1635  /*
1636  * Obey which SMPP msg_id type this SMSC is using, where we
1637  * have the following semantics for the variable smpp_msg_id:
1638  *
1639  * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm
1640  *
1641  * if bit is set value is hex otherwise dec
1642  *
1643  * 0x00 deliver_sm dec, submit_sm_resp dec
1644  * 0x01 deliver_sm dec, submit_sm_resp hex
1645  * 0x02 deliver_sm hex, submit_sm_resp dec
1646  * 0x03 deliver_sm hex, submit_sm_resp hex
1647  *
1648  * Default behaviour is SMPP spec compliant, which means
1649  * msg_ids should be C strings and hence non modified.
1650  */
1651  if (smpp->smpp_msg_id_type == -1) {
1652  /* the default, C string */
1653  tmp = octstr_duplicate(msgid);
1654  } else {
1655  if ((smpp->smpp_msg_id_type & 0x02) ||
1656  (!octstr_check_range(msgid, 0, octstr_len(msgid), gw_isdigit))) {
1657  tmp = octstr_format("%llu", strtoll(octstr_get_cstr(msgid), NULL, 16));
1658  } else {
1659  tmp = octstr_format("%llu", strtoll(octstr_get_cstr(msgid), NULL, 10));
1660  }
1661  }
1662 
1663  dlrmsg = dlr_find(smpp->conn->id,
1664  tmp, /* smsc message id */
1665  destination_addr, /* destination */
1666  dlrstat, 0);
1667 
1668  octstr_destroy(msgid);
1669  } else
1670  tmp = octstr_create("");
1671 
1672  if (network_err == NULL && dlr_err != NULL) {
1673  unsigned char ctmp[3];
1674 
1675  ctmp[0] = 3; /* we assume here its a GSM error due to lack of other information */
1676  ctmp[1] = (err_int >> 8) & 0xFF;
1677  ctmp[2] = (err_int & 0xFF);
1678  network_err = octstr_create_from_data((char*)ctmp, 3);
1679  }
1680 
1681  if (dlrmsg != NULL) {
1682  /*
1683  * we found the delivery report in our storage, so recode the
1684  * message structure.
1685  * The DLR trigger URL is indicated by msg->sms.dlr_url.
1686  * Add the DLR error code to meta-data.
1687  */
1688  dlrmsg->sms.msgdata = octstr_duplicate(respstr);
1689  dlrmsg->sms.sms_type = report_mo;
1690  dlrmsg->sms.account = octstr_duplicate(smpp->username);
1691  if (network_err != NULL) {
1692  if (dlrmsg->sms.meta_data == NULL) {
1693  dlrmsg->sms.meta_data = octstr_create("");
1694  }
1695  meta_data_set_value(dlrmsg->sms.meta_data, "smpp", octstr_imm("dlr_err"), network_err, 1);
1696  }
1697  } else {
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>",
1700  octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp),
1701  octstr_get_cstr(destination_addr), dlrstat);
1702  }
1703  octstr_destroy(tmp);
1704  octstr_destroy(network_err);
1705  octstr_destroy(dlr_err);
1706 
1707  return dlrmsg;
1708 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
Definition: msg.h:109
Octstr * id
Definition: smscconn_p.h:174
int meta_data_set_value(Octstr *data, const char *group, const Octstr *key, const Octstr *value, int replace)
Definition: meta_data.c:324
SMSCConn * conn
Definition: smsc_smpp.c:188
#define DLR_EXPIRED
Definition: dlr.h:77
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
int version
Definition: smsc_smpp.c:173
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
Definition: dlr.c:387
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
#define DLR_SUCCESS
Definition: dlr.h:72
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
int smpp_msg_id_type
Definition: smsc_smpp.c:177
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int gw_isdigit(int c)
Definition: utils.c:988
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define DLR_BUFFERED
Definition: dlr.h:74
Octstr * username
Definition: smsc_smpp.c:153
static int error_from_network_error_code(Octstr *network_error_code)
Definition: smsc_smpp.c:1468
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
#define DLR_FAIL
Definition: dlr.h:73
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ handle_mo_dcs()

static void handle_mo_dcs ( Msg msg,
Octstr alt_charset,
int  data_coding,
int  esm_class 
)
static

Definition at line 509 of file smsc_smpp.c.

References alt_charset, charset_convert(), charset_gsm_to_utf8(), DC_7BIT, DC_8BIT, DC_UCS2, DC_UNDEF, error(), ESM_CLASS_SUBMIT_UDH_INDICATOR, msg, octstr_get_cstr, and SMPP_DEFAULT_CHARSET.

Referenced by data_sm_to_msg(), and pdu_to_msg().

510 {
511  switch (data_coding) {
512  case 0x00: /* default SMSC alphabet */
513  /*
514  * try to convert from something interesting if specified so
515  * unless it was specified binary, i.e. UDH indicator was detected
516  */
517  if (alt_charset && msg->sms.coding != DC_8BIT) {
519  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
521  msg->sms.coding = DC_7BIT;
522  } else { /* assume GSM 03.38 7-bit alphabet */
523  charset_gsm_to_utf8(msg->sms.msgdata);
524  msg->sms.coding = DC_7BIT;
525  }
526  break;
527  case 0x01:
528  /* ASCII/IA5 - we don't need to perform any conversion
529  * due that UTF-8's first range is exactly the ASCII table */
530  msg->sms.coding = DC_7BIT; break;
531  case 0x03: /* ISO-8859-1 - I'll convert to internal encoding */
532  if (charset_convert(msg->sms.msgdata, "ISO-8859-1", SMPP_DEFAULT_CHARSET) != 0)
533  error(0, "Failed to convert msgdata from ISO-8859-1 to " SMPP_DEFAULT_CHARSET ", will leave as is");
534  msg->sms.coding = DC_7BIT; break;
535  case 0x02: /* 8 bit binary - do nothing */
536  case 0x04: /* 8 bit binary - do nothing */
537  msg->sms.coding = DC_8BIT; break;
538  case 0x05: /* Japanese, JIS(X 0208-1990) */
539  if (charset_convert(msg->sms.msgdata, "JIS_X0208-1990", SMPP_DEFAULT_CHARSET) != 0)
540  error(0, "Failed to convert msgdata from Japanese (JIS_X0208-1990) to " SMPP_DEFAULT_CHARSET ", will leave as is");
541  msg->sms.coding = DC_7BIT; break;
542  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to internal encoding */
543  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", SMPP_DEFAULT_CHARSET) != 0)
544  error(0, "Failed to convert msgdata from Cyrllic (ISO-8859-5) to " SMPP_DEFAULT_CHARSET ", will leave as is");
545  msg->sms.coding = DC_7BIT; break;
546  case 0x07: /* Hebrew iso-8859-8, I'll convert to internal encoding */
547  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", SMPP_DEFAULT_CHARSET) != 0)
548  error(0, "Failed to convert msgdata from Hebrew (ISO-8859-8) to " SMPP_DEFAULT_CHARSET ", will leave as is");
549  msg->sms.coding = DC_7BIT; break;
550  case 0x08: /* unicode UCS-2, yey */
551  msg->sms.coding = DC_UCS2; break;
552  case 0x0D: /* Japanese, Extended Kanji JIS(X 0212-1990) */
553  if (charset_convert(msg->sms.msgdata, "JIS_X0212-1990", SMPP_DEFAULT_CHARSET) != 0)
554  error(0, "Failed to convert msgdata from Japanese (JIS-X0212-1990) to " SMPP_DEFAULT_CHARSET ", will leave as is");
555  msg->sms.coding = DC_7BIT; break;
556  case 0x0E: /* Korean, KS C 5601 - now called KS X 1001, convert to Unicode */
557  if (charset_convert(msg->sms.msgdata, "KSC_5601", SMPP_DEFAULT_CHARSET) != 0 &&
558  charset_convert(msg->sms.msgdata, "KSC5636", SMPP_DEFAULT_CHARSET) != 0)
559  error(0, "Failed to convert msgdata from Korean (KSC_5601/KSC5636) to " SMPP_DEFAULT_CHARSET ", will leave as is");
560  msg->sms.coding = DC_7BIT; break;
561 
562  /*
563  * don't much care about the others,
564  * you implement them if you feel like it
565  */
566 
567  default:
568  /*
569  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
570  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
571  * if we have an UDH indicator, we assume DC_8BIT.
572  */
573  if (msg->sms.coding == DC_UNDEF && (esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR))
574  msg->sms.coding = DC_8BIT;
575  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , re-encode */
576  msg->sms.coding = DC_7BIT;
577  charset_gsm_to_utf8(msg->sms.msgdata);
578  }
579  break;
580  }
581 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
#define DC_8BIT
Definition: sms.h:111
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define SMPP_DEFAULT_CHARSET
Definition: smsc_smpp.c:84
#define DC_UNDEF
Definition: sms.h:109
static Octstr * alt_charset
Definition: opensmppbox.c:129
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DC_UCS2
Definition: sms.h:112
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
void charset_gsm_to_utf8(Octstr *ostr)
Definition: charset.c:220

◆ handle_mt_dcs()

static void handle_mt_dcs ( Octstr short_message,
char *  internal,
int  data_coding 
)
static

Definition at line 439 of file smsc_smpp.c.

References charset_convert(), charset_utf8_to_gsm(), error(), and SMPP_DEFAULT_UCS2_CHARSET.

Referenced by msg_to_pdu().

440 {
441  /*
442  * Keep in mind that we do transcode the encoding here,
443  * but effectively we're limited to the GSM 03.38 alphabet character
444  * range, since we do a round-trip conversion from/to UTF-8/GSM in
445  * function gw/sms.c:extract_msgdata_part_by_coding().
446  *
447  * If your underlying radio network is NOT GSM, and you want to support
448  * the extended range of characters of the tables, then remove the
449  * round-trip conversion from the above mentioned function.
450  */
451  switch (data_coding) {
452  case 0x01: /* ASCII or IA5 */
453  if (charset_convert(short_message, internal, "ASCII") != 0) {
454  error(0, "Failed to convert msgdata from %s to ASCII, will leave as is", internal);
455  }
456  break;
457  case 0x03: /* ISO-8859-1 (aka latin1) */
458  if (charset_convert(short_message, internal, "LATIN1") != 0) {
459  error(0, "Failed to convert msgdata from %s to LATIN1, will leave as is", internal);
460  }
461  break;
462  case 0x02: /* 8 bit binary - do nothing */
463  case 0x04: /* 8 bit binary - do nothing */
464  break;
465  case 0x05: /* Japanese, JIS(X 0208-1990) */
466  if (charset_convert(short_message, internal, "JIS_X0208-1990") != 0)
467  error(0, "Failed to convert msgdata from %s to Japanese (JIS-X0208-1990), "
468  "will leave as is", internal);
469  break;
470  case 0x06: /* Cyrllic - iso-8859-5 */
471  if (charset_convert(short_message, internal, "ISO-8859-5") != 0)
472  error(0, "Failed to convert msgdata from %s to Cyrllic (ISO-8859-5), "
473  "will leave as is", internal);
474  break;
475  case 0x07: /* Hebrew iso-8859-8 */
476  if (charset_convert(short_message, internal, "ISO-8859-8") != 0)
477  error(0, "Failed to convert msgdata from %s to Hebrew (ISO-8859-8), "
478  "will leave as is", internal);
479  break;
480  case 0x08: /* unicode UCS-2 */
481  if (charset_convert(short_message, internal, SMPP_DEFAULT_UCS2_CHARSET) != 0)
482  error(0, "Failed to convert msgdata from %s to Unicode (UTF-16BE), "
483  "will leave as is", internal);
484  break;
485  case 0x0D: /* Japanese, Extended Kanji JIS(X 0212-1990) */
486  if (charset_convert(short_message, internal, "JIS_X0212-1990") != 0)
487  error(0, "Failed to convert msgdata from %s to Japanese (JIS-X0212-1990), "
488  "will leave as is", internal);
489  break;
490  case 0x0E: /* Korean, KS C 5601 - now called KS X 1001, convert to Unicode */
491  if (charset_convert(short_message, internal, "KSC_5601") != 0 &&
492  charset_convert(short_message, internal, "KSC5636") != 0)
493  error(0, "Failed to convert msgdata from %s to Korean (KSC_5601/KSC5636), "
494  "will leave as is", internal);
495  break;
496  case 0x00: /* GSM 03.38 */
497  default:
498  charset_utf8_to_gsm(short_message);
499  break;
500 
501  /*
502  * don't much care about the others,
503  * you implement them if you feel like it
504  */
505  }
506 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void charset_utf8_to_gsm(Octstr *ostr)
Definition: charset.c:288
#define SMPP_DEFAULT_UCS2_CHARSET
Definition: smsc_smpp.c:85
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589

◆ handle_pdu()

static int handle_pdu ( SMPP smpp,
Connection conn,
SMPP_PDU pdu,
long *  pending_submits 
)
static

Definition at line 1726 of file smsc_smpp.c.

References bb_alog_sms(), bb_smscconn_connected(), bb_smscconn_receive(), bb_smscconn_send_failed(), bb_smscconn_sent(), SMPP::conn, smscconn::connect_time, data_sm_to_msg(), debug(), dict_remove(), dlr_add(), DLR_IS_ENABLED_DEVICE, error(), smscconn::flow_mutex, gw_isdigit(), handle_dlr(), smscconn::id, smscconn::is_stopped, meta_data_set_values(), msg, smpp_msg::msg, msg_destroy(), mutex_lock, mutex_unlock, SMPP::my_number, octstr_check_range(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_len(), pdu_to_msg(), SMPP::quitting, SMPP::retry, send_gnack(), send_pdu(), SMPP::sent_msgs, smpp_error_to_string(), SMPP_ESME_RALYBND, SMPP_ESME_RINVCMDID, SMPP_ESME_RINVPASWD, SMPP_ESME_RINVSYSID, SMPP_ESME_RINVSYSTYP, SMPP_ESME_ROK, SMPP_ESME_RTHROTTLED, SMPP_ESME_RX_T_APPN, smpp_msg_destroy(), SMPP::smpp_msg_id_type, smpp_pdu_create(), smpp_pdu_destroy(), smpp_status_to_smscconn_failure_reason(), SMSCCONN_ACTIVE, SMSCCONN_ACTIVE_RECV, SMSCCONN_DISCONNECTED, smscconn_failure_reason_to_smpp_status(), SMSCCONN_SUCCESS, smscconn::status, SMPP::throttling_err_time, SMPP_PDU::type, SMPP_PDU::type_name, SMPP_PDU::u, SMPP::username, and warning().

Referenced by io_thread().

1728 {
1729  SMPP_PDU *resp = NULL;
1730  Octstr *os;
1731  Msg *msg = NULL, *dlrmsg=NULL;
1732  struct smpp_msg *smpp_msg = NULL;
1733  long reason, cmd_stat;
1734  int ret = 0;
1735 
1736  /*
1737  * In order to keep the protocol implementation logically clean,
1738  * we will obey the required SMPP session state while processing
1739  * the PDUs, see Table 2-1, SMPP v3.4 spec, section 2.3, page 17.
1740  * Therefore we will interpret our abstracted smpp->conn->status
1741  * value as SMPP session state here.
1742  */
1743  switch (pdu->type) {
1744  case data_sm:
1745  /*
1746  * Session state check
1747  */
1748  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1749  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1750  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1751  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1752  return 0;
1753  }
1754  resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);
1755  /*
1756  * If SMSCConn stopped then send temp. error code
1757  */
1758  mutex_lock(smpp->conn->flow_mutex);
1759  if (smpp->conn->is_stopped) {
1760  mutex_unlock(smpp->conn->flow_mutex);
1761  resp->u.data_sm_resp.command_status = SMPP_ESME_RX_T_APPN;
1762  break;
1763  }
1764  mutex_unlock(smpp->conn->flow_mutex);
1765  /* got a deliver ack (DLR)?
1766  * NOTE: following SMPP v3.4. spec. we are interested
1767  * only on bits 2-5 (some SMSC's send 0x44, and it's
1768  * spec. conforme)
1769  */
1770  if (pdu->u.data_sm.esm_class & (0x04|0x08|0x20)) {
1771  debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
1772  octstr_get_cstr(smpp->conn->id));
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)
1777  dlrmsg->sms.meta_data = octstr_create("");
1778  meta_data_set_values(dlrmsg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 0);
1779  /* passing DLR to upper layer */
1780  reason = bb_smscconn_receive(smpp->conn, dlrmsg);
1781  } else {
1782  /* no DLR will be passed, but we write an access-log entry */
1783  msg = data_sm_to_msg(smpp, pdu, &reason);
1784  if (msg == NULL || reason != SMPP_ESME_ROK) {
1785  resp->u.data_sm_resp.command_status = reason;
1786  break;
1787  }
1788  reason = SMSCCONN_SUCCESS;
1789  bb_alog_sms(smpp->conn, msg, "FAILED Receive DLR");
1790  msg_destroy(msg);
1791  }
1792  resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1793  } else { /* MO message */
1794  msg = data_sm_to_msg(smpp, pdu, &reason);
1795  if (msg == NULL || reason != SMPP_ESME_ROK) {
1796  resp->u.data_sm_resp.command_status = reason;
1797  break;
1798  }
1799  /* Replace MO destination number with my-number */
1800  if (octstr_len(smpp->my_number)) {
1801  octstr_destroy(msg->sms.receiver);
1802  msg->sms.receiver = octstr_duplicate(smpp->my_number);
1803  }
1804  time(&msg->sms.time);
1805  msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
1806  reason = bb_smscconn_receive(smpp->conn, msg);
1807  resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1808  }
1809  break;
1810 
1811  case deliver_sm:
1812  /*
1813  * Session state check
1814  */
1815  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1816  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1817  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1818  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1819  return 0;
1820  }
1821 
1822  /*
1823  * If SMSCConn stopped then send temp. error code
1824  */
1825  mutex_lock(smpp->conn->flow_mutex);
1826  if (smpp->conn->is_stopped) {
1827  mutex_unlock(smpp->conn->flow_mutex);
1828  resp = smpp_pdu_create(deliver_sm_resp,
1829  pdu->u.deliver_sm.sequence_number);
1830  resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_T_APPN;
1831  break;
1832  }
1833  mutex_unlock(smpp->conn->flow_mutex);
1834 
1835  /*
1836  * Got a deliver ack (DLR)?
1837  * NOTE: following SMPP v3.4. spec. we are interested
1838  * only on bits 2-5 (some SMSC's send 0x44, and it's
1839  * spec. conforme)
1840  */
1841  if (pdu->u.deliver_sm.esm_class & (0x04|0x08|0x20)) {
1842 
1843  debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
1844  octstr_get_cstr(smpp->conn->id));
1845 
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)
1851  dlrmsg->sms.meta_data = octstr_create("");
1852  meta_data_set_values(dlrmsg->sms.meta_data, pdu->u.deliver_sm.tlv, "smpp", 0);
1853  /* passing DLR to upper layer */
1854  reason = bb_smscconn_receive(smpp->conn, dlrmsg);
1855  } else {
1856  /* no DLR will be passed, but we write an access-log entry */
1857  msg = pdu_to_msg(smpp, pdu, &reason);
1858  if (msg == NULL) {
1859  resp->u.deliver_sm_resp.command_status = reason;
1860  break;
1861  }
1862  reason = SMSCCONN_SUCCESS;
1863  bb_alog_sms(smpp->conn, msg, "FAILED Receive DLR");
1864  msg_destroy(msg);
1865  }
1866  resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1867  } else {/* MO-SMS */
1868  resp = smpp_pdu_create(deliver_sm_resp,
1869  pdu->u.deliver_sm.sequence_number);
1870  /* ensure the smsc-id is set */
1871  msg = pdu_to_msg(smpp, pdu, &reason);
1872  if (msg == NULL) {
1873  resp->u.deliver_sm_resp.command_status = reason;
1874  break;
1875  }
1876 
1877  /* Replace MO destination number with my-number */
1878  if (octstr_len(smpp->my_number)) {
1879  octstr_destroy(msg->sms.receiver);
1880  msg->sms.receiver = octstr_duplicate(smpp->my_number);
1881  }
1882 
1883  time(&msg->sms.time);
1884  msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
1885  msg->sms.account = octstr_duplicate(smpp->username);
1886  reason = bb_smscconn_receive(smpp->conn, msg);
1887  resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1888  }
1889  break;
1890 
1891  case enquire_link:
1892  /*
1893  * Session state check
1894  */
1895  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1896  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1897  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1898  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1899  return 0;
1900  }
1901  resp = smpp_pdu_create(enquire_link_resp,
1902  pdu->u.enquire_link.sequence_number);
1903  break;
1904 
1905  case enquire_link_resp:
1906  /*
1907  * Session state check
1908  */
1909  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1910  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1911  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1912  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1913  return 0;
1914  }
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).",
1917  octstr_get_cstr(smpp->conn->id),
1918  pdu->u.enquire_link_resp.command_status,
1919  smpp_error_to_string(pdu->u.enquire_link_resp.command_status));
1920  }
1921  break;
1922 
1923  case submit_sm_resp:
1924  /*
1925  * Session state check
1926  */
1927  if (!(smpp->conn->status == SMSCCONN_ACTIVE)) {
1928  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1929  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1930  return 0;
1931  }
1932 
1933  os = octstr_format("%ld", pdu->u.submit_sm_resp.sequence_number);
1934  smpp_msg = dict_remove(smpp->sent_msgs, os);
1935  octstr_destroy(os);
1936  if (smpp_msg == NULL) {
1937  warning(0, "SMPP[%s]: SMSC sent submit_sm_resp PDU "
1938  "with wrong sequence number 0x%08lx",
1939  octstr_get_cstr(smpp->conn->id),
1940  pdu->u.submit_sm_resp.sequence_number);
1941  break;
1942  }
1943  msg = smpp_msg->msg;
1945 
1946  /* pack submit_sm_resp TLVs into metadata */
1947  if (msg->sms.meta_data == NULL)
1948  msg->sms.meta_data = octstr_create("");
1949  meta_data_set_values(msg->sms.meta_data, pdu->u.submit_sm_resp.tlv, "smpp_resp", 1);
1950 
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.",
1954  octstr_get_cstr(smpp->conn->id),
1955  pdu->u.submit_sm_resp.command_status,
1956  smpp_error_to_string(pdu->u.submit_sm_resp.command_status));
1958  pdu->u.submit_sm_resp.command_status);
1959 
1960  /*
1961  * check to see if we got a "throttling error", in which case we'll just
1962  * sleep for a while
1963  */
1964  if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
1965  time(&(smpp->throttling_err_time));
1966  else
1967  smpp->throttling_err_time = 0;
1968 
1969  bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
1970  smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
1971  --(*pending_submits);
1972  }
1973  else if (pdu->u.submit_sm_resp.message_id != NULL) {
1974  Octstr *tmp;
1975 
1976  /* check if msg_id is C string, decimal or hex for this SMSC */
1977  if (smpp->smpp_msg_id_type == -1) {
1978  /* the default, C string */
1979  tmp = octstr_duplicate(pdu->u.submit_sm_resp.message_id);
1980  } else {
1981  if ((smpp->smpp_msg_id_type & 0x01) ||
1982  (!octstr_check_range(pdu->u.submit_sm_resp.message_id, 0,
1983  octstr_len(pdu->u.submit_sm_resp.message_id), gw_isdigit))) {
1984  tmp = octstr_format("%llu", strtoll( /* hex */
1985  octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 16));
1986  } else {
1987  tmp = octstr_format("%llu", strtoll( /* decimal */
1988  octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 10));
1989  }
1990  }
1991 
1992  /*
1993  * SMSC ACK.. now we have the message ID.
1994  * The message ID is inserted into the msg struct in dlr_add(),
1995  * and we add it manually here if no DLR was requested, in
1996  * order to get it logged to access-log.
1997  */
1998  if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {
1999  dlr_add(smpp->conn->id, tmp, msg, 0);
2000  octstr_destroy(tmp);
2001  } else {
2002  octstr_destroy(msg->sms.foreign_id);
2003  msg->sms.foreign_id = tmp;
2004  }
2005 
2006  bb_smscconn_sent(smpp->conn, msg, NULL);
2007  --(*pending_submits);
2008  } /* end if for SMSC ACK */
2009  else {
2010  error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
2011  "in response to submit_sm PDU, but no `message_id' value!",
2012  octstr_get_cstr(smpp->conn->id),
2013  pdu->u.submit_sm_resp.command_status,
2014  smpp_error_to_string(pdu->u.submit_sm_resp.command_status));
2015  bb_smscconn_sent(smpp->conn, msg, NULL);
2016  --(*pending_submits);
2017  }
2018  break;
2019 
2020  case bind_transmitter_resp:
2021  /*
2022  * Session state check
2023  */
2024  if (smpp->conn->status == SMSCCONN_ACTIVE ||
2025  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
2026  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
2027  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2028  return 0;
2029  }
2030  if (pdu->u.bind_transmitter_resp.command_status != 0 &&
2031  pdu->u.bind_transmitter_resp.command_status != SMPP_ESME_RALYBND) {
2032  error(0, "SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
2033  octstr_get_cstr(smpp->conn->id),
2034  pdu->u.bind_transmitter_resp.command_status,
2035  smpp_error_to_string(pdu->u.bind_transmitter_resp.command_status));
2036  mutex_lock(smpp->conn->flow_mutex);
2038  mutex_unlock(smpp->conn->flow_mutex);
2039  if (!smpp->retry &&
2040  (pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSID ||
2041  pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVPASWD ||
2042  pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSTYP)) {
2043  smpp->quitting = 1;
2044  }
2045  } else {
2046  *pending_submits = 0;
2047  mutex_lock(smpp->conn->flow_mutex);
2048  smpp->conn->status = SMSCCONN_ACTIVE;
2049  time(&smpp->conn->connect_time);
2050  mutex_unlock(smpp->conn->flow_mutex);
2051  bb_smscconn_connected(smpp->conn);
2052  }
2053  break;
2054 
2055  case bind_transceiver_resp:
2056  /*
2057  * Session state check
2058  */
2059  if (smpp->conn->status == SMSCCONN_ACTIVE ||
2060  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
2061  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
2062  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2063  return 0;
2064  }
2065  if (pdu->u.bind_transceiver_resp.command_status != 0 &&
2066  pdu->u.bind_transceiver_resp.command_status != SMPP_ESME_RALYBND) {
2067  error(0, "SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
2068  octstr_get_cstr(smpp->conn->id),
2069  pdu->u.bind_transceiver_resp.command_status,
2070  smpp_error_to_string(pdu->u.bind_transceiver_resp.command_status));
2071  mutex_lock(smpp->conn->flow_mutex);
2073  mutex_unlock(smpp->conn->flow_mutex);
2074  if (!smpp->retry &&
2075  (pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSID ||
2076  pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVPASWD ||
2077  pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSTYP)) {
2078  smpp->quitting = 1;
2079  }
2080  } else {
2081  *pending_submits = 0;
2082  mutex_lock(smpp->conn->flow_mutex);
2083  smpp->conn->status = SMSCCONN_ACTIVE;
2084  time(&smpp->conn->connect_time);
2085  mutex_unlock(smpp->conn->flow_mutex);
2086  bb_smscconn_connected(smpp->conn);
2087  }
2088  break;
2089 
2090  case bind_receiver_resp:
2091  /*
2092  * Session state check
2093  */
2094  if (smpp->conn->status == SMSCCONN_ACTIVE ||
2095  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
2096  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
2097  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2098  return 0;
2099  }
2100  if (pdu->u.bind_receiver_resp.command_status != 0 &&
2101  pdu->u.bind_receiver_resp.command_status != SMPP_ESME_RALYBND) {
2102  error(0, "SMPP[%s]: SMSC rejected login to receive, code 0x%08lx (%s).",
2103  octstr_get_cstr(smpp->conn->id),
2104  pdu->u.bind_receiver_resp.command_status,
2105  smpp_error_to_string(pdu->u.bind_receiver_resp.command_status));
2106  mutex_lock(smpp->conn->flow_mutex);
2108  mutex_unlock(smpp->conn->flow_mutex);
2109  if (!smpp->retry &&
2110  (pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSID ||
2111  pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVPASWD ||
2112  pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSTYP)) {
2113  smpp->quitting = 1;
2114  }
2115  } else {
2116  /* set only receive status if no transmit is bind */
2117  mutex_lock(smpp->conn->flow_mutex);
2118  if (smpp->conn->status != SMSCCONN_ACTIVE) {
2119  smpp->conn->status = SMSCCONN_ACTIVE_RECV;
2120  time(&smpp->conn->connect_time);
2121  }
2122  mutex_unlock(smpp->conn->flow_mutex);
2123  }
2124  break;
2125 
2126  case unbind:
2127  /*
2128  * Session state check
2129  */
2130  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2131  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2132  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2133  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2134  return 0;
2135  }
2136  resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
2137  mutex_lock(smpp->conn->flow_mutex);
2139  mutex_unlock(smpp->conn->flow_mutex);
2140  *pending_submits = -1;
2141  break;
2142 
2143  case unbind_resp:
2144  /*
2145  * Session state check
2146  */
2147  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2148  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2149  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2150  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2151  return 0;
2152  }
2153  mutex_lock(smpp->conn->flow_mutex);
2155  mutex_unlock(smpp->conn->flow_mutex);
2156  break;
2157 
2158  case generic_nack:
2159  /*
2160  * Session state check
2161  */
2162  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2163  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2164  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2165  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2166  return 0;
2167  }
2168 
2169  cmd_stat = pdu->u.generic_nack.command_status;
2170 
2171  os = octstr_format("%ld", pdu->u.generic_nack.sequence_number);
2172  smpp_msg = dict_remove(smpp->sent_msgs, os);
2173  octstr_destroy(os);
2174 
2175  if (smpp_msg == NULL) {
2176  error(0, "SMPP[%s]: SMSC rejected last command, code 0x%08lx (%s).",
2177  octstr_get_cstr(smpp->conn->id),
2178  cmd_stat,
2179  smpp_error_to_string(cmd_stat));
2180  } else {
2181  msg = smpp_msg->msg;
2183 
2184  error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) in response to submit_sm PDU.",
2185  octstr_get_cstr(smpp->conn->id),
2186  cmd_stat,
2187  smpp_error_to_string(cmd_stat));
2188 
2189  /*
2190  * check to see if we got a "throttling error", in which case we'll just
2191  * sleep for a while
2192  */
2193  if (cmd_stat == SMPP_ESME_RTHROTTLED)
2194  time(&(smpp->throttling_err_time));
2195  else
2196  smpp->throttling_err_time = 0;
2197 
2198  reason = smpp_status_to_smscconn_failure_reason(cmd_stat);
2199  bb_smscconn_send_failed(smpp->conn, msg, reason,
2200  octstr_format("0x%08lx/%s", cmd_stat, smpp_error_to_string(cmd_stat)));
2201  --(*pending_submits);
2202  }
2203  break;
2204 
2205  default:
2206  error(0, "SMPP[%s]: Unhandled %s PDU type 0x%08lx, ignored.",
2207  octstr_get_cstr(smpp->conn->id), pdu->type_name, pdu->type);
2208  /*
2209  * We received an unknown PDU type, therefore we will respond
2210  * with a generic_nack PDU, see SMPP v3.4 spec, section 3.3.
2211  */
2212  ret = send_gnack(smpp, conn, SMPP_ESME_RINVCMDID, pdu->u.generic_nack.sequence_number);
2213  break;
2214  }
2215 
2216  if (resp != NULL) {
2217  ret = send_pdu(conn, smpp, resp) != -1 ? 0 : -1;
2218  smpp_pdu_destroy(resp);
2219  }
2220 
2221  return ret;
2222 }
const char * smpp_error_to_string(enum SMPP_ERROR_MESSAGES error)
Definition: smpp_pdu.c:911
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
void bb_smscconn_connected(SMSCConn *conn)
Definition: bb_smscconn.c:192
#define mutex_unlock(m)
Definition: thread.h:136
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1237
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
Definition: smsc_smpp.c:1197
Octstr * id
Definition: smscconn_p.h:174
const char * type_name
Definition: smpp_pdu.h:92
SMSCConn * conn
Definition: smsc_smpp.c:188
static Msg * data_sm_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
Definition: smsc_smpp.c:731
unsigned long type
Definition: smpp_pdu.h:91
time_t throttling_err_time
Definition: smsc_smpp.c:176
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
Definition: dlr.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
static Msg * pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
Definition: smsc_smpp.c:590
int smpp_msg_id_type
Definition: smsc_smpp.c:177
static long smpp_status_to_smscconn_failure_reason(long status)
Definition: smsc_smpp.c:854
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:477
time_t connect_time
Definition: smscconn_p.h:155
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Mutex * flow_mutex
Definition: smscconn_p.h:157
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_isdigit(int c)
Definition: utils.c:988
Octstr * my_number
Definition: smsc_smpp.c:156
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
union SMPP_PDU::@15 u
int retry
Definition: smsc_smpp.c:182
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Msg * msg
Definition: smsc_smpp.c:194
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
Definition: bb_smscconn.c:281
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
smscconn_status_t status
Definition: smscconn_p.h:151
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
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)
Definition: smsc_smpp.c:1492
Octstr * username
Definition: smsc_smpp.c:153
static long smscconn_failure_reason_to_smpp_status(long reason)
Definition: smsc_smpp.c:1711
#define mutex_lock(m)
Definition: thread.h:130
#define DLR_IS_ENABLED_DEVICE(dlr)
Definition: dlr.h:82
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
Definition: smsc_smpp.c:216
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273
volatile int quitting
Definition: smsc_smpp.c:170

◆ io_arg_create()

static struct io_arg* io_arg_create ( SMPP smpp,
int  transmitter 
)
static

Definition at line 2231 of file smsc_smpp.c.

References io_arg::smpp, and io_arg::transmitter.

Referenced by smsc_smpp_create().

2232 {
2233  struct io_arg *io_arg;
2234 
2235  io_arg = gw_malloc(sizeof(*io_arg));
2236  io_arg->smpp = smpp;
2238  return io_arg;
2239 }
int transmitter
Definition: smsc_smpp.c:2227
SMPP * smpp
Definition: smsc_smpp.c:2226

◆ io_thread()

static void io_thread ( void *  arg)
static

Definition at line 2311 of file smsc_smpp.c.

References bb_smscconn_killed(), bb_smscconn_send_failed(), SMPP::conn, conn_destroy(), conn_wait(), SMPP::connection_timeout, smscconn::data, debug(), dict_keys(), dict_remove(), do_queue_cleanup(), dump_pdu, SMPP::enquire_link_interval, error(), smscconn::flow_mutex, gw_prioqueue_len(), gw_prioqueue_remove(), gwlist_destroy(), gwlist_extract_first(), gwthread_join(), gwthread_sleep(), gwthread_wakeup(), handle_pdu(), smscconn::id, IS_ACTIVE, SMPP::log_format, smscconn::log_idx, log_thread_to(), SMPP::max_pending_submits, msg, smpp_msg::msg, SMPP::msgs_to_send, mutex_lock, mutex_unlock, smscconn::name, octstr_destroy(), octstr_get_cstr, open_receiver(), open_transceiver(), open_transmitter(), SMPP::quitting, read_pdu(), SMPP::receiver, smscconn::reconnect_delay, send_enquire_link(), send_gnack(), send_messages(), send_unbind(), SMPP::sent_msgs, io_arg::smpp, SMPP_DEFAULT_SHUTDOWN_TIMEOUT, smpp_destroy(), SMPP_ESME_RINVCMDLEN, smpp_msg_destroy(), smpp_pdu_destroy(), SMPP_THROTTLING_SLEEP_TIME, SMSCCONN_DEAD, SMSCCONN_DISCONNECTED, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_FAILED_TEMPORARILY, SMSCCONN_RECONNECTING, smscconn::status, SMPP::throttling_err_time, smscconn::throughput, SMPP::transmitter, io_arg::transmitter, SMPP::wait_ack, and warning().

Referenced by smsc_smpp_create().

2312 {
2313  SMPP *smpp;
2314  struct io_arg *io_arg;
2315  int transmitter;
2316  Connection *conn;
2317  int ret;
2318  long pending_submits;
2319  long len;
2320  SMPP_PDU *pdu;
2321  double timeout;
2322  time_t last_cleanup, last_enquire_sent, last_response, now;
2323 
2324  io_arg = arg;
2325  smpp = io_arg->smpp;
2327  gw_free(io_arg);
2328 
2329  /* Make sure we log into our own log-file if defined */
2331 
2332 #define IS_ACTIVE (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)
2333 
2334  conn = NULL;
2335  while (!smpp->quitting) {
2336  if (transmitter == 1)
2337  conn = open_transmitter(smpp);
2338  else if (transmitter == 2)
2339  conn = open_transceiver(smpp);
2340  else
2341  conn = open_receiver(smpp);
2342 
2343  pending_submits = -1;
2344  len = 0;
2345  last_response = last_cleanup = last_enquire_sent = time(NULL);
2346  while(conn != NULL) {
2347  ret = read_pdu(smpp, conn, &len, &pdu);
2348  if (ret == -1) { /* connection broken */
2349  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2351  break;
2352  } else if (ret == -2) {
2353  /* wrong pdu length , send gnack */
2354  len = 0;
2355  if (send_gnack(smpp, conn, SMPP_ESME_RINVCMDLEN, 0) == -1) {
2356  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2358  break;
2359  }
2360  } else if (ret == 1) { /* data available */
2361  /* Deal with the PDU we just got */
2362  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2363  ret = handle_pdu(smpp, conn, pdu, &pending_submits);
2364  smpp_pdu_destroy(pdu);
2365  if (ret == -1) {
2366  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2368  break;
2369  }
2370 
2371  /*
2372  * check if we are still connected
2373  * Note: Function handle_pdu will set status to SMSCCONN_DISCONNECTED
2374  * when unbind was received.
2375  */
2377  break;
2378 
2379  /*
2380  * If we are not bounded then no PDU may coming from SMSC.
2381  * It's just a workaround for buggy SMSC's who send enquire_link's
2382  * although link is not bounded. Means: we doesn't notice these and if link
2383  * keep to be not bounden we are reconnect after defined timeout elapsed.
2384  */
2385  if (IS_ACTIVE) {
2386  /*
2387  * Store last response time.
2388  */
2389  time(&last_response);
2390  }
2391  } else { /* no data available */
2392  /* check last enquire_resp, if difftime > as idle_timeout
2393  * mark connection as broken.
2394  * We have some SMSC connections where connection seems to be OK, but
2395  * in reality is broken, because no responses received.
2396  */
2397  if (smpp->connection_timeout > 0 &&
2398  difftime(time(NULL), last_response) > smpp->connection_timeout) {
2399  /* connection seems to be broken */
2400  warning(0, "Got no responses within %ld sec., reconnecting...",
2401  (long) difftime(time(NULL), last_response));
2402  break;
2403  }
2404 
2405  time(&now);
2406  timeout = last_enquire_sent + smpp->enquire_link_interval - now;
2407  if (!IS_ACTIVE && timeout <= 0)
2408  timeout = smpp->enquire_link_interval;
2410  smpp->throttling_err_time > 0 && pending_submits < smpp->max_pending_submits) {
2411  time_t tr_timeout = smpp->throttling_err_time + SMPP_THROTTLING_SLEEP_TIME - now;
2412  timeout = timeout > tr_timeout ? tr_timeout : timeout;
2413  } else if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 && smpp->conn->throughput > 0 &&
2414  smpp->max_pending_submits > pending_submits) {
2415  double t = 1.0 / smpp->conn->throughput;
2416  timeout = t < timeout ? t : timeout;
2417  }
2418  /* sleep a while */
2419  if (timeout > 0 && conn_wait(conn, timeout) == -1)
2420  break;
2421  }
2422 
2423  /* send enquire link, only if connection is active */
2424  if (IS_ACTIVE && send_enquire_link(smpp, conn, &last_enquire_sent) == -1)
2425  break;
2426 
2427  /* cleanup sent queue */
2428  if (transmitter && difftime(time(NULL), last_cleanup) > smpp->wait_ack) {
2429  if (do_queue_cleanup(smpp, &pending_submits))
2430  break; /* reconnect */
2431  time(&last_cleanup);
2432  }
2433 
2434  /* make sure we send */
2435  if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
2437  if (send_messages(smpp, conn, &pending_submits) == -1)
2438  break;
2439  }
2440 
2441  /* unbind
2442  * Read so long as unbind_resp received or timeout passed. Otherwise we have
2443  * double delivered messages.
2444  */
2445  if (smpp->quitting) {
2446  if (!IS_ACTIVE || send_unbind(smpp, conn) == -1)
2447  break;
2448  time(&last_response);
2449  while(conn_wait(conn, 1.00) != -1 && IS_ACTIVE &&
2450  difftime(time(NULL), last_response) < SMPP_DEFAULT_SHUTDOWN_TIMEOUT) {
2451  if (read_pdu(smpp, conn, &len, &pdu) == 1) {
2452  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2453  handle_pdu(smpp, conn, pdu, &pending_submits);
2454  smpp_pdu_destroy(pdu);
2455  }
2456  }
2457  debug("bb.sms.smpp", 0, "SMPP[%s]: %s: break and shutting down",
2458  octstr_get_cstr(smpp->conn->id), __PRETTY_FUNCTION__);
2459 
2460  break;
2461  }
2462  }
2463 
2464  if (conn != NULL) {
2465  conn_destroy(conn);
2466  conn = NULL;
2467  }
2468  /* set reconnecting status first so that core don't put msgs into our queue */
2469  if (!smpp->quitting) {
2470  error(0, "SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
2476  }
2477  /*
2478  * put all queued messages back into global queue,so if
2479  * we have another link running than messages will be delivered
2480  * quickly
2481  */
2482  if (transmitter) {
2483  Msg *msg;
2484  struct smpp_msg *smpp_msg;
2485  List *noresp;
2486  Octstr *key;
2487 
2489 
2490  while((msg = gw_prioqueue_remove(smpp->msgs_to_send)) != NULL)
2491  bb_smscconn_send_failed(smpp->conn, msg, reason, NULL);
2492 
2493  noresp = dict_keys(smpp->sent_msgs);
2494  while((key = gwlist_extract_first(noresp)) != NULL) {
2495  smpp_msg = dict_remove(smpp->sent_msgs, key);
2496  if (smpp_msg != NULL) {
2497  bb_smscconn_send_failed(smpp->conn, smpp_msg->msg, reason, NULL);
2499  }
2500  octstr_destroy(key);
2501  }
2502  gwlist_destroy(noresp, NULL);
2503  }
2504  }
2505 
2506 #undef IS_ACTIVE
2507 
2508  /*
2509  * Shutdown sequence as follow:
2510  * 1) if this is TX session so join receiver and free SMPP
2511  * 2) if RX session available but no TX session so nothing to join then free SMPP
2512  */
2513  if (transmitter && smpp->receiver != -1) {
2514  gwthread_wakeup(smpp->receiver);
2515  gwthread_join(smpp->receiver);
2516  }
2517  if (transmitter || smpp->transmitter == -1) {
2518  debug("bb.smpp", 0, "SMSCConn %s shut down.",
2519  octstr_get_cstr(smpp->conn->name));
2520 
2521  mutex_lock(smpp->conn->flow_mutex);
2522  smpp->conn->status = SMSCCONN_DEAD;
2523  smpp->conn->data = NULL;
2524  mutex_unlock(smpp->conn->flow_mutex);
2525 
2526  smpp_destroy(smpp);
2528  }
2529 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
Octstr * name
Definition: smscconn_p.h:173
static Connection * open_transmitter(SMPP *smpp)
Definition: smsc_smpp.c:1312
void error(int err, const char *fmt,...)
Definition: log.c:648
static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
Definition: smsc_smpp.c:1174
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
#define mutex_unlock(m)
Definition: thread.h:136
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
Definition: smsc_smpp.c:1197
#define IS_ACTIVE
Octstr * id
Definition: smscconn_p.h:174
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:250
long max_pending_submits
Definition: smsc_smpp.c:172
long enquire_link_interval
Definition: smsc_smpp.c:171
#define SMPP_THROTTLING_SLEEP_TIME
Definition: smsc_smpp.c:124
int log_idx
Definition: smscconn_p.h:197
SMSCConn * conn
Definition: smsc_smpp.c:188
static int do_queue_cleanup(SMPP *smpp, long *pending_submits)
Definition: smsc_smpp.c:2246
time_t throttling_err_time
Definition: smsc_smpp.c:176
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long reconnect_delay
Definition: smscconn_p.h:199
void log_thread_to(int idx)
Definition: log.c:759
static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu)
Definition: smsc_smpp.c:327
long receiver
Definition: smsc_smpp.c:146
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * gwlist_extract_first(List *list)
Definition: list.c:305
static int send_unbind(SMPP *smpp, Connection *conn)
Definition: smsc_smpp.c:1217
int transmitter
Definition: smsc_smpp.c:2227
static void smpp_destroy(SMPP *smpp)
Definition: smsc_smpp.c:295
void conn_destroy(Connection *conn)
Definition: conn.c:627
static Connection * open_transceiver(SMPP *smpp)
Definition: smsc_smpp.c:1365
double throughput
Definition: smscconn_p.h:203
Mutex * flow_mutex
Definition: smscconn_p.h:157
static int handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits)
Definition: smsc_smpp.c:1726
void warning(int err, const char *fmt,...)
Definition: log.c:660
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:265
long gw_prioqueue_len(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:220
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void gwthread_sleep(double seconds)
long connection_timeout
Definition: smsc_smpp.c:181
long wait_ack
Definition: smsc_smpp.c:183
long log_format
Definition: smsc_smpp.c:186
Msg * msg
Definition: smsc_smpp.c:194
static int send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
Definition: smsc_smpp.c:1256
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
static Connection * open_receiver(SMPP *smpp)
Definition: smsc_smpp.c:1416
List * dict_keys(Dict *dict)
Definition: dict.c:347
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT
Definition: smsc_smpp.c:127
SMPP * smpp
Definition: smsc_smpp.c:2226
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
Definition: smsc_smpp.c:216
long transmitter
Definition: smsc_smpp.c:145
volatile int quitting
Definition: smsc_smpp.c:170
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ msg_to_pdu()

static SMPP_PDU* msg_to_pdu ( SMPP smpp,
Msg msg 
)
static

Definition at line 870 of file smsc_smpp.c.

References SMPP::alt_addr_charset, SMPP::alt_charset, smscconn::alt_dcs, SMPP::autodetect_addr, charset_convert(), charset_utf8_to_gsm(), SMPP::conn, counter_increase(), DC_7BIT, DC_UCS2, DC_UNDEF, debug(), SMPP::dest_addr_npi, SMPP::dest_addr_ton, dict_destroy(), DLR_IS_BUFFERED, DLR_IS_FAIL, DLR_IS_SUCCESS, DLR_IS_SUCCESS_OR_FAIL, error(), SMPP::esm_class, ESM_CLASS_SUBMIT_RPI, ESM_CLASS_SUBMIT_UDH_INDICATOR, fields_to_dcs(), GSM_ADDR_NPI_E164, GSM_ADDR_NPI_UNKNOWN, GSM_ADDR_TON_ALPHANUMERIC, GSM_ADDR_TON_INTERNATIONAL, GSM_ADDR_TON_NATIONAL, gw_gmtime(), gw_isdigit(), handle_mt_dcs(), smscconn::id, MC_UNDEF, SMPP::message_id_counter, meta_data_get_value(), meta_data_get_values(), METADATA_SMPP_GROUP, msg, MWI_UNDEF, octstr_check_range(), octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_insert(), octstr_len(), octstr_replace(), octstr_str_case_compare(), SMPP::priority, SMPP::service_type, SMPP_DEFAULT_CHARSET, SMPP_DEFAULT_UCS2_CHARSET, smpp_pdu_create(), smpp_pdu_destroy(), smpp_tlv_add_constant(), SMS_PARAM_UNDEFINED, SMPP::source_addr_npi, SMPP::source_addr_ton, SMPP_PDU::u, SMPP::validityperiod, and SMPP::version.

Referenced by send_messages().

871 {
872  SMPP_PDU *pdu;
873  int validity;
874  Octstr *tmp;
875  int ton_npi_forced;
876  int data_coding = -1;
877 
878  pdu = smpp_pdu_create(submit_sm,
880 
881  pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);
882  pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
883 
884  /* Set the service type of the outgoing message. We'll use the config
885  * directive as default and 'binfo' as specific parameter. */
886  if (octstr_len(msg->sms.binfo)) {
887  /* SMPP v5.0 has an own TLV for billing information */
888  if (smpp->version == 0x50) {
889  pdu->u.submit_sm.billing_identification = octstr_duplicate(msg->sms.binfo);
890  } else {
891  pdu->u.submit_sm.service_type = octstr_duplicate(msg->sms.binfo);
892  }
893  } else {
894  pdu->u.submit_sm.service_type = octstr_duplicate(smpp->service_type);
895  }
896 
897  /* Check for manual override of source ton and npi values */
898  if (smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
899  pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;
900  pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;
901  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
902  octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,
903  smpp->source_addr_npi);
904  } else {
905  /* setup default values */
906  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
907  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
908  }
909 
910  /* Check for forced source ton and npi values via meta-data */
911  ton_npi_forced = 0;
912  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("source_addr_ton"));
913  if (tmp != NULL) {
914  ton_npi_forced = 1;
915  pdu->u.submit_sm.source_addr_ton = atoi(octstr_get_cstr(tmp));
916  octstr_destroy(tmp);
917  }
918  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("source_addr_npi"));
919  if (tmp != NULL) {
920  ton_npi_forced = 1;
921  pdu->u.submit_sm.source_addr_npi = atoi(octstr_get_cstr(tmp));
922  octstr_destroy(tmp);
923  }
924 
925  /* don't touch source_addr ton/npi if overwritten in meta_data */
926  if (pdu->u.submit_sm.source_addr && !ton_npi_forced && smpp->autodetect_addr) {
927  /* lets see if its international or alphanumeric sender */
928  if (octstr_get_char(pdu->u.submit_sm.source_addr, 0) == '+') {
929  if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {
930  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
931  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; /* short code */
932  if (smpp->alt_addr_charset) {
933  if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
934  /* @ would break PDU if converted into GSM*/
935  octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
936  charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
937  } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
938  error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
940  }
941  } else {
942  /* numeric sender address with + in front -> international (remove the +) */
943  octstr_delete(pdu->u.submit_sm.source_addr, 0, 1);
944  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
945  }
946  } else {
947  if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {
948  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
949  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
950  if (smpp->alt_addr_charset) {
951  if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
952  /* @ would break PDU if converted into GSM */
953  octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
954  charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
955  } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
956  error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
958  }
959  }
960  }
961  }
962 
963  /* Check for manual override of destination ton and npi values */
964  if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
965  pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;
966  pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;
967  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
968  octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,
969  smpp->dest_addr_npi);
970  } else {
971  pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
972  pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
973  }
974 
975  /* Check for forced destination ton and npi values via meta-data */
976  ton_npi_forced = 0;
977  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("dest_addr_ton"));
978  if (tmp != NULL) {
979  ton_npi_forced = 1;
980  pdu->u.submit_sm.dest_addr_ton = atoi(octstr_get_cstr(tmp));
981  octstr_destroy(tmp);
982  }
983  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("dest_addr_npi"));
984  if (tmp != NULL) {
985  ton_npi_forced = 1;
986  pdu->u.submit_sm.dest_addr_npi = atoi(octstr_get_cstr(tmp));
987  octstr_destroy(tmp);
988  }
989 
990  /* don't touch source_addr ton/npi if overwritten in meta_data */
991  if (!ton_npi_forced) {
992  /*
993  * if its a international number starting with +, lets remove the
994  * '+' and set number type to international instead
995  */
996  if (octstr_get_char(pdu->u.submit_sm.destination_addr,0) == '+') {
997  octstr_delete(pdu->u.submit_sm.destination_addr, 0,1);
998  pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
999  }
1000  }
1001 
1002  /* check length of src/dst address */
1003  if (octstr_len(pdu->u.submit_sm.destination_addr) > 20 ||
1004  octstr_len(pdu->u.submit_sm.source_addr) > 20) {
1005  smpp_pdu_destroy(pdu);
1006  return NULL;
1007  }
1008 
1009  /*
1010  * set the data coding scheme (DCS) field
1011  * check if we have a forced value for this from the smsc-group.
1012  * Note: if message class is set, then we _must_ force alt_dcs otherwise
1013  * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
1014  * first here, because MWI and MCLASS can not be set at the same time and
1015  * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
1016  * if MWI is set.
1017  */
1018  if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
1019  pdu->u.submit_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
1020  else
1021  pdu->u.submit_sm.data_coding = fields_to_dcs(msg,
1022  (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
1023  msg->sms.alt_dcs : smpp->conn->alt_dcs));
1024 
1025  /* set protocol id */
1026  if (msg->sms.pid != SMS_PARAM_UNDEFINED)
1027  pdu->u.submit_sm.protocol_id = msg->sms.pid;
1028 
1029  /*
1030  * set the esm_class field
1031  * default is store and forward, plus udh and rpi if requested
1032  */
1033  pdu->u.submit_sm.esm_class = smpp->esm_class;
1034  if (octstr_len(msg->sms.udhdata))
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 |
1040 
1041  /*
1042  * set data segments and length
1043  */
1044 
1045  pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);
1046 
1047  /* Check for forced data_coding value via meta-data */
1048  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("data_coding"));
1049  if (tmp != NULL) {
1050  data_coding = atoi(octstr_get_cstr(tmp));
1051  octstr_destroy(tmp);
1052  }
1053 
1054  /*
1055  * only re-encoding if using default smsc charset that is defined via
1056  * alt-charset in smsc group and if MT is not binary
1057  */
1058  if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata) == 0)) {
1059  /*
1060  * consider 4 cases:
1061  * a) data_coding 0xFX: encoding should always be GSM 03.38 charset
1062  * b) data_coding 0xXX: encoding based on forced meta-data value
1063  * c) data_coding 0x00: encoding may be converted according to alt-charset
1064  * d) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
1065  */
1066  if (pdu->u.submit_sm.data_coding & 0xF0) {
1067  charset_utf8_to_gsm(pdu->u.submit_sm.short_message);
1068  } else if (pdu->u.submit_sm.data_coding == 0 && !smpp->alt_charset) {
1069  /*
1070  * convert to a forced data_coding value, or GSM 03.38 if not
1071  */
1072  handle_mt_dcs(pdu->u.submit_sm.short_message, SMPP_DEFAULT_CHARSET, data_coding);
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) {
1076  /*
1077  * convert to the given alternative charset
1078  */
1079  if (charset_convert(pdu->u.submit_sm.short_message, SMPP_DEFAULT_CHARSET,
1080  octstr_get_cstr(smpp->alt_charset)) != 0)
1081  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
1083  }
1084  }
1085  else if (msg->sms.coding == DC_UCS2 && data_coding > 0x04 && data_coding != 0x08) {
1086  /*
1087  * convert to a forced data_coding value, which is given in UCS-2,
1088  * avoid the transcoding if we want UCS2 (data_coding 0x08) anyway.
1089  */
1090  handle_mt_dcs(pdu->u.submit_sm.short_message, SMPP_DEFAULT_UCS2_CHARSET, data_coding);
1091  pdu->u.submit_sm.data_coding = data_coding;
1092  }
1093 
1094  /* prepend udh if present */
1095  if (octstr_len(msg->sms.udhdata)) {
1096  octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);
1097  }
1098 
1099  pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message);
1100 
1101  /* check long messages, because:
1102  * The sm_length parameter specifies the length of the short_message parameter in octets.
1103  * The sm_length should be set to 0 in the submit_sm, submit_multi, and deliver_sm PDUs if
1104  * the message_payload parameter is being used to send user data larger than 254 octets.
1105  */
1106  if (pdu->u.submit_sm.sm_length > 254) {
1107  if (smpp->version > 0x33) {
1108  /* put msgdata into message_payload */
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;
1112  } else {
1113  error(0, "SMPP[%s]: Unable to send long message (%ld) Octets in smpp version < 3.4",
1114  octstr_get_cstr(smpp->conn->id), pdu->u.submit_sm.sm_length);
1115  smpp_pdu_destroy(pdu);
1116  return NULL;
1117  }
1118  }
1119 
1120  /*
1121  * check for validity and deferred settings
1122  * were message value has higher priority then smsc config group value
1123  * Note: we always send in UTC and just define "Time Difference" as 00 and
1124  * direction '+'.
1125  */
1126  validity = SMS_PARAM_UNDEFINED;
1127  if (msg->sms.validity != SMS_PARAM_UNDEFINED)
1128  validity = msg->sms.validity;
1129  else if (smpp->validityperiod != SMS_PARAM_UNDEFINED)
1130  validity = time(NULL) + smpp->validityperiod * 60;
1131  if (validity != SMS_PARAM_UNDEFINED) {
1132  struct tm tm = gw_gmtime(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);
1136  }
1137 
1138  if (msg->sms.deferred != SMS_PARAM_UNDEFINED) {
1139  struct tm tm = gw_gmtime(msg->sms.deferred);
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);
1143  }
1144 
1145  /* ask for the delivery reports if needed */
1146  if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
1147  pdu->u.submit_sm.registered_delivery = 2;
1148  else if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
1149  pdu->u.submit_sm.registered_delivery = 1;
1150 
1151  if (DLR_IS_BUFFERED(msg->sms.dlr_mask))
1152  pdu->u.submit_sm.registered_delivery += 16;
1153 
1154  /* set priority */
1155  if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
1156  pdu->u.submit_sm.priority_flag = msg->sms.priority;
1157  else
1158  pdu->u.submit_sm.priority_flag = smpp->priority;
1159 
1160  /* set more messages to send */
1161  if (smpp->version > 0x33 && msg->sms.msg_left > 0)
1162  pdu->u.submit_sm.more_messages_to_send = 1;
1163 
1164  dict_destroy(pdu->u.submit_sm.tlv);
1165  pdu->u.submit_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1166 
1167  /* add any configured constant TLVs */
1168  smpp_tlv_add_constant(smpp->conn->id, &(pdu->u.submit_sm.tlv));
1169 
1170  return pdu;
1171 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
Dict * meta_data_get_values(const Octstr *data, const char *group)
Definition: meta_data.c:248
#define MWI_UNDEF
Definition: sms.h:99
int octstr_str_case_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:986
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
Definition: octstr.c:2649
Octstr * service_type
Definition: smsc_smpp.c:157
int alt_dcs
Definition: smscconn_p.h:201
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
#define DLR_IS_SUCCESS(dlr)
Definition: dlr.h:86
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
Octstr * id
Definition: smscconn_p.h:174
void smpp_tlv_add_constant(Octstr *smsc_id, Dict **tlvs)
Definition: smpp_pdu.c:102
#define GSM_ADDR_TON_NATIONAL
Definition: smasi_pdu.h:104
void charset_utf8_to_gsm(Octstr *ostr)
Definition: charset.c:288
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
int validityperiod
Definition: smsc_smpp.c:175
Octstr * meta_data_get_value(Octstr *data, const char *group, const Octstr *key)
Definition: meta_data.c:368
int source_addr_npi
Definition: smsc_smpp.c:159
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
Octstr * alt_addr_charset
Definition: smsc_smpp.c:180
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
Octstr * alt_charset
Definition: smsc_smpp.c:179
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define SMPP_DEFAULT_CHARSET
Definition: smsc_smpp.c:84
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int dest_addr_ton
Definition: smsc_smpp.c:160
int gw_isdigit(int c)
Definition: utils.c:988
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
int fields_to_dcs(Msg *msg, int mode)
Definition: sms.c:73
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int autodetect_addr
Definition: smsc_smpp.c:178
union SMPP_PDU::@15 u
#define DLR_IS_BUFFERED(dlr)
Definition: dlr.h:88
#define SMPP_DEFAULT_UCS2_CHARSET
Definition: smsc_smpp.c:85
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define GSM_ADDR_NPI_UNKNOWN
Definition: smasi_pdu.h:111
void dict_destroy(Dict *dict)
Definition: dict.c:215
#define MC_UNDEF
Definition: sms.h:93
Definition: octstr.c:118
static void handle_mt_dcs(Octstr *short_message, char *internal, int data_coding)
Definition: smsc_smpp.c:439
#define GSM_ADDR_NPI_E164
Definition: smasi_pdu.h:112
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int source_addr_ton
Definition: smsc_smpp.c:158
#define METADATA_SMPP_GROUP
Definition: meta_data.h:76
int dest_addr_npi
Definition: smsc_smpp.c:161
#define DC_UNDEF
Definition: sms.h:109
#define DLR_IS_FAIL(dlr)
Definition: dlr.h:87
#define GSM_ADDR_TON_ALPHANUMERIC
Definition: smasi_pdu.h:107
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
#define DLR_IS_SUCCESS_OR_FAIL(dlr)
Definition: dlr.h:85
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
Counter * message_id_counter
Definition: smsc_smpp.c:150
int priority
Definition: smsc_smpp.c:174
#define DC_UCS2
Definition: sms.h:112
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
int esm_class
Definition: smsc_smpp.c:185

◆ open_receiver()

static Connection* open_receiver ( SMPP smpp)
static

Definition at line 1416 of file smsc_smpp.c.

References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, SMPP::conn, conn_destroy(), conn_open_tcp(), conn_open_tcp_with_port(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::our_receiver_port, SMPP::password, SMPP::receive_port, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::ssl_client_certkey_file, SMPP::system_type, SMPP_PDU::u, SMPP::use_ssl, SMPP::username, and SMPP::version.

Referenced by io_thread().

1417 {
1418  SMPP_PDU *bind;
1419  Connection *conn;
1420 
1421 #ifdef HAVE_LIBSSL
1422  if (smpp->use_ssl)
1423  conn = conn_open_ssl(smpp->host, smpp->receive_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1424  else
1425 #endif
1426 
1427  if (smpp->our_receiver_port > 0)
1428  conn = conn_open_tcp_with_port(smpp->host, smpp->receive_port, smpp->our_receiver_port, smpp->conn->our_host);
1429  else
1430  conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host);
1431 
1432  if (conn == NULL) {
1433  error(0, "SMPP[%s]: Couldn't connect to server.",
1434  octstr_get_cstr(smpp->conn->id));
1435  return NULL;
1436  }
1437 
1438  bind = smpp_pdu_create(bind_receiver,
1440  bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username);
1441  bind->u.bind_receiver.password = octstr_duplicate(smpp->password);
1442  if (smpp->system_type == NULL)
1443  bind->u.bind_receiver.system_type = octstr_create("VMA");
1444  else
1445  bind->u.bind_receiver.system_type =
1447  bind->u.bind_receiver.interface_version = smpp->version;
1448  bind->u.bind_receiver.address_range =
1450  bind->u.bind_receiver.addr_ton = smpp->bind_addr_ton;
1451  bind->u.bind_receiver.addr_npi = smpp->bind_addr_npi;
1452  if (send_pdu(conn, smpp, bind) == -1) {
1453  error(0, "SMPP[%s]: Couldn't send bind_receiver to server.",
1454  octstr_get_cstr(smpp->conn->id));
1455  conn_destroy(conn);
1456  conn = NULL;
1457  }
1458  smpp_pdu_destroy(bind);
1459 
1460  return conn;
1461 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:496
int our_receiver_port
Definition: smsc_smpp.c:163
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1237
long bind_addr_npi
Definition: smsc_smpp.c:165
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
long bind_addr_ton
Definition: smsc_smpp.c:164
Octstr * our_host
Definition: smscconn_p.h:192
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int use_ssl
Definition: smsc_smpp.c:168
void conn_destroy(Connection *conn)
Definition: conn.c:627
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:548
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
Octstr * username
Definition: smsc_smpp.c:153
int receive_port
Definition: smsc_smpp.c:167
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
Counter * message_id_counter
Definition: smsc_smpp.c:150
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169
Octstr * password
Definition: smsc_smpp.c:154

◆ open_transceiver()

static Connection* open_transceiver ( SMPP smpp)
static

Definition at line 1365 of file smsc_smpp.c.

References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, SMPP::conn, conn_destroy(), conn_open_tcp(), conn_open_tcp_with_port(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::our_port, SMPP::password, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::ssl_client_certkey_file, SMPP::system_type, SMPP::transmit_port, SMPP_PDU::u, SMPP::use_ssl, SMPP::username, and SMPP::version.

Referenced by io_thread().

1366 {
1367  SMPP_PDU *bind;
1368  Connection *conn;
1369 
1370 #ifdef HAVE_LIBSSL
1371  if (smpp->use_ssl)
1372  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1373  else
1374 #endif
1375 
1376  if (smpp->our_port > 0)
1377  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1378  else
1379  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1380 
1381  if (conn == NULL) {
1382  error(0, "SMPP[%s]: Couldn't connect to server.",
1383  octstr_get_cstr(smpp->conn->id));
1384  return NULL;
1385  }
1386 
1387  bind = smpp_pdu_create(bind_transceiver,
1389  bind->u.bind_transceiver.system_id = octstr_duplicate(smpp->username);
1390  bind->u.bind_transceiver.password = octstr_duplicate(smpp->password);
1391  if (smpp->system_type == NULL)
1392  bind->u.bind_transceiver.system_type = octstr_create("VMA");
1393  else
1394  bind->u.bind_transceiver.system_type = octstr_duplicate(smpp->system_type);
1395  bind->u.bind_transceiver.interface_version = smpp->version;
1396  bind->u.bind_transceiver.address_range = octstr_duplicate(smpp->address_range);
1397  bind->u.bind_transceiver.addr_ton = smpp->bind_addr_ton;
1398  bind->u.bind_transceiver.addr_npi = smpp->bind_addr_npi;
1399  if (send_pdu(conn, smpp, bind) == -1) {
1400  error(0, "SMPP[%s]: Couldn't send bind_transceiver to server.",
1401  octstr_get_cstr(smpp->conn->id));
1402  conn_destroy(conn);
1403  conn = NULL;
1404  }
1405  smpp_pdu_destroy(bind);
1406 
1407  return conn;
1408 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:496
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1237
long bind_addr_npi
Definition: smsc_smpp.c:165
Octstr * id
Definition: smscconn_p.h:174
int transmit_port
Definition: smsc_smpp.c:166
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
long bind_addr_ton
Definition: smsc_smpp.c:164
Octstr * our_host
Definition: smscconn_p.h:192
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int use_ssl
Definition: smsc_smpp.c:168
void conn_destroy(Connection *conn)
Definition: conn.c:627
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:548
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
Octstr * username
Definition: smsc_smpp.c:153
int our_port
Definition: smsc_smpp.c:162
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
Counter * message_id_counter
Definition: smsc_smpp.c:150
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169
Octstr * password
Definition: smsc_smpp.c:154

◆ open_transmitter()

static Connection* open_transmitter ( SMPP smpp)
static

Definition at line 1312 of file smsc_smpp.c.

References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, SMPP::conn, conn_destroy(), conn_open_tcp(), conn_open_tcp_with_port(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::our_port, SMPP::password, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::ssl_client_certkey_file, SMPP::system_type, SMPP::transmit_port, SMPP_PDU::u, SMPP::use_ssl, SMPP::username, and SMPP::version.

Referenced by io_thread().

1313 {
1314  SMPP_PDU *bind;
1315  Connection *conn;
1316 
1317 #ifdef HAVE_LIBSSL
1318  if (smpp->use_ssl)
1319  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1320  else
1321 #endif
1322 
1323  if (smpp->our_port > 0)
1324  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1325  else
1326  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1327 
1328  if (conn == NULL) {
1329  error(0, "SMPP[%s]: Couldn't connect to server.",
1330  octstr_get_cstr(smpp->conn->id));
1331  return NULL;
1332  }
1333 
1334  bind = smpp_pdu_create(bind_transmitter,
1336  bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username);
1337  bind->u.bind_transmitter.password = octstr_duplicate(smpp->password);
1338  if (smpp->system_type == NULL)
1339  bind->u.bind_transmitter.system_type = octstr_create("VMA");
1340  else
1341  bind->u.bind_transmitter.system_type =
1343  bind->u.bind_transmitter.interface_version = smpp->version;
1344  bind->u.bind_transmitter.address_range =
1346  bind->u.bind_transmitter.addr_ton = smpp->bind_addr_ton;
1347  bind->u.bind_transmitter.addr_npi = smpp->bind_addr_npi;
1348  if (send_pdu(conn, smpp, bind) == -1) {
1349  error(0, "SMPP[%s]: Couldn't send bind_transmitter to server.",
1350  octstr_get_cstr(smpp->conn->id));
1351  conn_destroy(conn);
1352  conn = NULL;
1353  }
1354  smpp_pdu_destroy(bind);
1355 
1356  return conn;
1357 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:496
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1237
long bind_addr_npi
Definition: smsc_smpp.c:165
Octstr * id
Definition: smscconn_p.h:174
int transmit_port
Definition: smsc_smpp.c:166
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
long bind_addr_ton
Definition: smsc_smpp.c:164
Octstr * our_host
Definition: smscconn_p.h:192
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int use_ssl
Definition: smsc_smpp.c:168
void conn_destroy(Connection *conn)
Definition: conn.c:627
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:548
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
Octstr * username
Definition: smsc_smpp.c:153
int our_port
Definition: smsc_smpp.c:162
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
Counter * message_id_counter
Definition: smsc_smpp.c:150
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169
Octstr * password
Definition: smsc_smpp.c:154

◆ pdu_to_msg()

static Msg* pdu_to_msg ( SMPP smpp,
SMPP_PDU pdu,
long *  reason 
)
static

Definition at line 590 of file smsc_smpp.c.

References SMPP::alt_addr_charset, SMPP::alt_charset, SMPP::conn, convert_addr_from_pdu(), dcs_to_fields(), debug(), error(), ESM_CLASS_SUBMIT_RPI, ESM_CLASS_SUBMIT_UDH_INDICATOR, gw_assert(), handle_mo_dcs(), smscconn::id, meta_data_set_values(), msg, msg_create, msg_destroy(), octstr_copy, octstr_create, octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_len(), prepend_catenation_udh(), SMPP_ESME_RINVDSTADR, SMPP_ESME_RINVESMCLASS, SMPP_ESME_RINVTLVVAL, SMPP_ESME_ROK, SMPP_PDU::type, SMPP_PDU::u, and SMPP::version.

Referenced by handle_pdu().

591 {
592  Msg *msg;
593  int ton, npi;
594 
595  gw_assert(pdu->type == deliver_sm);
596 
597  msg = msg_create(sms);
598  gw_assert(msg != NULL);
599  *reason = SMPP_ESME_ROK;
600 
601  /*
602  * Reset source addr to have a prefixed '+' in case we have an
603  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
604  * between national and international numbers.
605  */
606  ton = pdu->u.deliver_sm.source_addr_ton;
607  npi = pdu->u.deliver_sm.source_addr_npi;
608  /* check source addr */
609  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
610  goto error;
611  msg->sms.sender = pdu->u.deliver_sm.source_addr;
612  pdu->u.deliver_sm.source_addr = NULL;
613 
614  /*
615  * Follows SMPP spec. v3.4. issue 1.2
616  * it's not allowed to have destination_addr NULL
617  */
618  if (pdu->u.deliver_sm.destination_addr == NULL) {
619  error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. "
620  "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
621  octstr_get_cstr(pdu->u.deliver_sm.destination_addr));
622  *reason = SMPP_ESME_RINVDSTADR;
623  goto error;
624  }
625 
626  /* Same reset of destination number as for source */
627  ton = pdu->u.deliver_sm.dest_addr_ton;
628  npi = pdu->u.deliver_sm.dest_addr_npi;
629  /* check destination addr */
630  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
631  goto error;
632  msg->sms.receiver = pdu->u.deliver_sm.destination_addr;
633  pdu->u.deliver_sm.destination_addr = NULL;
634 
635  /* SMSCs use service_type for billing information
636  * According to SMPP v5.0 there is no 'billing_identification'
637  * TLV in the deliver_sm PDU optional TLVs. */
638  msg->sms.binfo = pdu->u.deliver_sm.service_type;
639  pdu->u.deliver_sm.service_type = NULL;
640 
641  /* Foreign ID on MO */
642  msg->sms.foreign_id = pdu->u.deliver_sm.receipted_message_id;
643  pdu->u.deliver_sm.receipted_message_id = NULL;
644 
645  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
646  msg->sms.rpi = 1;
647 
648  /*
649  * Check for message_payload if version > 0x33 and sm_length == 0
650  * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!
651  */
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;
655  }
656  else {
657  msg->sms.msgdata = pdu->u.deliver_sm.short_message;
658  pdu->u.deliver_sm.short_message = NULL;
659  }
660 
661  /* check sar_msg_ref_num, sar_segment_seqnum, sar_total_segments */
662  if (smpp->version > 0x33 &&
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) {
664  /*
665  For GSM networks, the concatenation related TLVs (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum)
666  or port addressing related TLVs
667  (source_port, dest_port) cannot be used in conjunction with encoded User Data Header in the short_message
668  (user data) field. This means that the above listed TLVs cannot be used if the User Data Header Indicator flag is set.
669  */
670  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
671  error(0, "SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
672  octstr_get_cstr(smpp->conn->id));
673  *reason = SMPP_ESME_RINVTLVVAL;
674  goto error;
675  }
676  /* create multipart UDH */
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);
681  }
682 
683  /*
684  * Encode udh if udhi set
685  * for reference see GSM03.40, section 9.2.3.24
686  */
687  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
688  int udhl;
689  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
690  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
691  octstr_get_cstr(smpp->conn->id), udhl);
692  if (udhl > octstr_len(msg->sms.msgdata)) {
693  error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "
694  "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
695  udhl, octstr_len(msg->sms.msgdata));
696  *reason = SMPP_ESME_RINVESMCLASS;
697  goto error;
698  }
699  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
700  octstr_delete(msg->sms.msgdata, 0, udhl);
701  }
702 
703  dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
704 
705  /* handle default data coding */
706  handle_mo_dcs(msg, smpp->alt_charset, pdu->u.deliver_sm.data_coding, pdu->u.deliver_sm.esm_class);
707 
708  msg->sms.pid = pdu->u.deliver_sm.protocol_id;
709 
710  /* set priority flag */
711  msg->sms.priority = pdu->u.deliver_sm.priority_flag;
712 
713  if (msg->sms.meta_data == NULL)
714  msg->sms.meta_data = octstr_create("");
715  meta_data_set_values(msg->sms.meta_data, pdu->u.deliver_sm.tlv, "smpp", 1);
716 
717  return msg;
718 
719 error:
720  msg_destroy(msg);
721  return NULL;
722 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
Octstr * id
Definition: smscconn_p.h:174
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
unsigned long type
Definition: smpp_pdu.h:91
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Octstr * alt_addr_charset
Definition: smsc_smpp.c:180
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset)
Definition: smsc_smpp.c:368
Definition: msg.h:79
Octstr * alt_charset
Definition: smsc_smpp.c:179
static void handle_mo_dcs(Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
Definition: smsc_smpp.c:509
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void msg_destroy(Msg *msg)
Definition: msg.c:132
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
void prepend_catenation_udh(Msg *sms, int part_no, int num_messages, int msg_sequence)
Definition: sms.c:224
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273

◆ queued_cb()

static long queued_cb ( SMSCConn conn)
static

Definition at line 2537 of file smsc_smpp.c.

References smscconn::data, gw_prioqueue_len(), smscconn::load, SMPP::msgs_to_send, SMSCCONN_DEAD, and smscconn::status.

Referenced by smsc_smpp_create().

2538 {
2539  SMPP *smpp;
2540 
2541  smpp = conn->data;
2542  conn->load = (smpp ? (conn->status != SMSCCONN_DEAD ?
2543  gw_prioqueue_len(smpp->msgs_to_send) : 0) : 0);
2544  return conn->load;
2545 }
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
void * data
Definition: smscconn_p.h:250
long gw_prioqueue_len(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:220
smscconn_status_t status
Definition: smscconn_p.h:151
int load
Definition: smscconn_p.h:152

◆ read_pdu()

static int read_pdu ( SMPP smpp,
Connection conn,
long *  len,
SMPP_PDU **  pdu 
)
static

Definition at line 327 of file smsc_smpp.c.

References SMPP::conn, conn_eof(), conn_error(), debug(), error(), smscconn::id, octstr_destroy(), octstr_dump, octstr_get_cstr, smpp_pdu_read_data(), smpp_pdu_read_len(), and smpp_pdu_unpack().

Referenced by io_thread().

328 {
329  Octstr *os;
330 
331  if (*len == 0) {
332  *len = smpp_pdu_read_len(conn);
333  if (*len == -1) {
334  error(0, "SMPP[%s]: Server sent garbage, ignored.",
335  octstr_get_cstr(smpp->conn->id));
336  return -2;
337  } else if (*len == 0) {
338  if (conn_eof(conn) || conn_error(conn))
339  return -1;
340  return 0;
341  }
342  }
343 
344  os = smpp_pdu_read_data(conn, *len);
345  if (os == NULL) {
346  if (conn_eof(conn) || conn_error(conn))
347  return -1;
348  return 0;
349  }
350  *len = 0;
351 
352  *pdu = smpp_pdu_unpack(smpp->conn->id, os);
353  if (*pdu == NULL) {
354  error(0, "SMPP[%s]: PDU unpacking failed.",
355  octstr_get_cstr(smpp->conn->id));
356  debug("bb.sms.smpp", 0, "SMPP[%s]: Failed PDU follows.",
357  octstr_get_cstr(smpp->conn->id));
358  octstr_dump(os, 0);
359  octstr_destroy(os);
360  return -2;
361  }
362 
363  octstr_destroy(os);
364  return 1;
365 }
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:869
int conn_eof(Connection *conn)
Definition: conn.c:705
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
Definition: smpp_pdu.c:597
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr * smpp_pdu_read_data(Connection *conn, long len)
Definition: smpp_pdu.c:895
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int conn_error(Connection *conn)
Definition: conn.c:716

◆ send_enquire_link()

static int send_enquire_link ( SMPP smpp,
Connection conn,
long *  last_sent 
)
static

Definition at line 1174 of file smsc_smpp.c.

References SMPP::conn, conn_write(), counter_increase(), date_universal_now(), dump_pdu, SMPP::enquire_link_interval, smscconn::id, SMPP::log_format, SMPP::message_id_counter, octstr_destroy(), smpp_pdu_create(), smpp_pdu_destroy(), and smpp_pdu_pack().

Referenced by io_thread().

1175 {
1176  SMPP_PDU *pdu;
1177  Octstr *os;
1178  int ret;
1179 
1180  if (difftime(date_universal_now(),*last_sent) < smpp->enquire_link_interval)
1181  return 0;
1182  *last_sent = date_universal_now();
1183 
1184  pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));
1185  dump_pdu("Sending enquire link:", smpp->conn->id, pdu, smpp->log_format);
1186  os = smpp_pdu_pack(smpp->conn->id, pdu);
1187  if (os != NULL)
1188  ret = conn_write(conn, os); /* Write errors checked by caller. */
1189  else
1190  ret = -1;
1191  octstr_destroy(os);
1192  smpp_pdu_destroy(pdu);
1193 
1194  return ret;
1195 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
Octstr * id
Definition: smscconn_p.h:174
long enquire_link_interval
Definition: smsc_smpp.c:171
SMSCConn * conn
Definition: smsc_smpp.c:188
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long log_format
Definition: smsc_smpp.c:186
long date_universal_now(void)
Definition: date.c:340
Definition: octstr.c:118
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
Counter * message_id_counter
Definition: smsc_smpp.c:150

◆ send_gnack()

static int send_gnack ( SMPP smpp,
Connection conn,
long  reason,
unsigned long  seq_num 
)
static

Definition at line 1197 of file smsc_smpp.c.

References SMPP::conn, conn_write(), dump_pdu, smscconn::id, SMPP::log_format, octstr_destroy(), smpp_pdu_create(), smpp_pdu_destroy(), smpp_pdu_pack(), and SMPP_PDU::u.

Referenced by handle_pdu(), and io_thread().

1198 {
1199  SMPP_PDU *pdu;
1200  Octstr *os;
1201  int ret;
1202 
1203  pdu = smpp_pdu_create(generic_nack, seq_num);
1204  pdu->u.generic_nack.command_status = reason;
1205  dump_pdu("Sending generic_nack:", smpp->conn->id, pdu, smpp->log_format);
1206  os = smpp_pdu_pack(smpp->conn->id, pdu);
1207  if (os != NULL)
1208  ret = conn_write(conn, os);
1209  else
1210  ret = -1;
1211  octstr_destroy(os);
1212  smpp_pdu_destroy(pdu);
1213 
1214  return ret;
1215 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
union SMPP_PDU::@15 u
long log_format
Definition: smsc_smpp.c:186
Definition: octstr.c:118
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400

◆ send_messages()

static int send_messages ( SMPP smpp,
Connection conn,
long *  pending_submits 
)
static

Definition at line 1256 of file smsc_smpp.c.

References bb_smscconn_send_failed(), SMPP::conn, debug(), dict_put(), gw_prioqueue_remove(), smscconn::id, SMPP::load, load_get(), load_increase, msg, msg_to_pdu(), SMPP::msgs_to_send, octstr_create, octstr_destroy(), octstr_format(), octstr_get_cstr, send_pdu(), SMPP::sent_msgs, smpp_msg_create(), smpp_pdu_destroy(), SMSCCONN_FAILED_MALFORMED, SMSCCONN_FAILED_TEMPORARILY, smscconn::throughput, and SMPP_PDU::u.

Referenced by io_thread().

1257 {
1258  Msg *msg;
1259  SMPP_PDU *pdu;
1260  Octstr *os;
1261 
1262  if (*pending_submits == -1)
1263  return 0;
1264 
1265  while (*pending_submits < smpp->max_pending_submits) {
1266  /* check our throughput */
1267  if (smpp->conn->throughput > 0 && load_get(smpp->load, 0) >= smpp->conn->throughput) {
1268  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput limit exceeded (%.02f,%.02f)",
1269  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1270  break;
1271  }
1272  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput (%.02f,%.02f)",
1273  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1274 
1275  /* Get next message, quit if none to be sent */
1277  if (msg == NULL)
1278  break;
1279 
1280  /* Send PDU, record it as waiting for ack from SMS center */
1281  pdu = msg_to_pdu(smpp, msg);
1282  if (pdu == NULL) {
1284  continue;
1285  }
1286  /* check for write errors */
1287  if (send_pdu(conn, smpp, pdu) == 0) {
1288  struct smpp_msg *smpp_msg = smpp_msg_create(msg);
1289  os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
1290  dict_put(smpp->sent_msgs, os, smpp_msg);
1291  smpp_pdu_destroy(pdu);
1292  octstr_destroy(os);
1293  ++(*pending_submits);
1294  load_increase(smpp->load);
1295  }
1296  else { /* write error occurs */
1297  smpp_pdu_destroy(pdu);
1299  return -1;
1300  }
1301  }
1302 
1303  return 0;
1304 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1237
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
static struct smpp_msg * smpp_msg_create(Msg *msg)
Definition: smsc_smpp.c:201
double load_get(Load *load, int pos)
Definition: load.c:191
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
double throughput
Definition: smscconn_p.h:203
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:265
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Load * load
Definition: smsc_smpp.c:187
union SMPP_PDU::@15 u
#define load_increase(load)
Definition: load.h:94
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
static SMPP_PDU * msg_to_pdu(SMPP *smpp, Msg *msg)
Definition: smsc_smpp.c:870
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ send_msg_cb()

static int send_msg_cb ( SMSCConn conn,
Msg msg 
)
static

Definition at line 2548 of file smsc_smpp.c.

References smscconn::data, gw_prioqueue_produce, gwthread_wakeup(), msg, msg_duplicate(), SMPP::msgs_to_send, and SMPP::transmitter.

Referenced by smsc_smpp_create().

2549 {
2550  SMPP *smpp;
2551 
2552  smpp = conn->data;
2555  return 0;
2556 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
void * data
Definition: smscconn_p.h:250
#define gw_prioqueue_produce(queue, item)
Definition: gw-prioqueue.h:98
void gwthread_wakeup(long thread)
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long transmitter
Definition: smsc_smpp.c:145

◆ send_pdu()

static int send_pdu ( Connection conn,
SMPP smpp,
SMPP_PDU pdu 
)
static

Definition at line 1237 of file smsc_smpp.c.

References SMPP::conn, conn_write(), dump_pdu, smscconn::id, SMPP::log_format, octstr_destroy(), and smpp_pdu_pack().

Referenced by handle_pdu(), open_receiver(), open_transceiver(), open_transmitter(), and send_messages().

1238 {
1239  Octstr *os;
1240  int ret;
1241 
1242  dump_pdu("Sending PDU:", smpp->conn->id, pdu, smpp->log_format);
1243  os = smpp_pdu_pack(smpp->conn->id, pdu);
1244  if (os) {
1245  /* Caller checks for write errors later */
1246  ret = conn_write(conn, os);
1247  /* it's not a error if we still have data buffered */
1248  ret = (ret == 1) ? 0 : ret;
1249  } else
1250  ret = -1;
1251  octstr_destroy(os);
1252  return ret;
1253 }
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long log_format
Definition: smsc_smpp.c:186
Definition: octstr.c:118
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104

◆ send_unbind()

static int send_unbind ( SMPP smpp,
Connection conn 
)
static

Definition at line 1217 of file smsc_smpp.c.

References SMPP::conn, conn_write(), counter_increase(), dump_pdu, smscconn::id, SMPP::log_format, SMPP::message_id_counter, octstr_destroy(), smpp_pdu_create(), smpp_pdu_destroy(), and smpp_pdu_pack().

Referenced by io_thread().

1218 {
1219  SMPP_PDU *pdu;
1220  Octstr *os;
1221  int ret;
1222 
1223  pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));
1224  dump_pdu("Sending unbind:", smpp->conn->id, pdu, smpp->log_format);
1225  os = smpp_pdu_pack(smpp->conn->id, pdu);
1226  if (os != NULL)
1227  ret = conn_write(conn, os);
1228  else
1229  ret = -1;
1230  octstr_destroy(os);
1231  smpp_pdu_destroy(pdu);
1232 
1233  return ret;
1234 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:188
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long log_format
Definition: smsc_smpp.c:186
Definition: octstr.c:118
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
Counter * message_id_counter
Definition: smsc_smpp.c:150

◆ shutdown_cb()

static int shutdown_cb ( SMSCConn conn,
int  finish_sending 
)
static

Definition at line 2559 of file smsc_smpp.c.

References smscconn::data, debug(), smscconn::flow_mutex, gwthread_wakeup(), mutex_lock, mutex_unlock, smscconn::name, octstr_get_cstr, SMPP::quitting, SMPP::receiver, SMSCCONN_KILLED_SHUTDOWN, SMPP::transmitter, and smscconn::why_killed.

Referenced by smsc_smpp_create().

2560 {
2561  SMPP *smpp;
2562 
2563  if (conn == NULL)
2564  return -1;
2565 
2566  debug("bb.smpp", 0, "Shutting down SMSCConn %s (%s)",
2567  octstr_get_cstr(conn->name),
2568  finish_sending ? "slow" : "instant");
2569 
2570  mutex_lock(conn->flow_mutex);
2571 
2573 
2574  smpp = conn->data;
2575  if (smpp == NULL) {
2576  mutex_unlock(conn->flow_mutex);
2577  return 0;
2578  }
2579 
2580  smpp->quitting = 1;
2581  if (smpp->transmitter != -1)
2583 
2584  if (smpp->receiver != -1)
2585  gwthread_wakeup(smpp->receiver);
2586 
2587  mutex_unlock(conn->flow_mutex);
2588 
2589  return 0;
2590 }
Octstr * name
Definition: smscconn_p.h:173
#define mutex_unlock(m)
Definition: thread.h:136
void * data
Definition: smscconn_p.h:250
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
long receiver
Definition: smsc_smpp.c:146
Mutex * flow_mutex
Definition: smscconn_p.h:157
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwthread_wakeup(long thread)
#define mutex_lock(m)
Definition: thread.h:130
long transmitter
Definition: smsc_smpp.c:145
volatile int quitting
Definition: smsc_smpp.c:170

◆ smpp_create()

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 
)
static

Definition at line 229 of file smsc_smpp.c.

References SMPP::address_range, SMPP::alt_addr_charset, alt_charset, SMPP::alt_charset, SMPP::autodetect_addr, SMPP::bind_addr_npi, SMPP::bind_addr_ton, SMPP::conn, SMPP::connection_timeout, counter_create(), counter_increase(), SMPP::dest_addr_npi, SMPP::dest_addr_ton, dict_create(), SMPP::enquire_link_interval, SMPP::esm_class, gw_prioqueue_add_producer(), gw_prioqueue_create(), gwlist_create, host, SMPP::host, SMPP::load, load_add_interval(), load_create_real(), SMPP::max_pending_submits, SMPP::message_id_counter, SMPP::msgs_to_send, SMPP::my_number, octstr_duplicate, our_port, SMPP::our_port, SMPP::our_receiver_port, password, SMPP::password, SMPP::priority, SMPP::quitting, SMPP::receive_port, SMPP::received_msgs, SMPP::receiver, SMPP::sent_msgs, SMPP::service_type, SMPP::smpp_msg_id_type, sms_priority_compare(), SMPP::source_addr_npi, SMPP::source_addr_ton, SMPP::ssl_client_certkey_file, SMPP::system_type, SMPP::throttling_err_time, SMPP::transmit_port, SMPP::transmitter, SMPP::use_ssl, username, SMPP::username, SMPP::validityperiod, SMPP::version, SMPP::wait_ack, and SMPP::wait_ack_action.

Referenced by smsc_smpp_create().

241 {
242  SMPP *smpp;
243 
244  smpp = gw_malloc(sizeof(*smpp));
245  smpp->transmitter = -1;
246  smpp->receiver = -1;
248  smpp->sent_msgs = dict_create(max_pending_submits, NULL);
250  smpp->received_msgs = gwlist_create();
253  smpp->host = octstr_duplicate(host);
254  smpp->system_type = octstr_duplicate(system_type);
255  smpp->our_port = our_port;
256  smpp->our_receiver_port = our_receiver_port;
259  smpp->address_range = octstr_duplicate(address_range);
260  smpp->source_addr_ton = source_addr_ton;
261  smpp->source_addr_npi = source_addr_npi;
262  smpp->dest_addr_ton = dest_addr_ton;
263  smpp->dest_addr_npi = dest_addr_npi;
264  smpp->my_number = octstr_duplicate(my_number);
265  smpp->service_type = octstr_duplicate(service_type);
266  smpp->transmit_port = transmit_port;
267  smpp->receive_port = receive_port;
268  smpp->enquire_link_interval = enquire_link_interval;
269  smpp->max_pending_submits = max_pending_submits;
270  smpp->quitting = 0;
271  smpp->version = version;
272  smpp->priority = priority;
273  smpp->validityperiod = validity;
274  smpp->conn = conn;
275  smpp->throttling_err_time = 0;
276  smpp->smpp_msg_id_type = smpp_msg_id_type;
277  smpp->autodetect_addr = autodetect_addr;
279  smpp->alt_addr_charset = octstr_duplicate(alt_addr_charset);
280  smpp->connection_timeout = connection_timeout;
281  smpp->wait_ack = wait_ack;
282  smpp->wait_ack_action = wait_ack_action;
283  smpp->bind_addr_ton = 0;
284  smpp->bind_addr_npi = 0;
285  smpp->use_ssl = 0;
286  smpp->ssl_client_certkey_file = NULL;
287  smpp->load = load_create_real(0);
288  load_add_interval(smpp->load, 1);
289  smpp->esm_class = esm_class;
290 
291  return smpp;
292 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static long our_port
Definition: radius_acct.c:87
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
int our_receiver_port
Definition: smsc_smpp.c:163
Octstr * service_type
Definition: smsc_smpp.c:157
long bind_addr_npi
Definition: smsc_smpp.c:165
long max_pending_submits
Definition: smsc_smpp.c:172
long enquire_link_interval
Definition: smsc_smpp.c:171
int transmit_port
Definition: smsc_smpp.c:166
int load_add_interval(Load *load, int interval)
Definition: load.c:111
SMSCConn * conn
Definition: smsc_smpp.c:188
int version
Definition: smsc_smpp.c:173
static Octstr * host
Definition: fakesmsc.c:122
long bind_addr_ton
Definition: smsc_smpp.c:164
int validityperiod
Definition: smsc_smpp.c:175
Load * load_create_real(int heuristic)
Definition: load.c:97
int source_addr_npi
Definition: smsc_smpp.c:159
time_t throttling_err_time
Definition: smsc_smpp.c:176
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Octstr * alt_addr_charset
Definition: smsc_smpp.c:180
unsigned char * username
Definition: test_cimd2.c:99
int use_ssl
Definition: smsc_smpp.c:168
unsigned char * password
Definition: test_cimd2.c:100
long receiver
Definition: smsc_smpp.c:146
int sms_priority_compare(const void *a, const void *b)
Definition: sms.c:395
Counter * counter_create(void)
Definition: counter.c:94
Octstr * alt_charset
Definition: smsc_smpp.c:179
int smpp_msg_id_type
Definition: smsc_smpp.c:177
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int dest_addr_ton
Definition: smsc_smpp.c:160
Octstr * my_number
Definition: smsc_smpp.c:156
gw_prioqueue_t * gw_prioqueue_create(int(*cmp)(const void *, const void *))
Definition: gw-prioqueue.c:174
Load * load
Definition: smsc_smpp.c:187
long connection_timeout
Definition: smsc_smpp.c:181
int autodetect_addr
Definition: smsc_smpp.c:178
Octstr * system_type
Definition: smsc_smpp.c:152
long wait_ack
Definition: smsc_smpp.c:183
Octstr * address_range
Definition: smsc_smpp.c:155
Dict * sent_msgs
Definition: smsc_smpp.c:148
Octstr * host
Definition: smsc_smpp.c:151
int source_addr_ton
Definition: smsc_smpp.c:158
List * received_msgs
Definition: smsc_smpp.c:149
int wait_ack_action
Definition: smsc_smpp.c:184
#define gwlist_create()
Definition: list.h:136
int dest_addr_npi
Definition: smsc_smpp.c:161
Octstr * username
Definition: smsc_smpp.c:153
int receive_port
Definition: smsc_smpp.c:167
int our_port
Definition: smsc_smpp.c:162
static Octstr * alt_charset
Definition: opensmppbox.c:129
Counter * message_id_counter
Definition: smsc_smpp.c:150
long transmitter
Definition: smsc_smpp.c:145
volatile int quitting
Definition: smsc_smpp.c:170
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169
int priority
Definition: smsc_smpp.c:174
void gw_prioqueue_add_producer(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:331
int esm_class
Definition: smsc_smpp.c:185
Octstr * password
Definition: smsc_smpp.c:154

◆ smpp_destroy()

static void smpp_destroy ( SMPP smpp)
static

Definition at line 295 of file smsc_smpp.c.

References SMPP::address_range, SMPP::alt_addr_charset, SMPP::alt_charset, counter_destroy(), dict_destroy(), gw_prioqueue_destroy(), gwlist_destroy(), SMPP::host, SMPP::load, load_destroy(), SMPP::message_id_counter, msg_destroy_item(), SMPP::msgs_to_send, SMPP::my_number, octstr_destroy(), SMPP::password, SMPP::received_msgs, SMPP::sent_msgs, SMPP::service_type, SMPP::ssl_client_certkey_file, SMPP::system_type, and SMPP::username.

Referenced by io_thread(), and smsc_smpp_create().

296 {
297  if (smpp != NULL) {
299  dict_destroy(smpp->sent_msgs);
302  octstr_destroy(smpp->host);
303  octstr_destroy(smpp->username);
304  octstr_destroy(smpp->password);
308  octstr_destroy(smpp->my_number);
312  load_destroy(smpp->load);
313  gw_free(smpp);
314  }
315 }
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
Octstr * service_type
Definition: smsc_smpp.c:157
void counter_destroy(Counter *counter)
Definition: counter.c:110
Octstr * alt_addr_charset
Definition: smsc_smpp.c:180
void msg_destroy_item(void *msg)
Definition: msg.c:147
Octstr * alt_charset
Definition: smsc_smpp.c:179
Octstr * my_number
Definition: smsc_smpp.c:156
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Load * load
Definition: smsc_smpp.c:187
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
void dict_destroy(Dict *dict)
Definition: dict.c:215
void gw_prioqueue_destroy(gw_prioqueue_t *queue, void(*item_destroy)(void *))
Definition: gw-prioqueue.c:201
Dict * sent_msgs
Definition: smsc_smpp.c:148
Octstr * host
Definition: smsc_smpp.c:151
List * received_msgs
Definition: smsc_smpp.c:149
void load_destroy(Load *load)
Definition: load.c:145
Octstr * username
Definition: smsc_smpp.c:153
Counter * message_id_counter
Definition: smsc_smpp.c:150
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169
Octstr * password
Definition: smsc_smpp.c:154
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ smpp_msg_create()

static struct smpp_msg* smpp_msg_create ( Msg msg)
inlinestatic

Definition at line 201 of file smsc_smpp.c.

References gw_assert(), msg, smpp_msg::msg, and smpp_msg::sent_time.

Referenced by send_messages().

202 {
203  struct smpp_msg *result = gw_malloc(sizeof(struct smpp_msg));
204 
205  gw_assert(result != NULL);
206  result->sent_time = time(NULL);
207  result->msg = msg;
208 
209  return result;
210 }
gw_assert(wtls_machine->packet_to_send !=NULL)
time_t sent_time
Definition: smsc_smpp.c:193
Msg * msg
Definition: smsc_smpp.c:194
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ smpp_msg_destroy()

static void smpp_msg_destroy ( struct smpp_msg msg,
int  destroy_msg 
)
inlinestatic

Definition at line 216 of file smsc_smpp.c.

References msg, and msg_destroy().

Referenced by do_queue_cleanup(), handle_pdu(), and io_thread().

217 {
218  /* sanity check */
219  if (msg == NULL)
220  return;
221 
222  if (destroy_msg && msg->msg != NULL)
223  msg_destroy(msg->msg);
224 
225  gw_free(msg);
226 }
void msg_destroy(Msg *msg)
Definition: msg.c:132
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ smpp_status_to_smscconn_failure_reason()

static long smpp_status_to_smscconn_failure_reason ( long  status)
static

◆ smsc_smpp_create()

int smsc_smpp_create ( SMSCConn conn,
CfgGroup grp 
)

Definition at line 2599 of file smsc_smpp.c.

References alt_charset, SMPP::bind_addr_npi, SMPP::bind_addr_ton, cfg_get, cfg_get_bool(), cfg_get_integer(), SMPP::conn, smscconn::data, error(), ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE, gwthread_create, gwthread_join(), gwthread_wakeup(), host, smscconn::id, io_arg_create(), io_thread(), SMPP::log_format, smscconn::name, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), ok, our_port, panic, password, port, smscconn::queued, queued_cb(), SMPP::quitting, SMPP::receiver, SMPP::retry, smscconn::send_msg, send_msg_cb(), smscconn::shutdown, shutdown_cb(), smpp_create(), SMPP_DEFAULT_CONNECTION_TIMEOUT, SMPP_DEFAULT_PORT, SMPP_DEFAULT_PRIORITY, SMPP_DEFAULT_VERSION, SMPP_DEFAULT_WAITACK, smpp_destroy(), SMPP_ENQUIRE_LINK_INTERVAL, SMPP_MAX_PENDING_SUBMITS, SMPP_PDU_DUMP_MULTILINE, SMPP_WAITACK_REQUEUE, SMS_PARAM_UNDEFINED, smsc_id, SMSCCONN_CONNECTING, SMPP::ssl_client_certkey_file, smscconn::status, SMPP::transmitter, SMPP::use_ssl, username, and warning().

Referenced by smscconn_create().

2600 {
2601  Octstr *host;
2602  long port;
2603  long receive_port;
2604  Octstr *username;
2605  Octstr *password;
2606  Octstr *system_id;
2607  Octstr *system_type;
2608  Octstr *address_range;
2609  long source_addr_ton;
2610  long source_addr_npi;
2611  long dest_addr_ton;
2612  long dest_addr_npi;
2613  long our_port;
2614  long our_receiver_port;
2615  Octstr *my_number;
2616  Octstr *service_type;
2617  SMPP *smpp;
2618  int ok;
2619  int transceiver_mode;
2620  Octstr *smsc_id;
2621  long enquire_link_interval;
2622  long max_pending_submits;
2623  long version;
2624  long priority;
2625  long validity;
2626  long smpp_msg_id_type;
2627  int autodetect_addr;
2629  Octstr *alt_addr_charset;
2630  long connection_timeout, wait_ack, wait_ack_action;
2631  long esm_class;
2632 
2633  my_number = alt_addr_charset = alt_charset = NULL;
2634  transceiver_mode = 0;
2635  autodetect_addr = 1;
2636 
2637  host = cfg_get(grp, octstr_imm("host"));
2638  if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1)
2639  port = 0;
2640  if (cfg_get_integer(&receive_port, grp, octstr_imm("receive-port")) == -1)
2641  receive_port = 0;
2642 
2643  if (cfg_get_integer(&our_port, grp, octstr_imm("our-port")) == -1)
2644  our_port = 0;
2645  if (cfg_get_integer(&our_receiver_port, grp, octstr_imm("our-receiver-port")) == -1)
2646  our_receiver_port = 0;
2647 
2648  cfg_get_bool(&transceiver_mode, grp, octstr_imm("transceiver-mode"));
2649  username = cfg_get(grp, octstr_imm("smsc-username"));
2650  password = cfg_get(grp, octstr_imm("smsc-password"));
2651  system_type = cfg_get(grp, octstr_imm("system-type"));
2652  address_range = cfg_get(grp, octstr_imm("address-range"));
2653  my_number = cfg_get(grp, octstr_imm("my-number"));
2654  service_type = cfg_get(grp, octstr_imm("service-type"));
2655 
2656  system_id = cfg_get(grp, octstr_imm("system-id"));
2657  if (system_id != NULL) {
2658  warning(0, "SMPP: obsolete system-id variable is set, "
2659  "use smsc-username instead.");
2660  if (username == NULL) {
2661  warning(0, "SMPP: smsc-username not set, using system-id instead");
2662  username = system_id;
2663  } else
2664  octstr_destroy(system_id);
2665  }
2666 
2667  /*
2668  * check if timing values have been configured, otherwise
2669  * use the predefined default values.
2670  */
2671  if (cfg_get_integer(&enquire_link_interval, grp,
2672  octstr_imm("enquire-link-interval")) == -1)
2673  enquire_link_interval = SMPP_ENQUIRE_LINK_INTERVAL;
2674  if (cfg_get_integer(&max_pending_submits, grp,
2675  octstr_imm("max-pending-submits")) == -1)
2676  max_pending_submits = SMPP_MAX_PENDING_SUBMITS;
2677 
2678  /* Check that config is OK */
2679  ok = 1;
2680  if (host == NULL) {
2681  error(0, "SMPP: Configuration file doesn't specify host");
2682  ok = 0;
2683  }
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);
2688  }
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!");
2692  ok = 0;
2693  }
2694  if (username == NULL) {
2695  error(0, "SMPP: Configuration file doesn't specify username.");
2696  ok = 0;
2697  }
2698  if (password == NULL) {
2699  error(0, "SMPP: Configuration file doesn't specify password.");
2700  ok = 0;
2701  }
2702  if (system_type == NULL) {
2703  error(0, "SMPP: Configuration file doesn't specify system-type.");
2704  ok = 0;
2705  }
2706  if (octstr_len(service_type) > 6) {
2707  error(0, "SMPP: Service type must be 6 characters or less.");
2708  ok = 0;
2709  }
2710  if (transceiver_mode && receive_port != 0) {
2711  warning(0, "SMPP: receive-port for transceiver mode defined, ignoring.");
2712  receive_port = 0;
2713  }
2714 
2715  if (!ok)
2716  return -1;
2717 
2718  /* if the ton and npi values are forced, set them, else set them to -1 */
2719  if (cfg_get_integer(&source_addr_ton, grp,
2720  octstr_imm("source-addr-ton")) == -1)
2721  source_addr_ton = -1;
2722  if (cfg_get_integer(&source_addr_npi, grp,
2723  octstr_imm("source-addr-npi")) == -1)
2724  source_addr_npi = -1;
2725  if (cfg_get_integer(&dest_addr_ton, grp,
2726  octstr_imm("dest-addr-ton")) == -1)
2727  dest_addr_ton = -1;
2728  if (cfg_get_integer(&dest_addr_npi, grp,
2729  octstr_imm("dest-addr-npi")) == -1)
2730  dest_addr_npi = -1;
2731 
2732  /* if source addr autodetection should be used set this to 1 */
2733  if (cfg_get_bool(&autodetect_addr, grp, octstr_imm("source-addr-autodetect")) == -1)
2734  autodetect_addr = 1; /* default is autodetect if no option defined */
2735 
2736  /* check for any specified interface version */
2737  if (cfg_get_integer(&version, grp, octstr_imm("interface-version")) == -1)
2738  version = SMPP_DEFAULT_VERSION;
2739  else
2740  /* convert decimal to BCD */
2741  version = ((version / 10) << 4) + (version % 10);
2742 
2743  /* check for any specified priority value in range [0-5] */
2744  if (cfg_get_integer(&priority, grp, octstr_imm("priority")) == -1)
2745  priority = SMPP_DEFAULT_PRIORITY;
2746  else if (priority < 0 || priority > 3)
2747  panic(0, "SMPP: Invalid value for priority directive in configuraton (allowed range 0-3).");
2748 
2749  /* check for message validity period */
2750  if (cfg_get_integer(&validity, grp, octstr_imm("validityperiod")) == -1)
2751  validity = SMS_PARAM_UNDEFINED;
2752  else if (validity < 0)
2753  panic(0, "SMPP: Invalid value for validity period (allowed value >= 0).");
2754 
2755  /* set the msg_id type variable for this SMSC */
2756  if (cfg_get_integer(&smpp_msg_id_type, grp, octstr_imm("msg-id-type")) == -1) {
2757  /*
2758  * defaults to C string "as-is" style
2759  */
2760  smpp_msg_id_type = -1;
2761  } else {
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");
2764  }
2765 
2766  /* check for an alternative charset */
2767  alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
2768  alt_addr_charset = cfg_get(grp, octstr_imm("alt-addr-charset"));
2769 
2770  /* check for connection timeout */
2771  if (cfg_get_integer(&connection_timeout, grp, octstr_imm("connection-timeout")) == -1)
2772  connection_timeout = SMPP_DEFAULT_CONNECTION_TIMEOUT;
2773 
2774  /* check if wait-ack timeout set */
2775  if (cfg_get_integer(&wait_ack, grp, octstr_imm("wait-ack")) == -1)
2776  wait_ack = SMPP_DEFAULT_WAITACK;
2777 
2778  if (cfg_get_integer(&wait_ack_action, grp, octstr_imm("wait-ack-expire")) == -1)
2779  wait_ack_action = SMPP_WAITACK_REQUEUE;
2780  else if (wait_ack_action > 0x03 || wait_ack_action < 0)
2781  panic(0, "SMPP: Invalid wait-ack-expire directive in configuration.");
2782 
2783  if (cfg_get_integer(&esm_class, grp, octstr_imm("esm-class")) == -1) {
2785  }
2786 
2787  smpp = smpp_create(conn, host, port, receive_port, our_port, our_receiver_port, system_type,
2788  username, password, address_range,
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);
2794 
2795  cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton"));
2796  cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
2797 
2798  /* set connect retry, default false */
2799  if (cfg_get_bool(&smpp->retry, grp, octstr_imm("retry")) == -1)
2800  smpp->retry = 0;
2801 
2802  cfg_get_bool(&smpp->use_ssl, grp, octstr_imm("use-ssl"));
2803  if (smpp->use_ssl)
2804 #ifndef HAVE_LIBSSL
2805  panic(0, "SMPP: Can not use 'use-ssl' without SSL support compiled in.");
2806 #else
2807  smpp->ssl_client_certkey_file = cfg_get(grp, octstr_imm("ssl-client-certkey-file"));
2808 #endif
2809 
2810  conn->data = smpp;
2811  conn->name = octstr_format("%sSMPP:%S:%d/%d:%S:%S",
2812  (smpp->use_ssl ? "S" : ""), host, port,
2813  (!receive_port && transceiver_mode ? port : receive_port),
2814  username, system_type);
2815 
2816  smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
2817  if (smsc_id == NULL) {
2818  conn->id = octstr_duplicate(conn->name);
2819  }
2820 
2821  if (cfg_get_integer(&smpp->log_format, grp, octstr_imm("log-format")) == -1)
2823 
2827  octstr_destroy(system_type);
2828  octstr_destroy(address_range);
2829  octstr_destroy(my_number);
2832  octstr_destroy(alt_addr_charset);
2833  octstr_destroy(service_type);
2834 
2835  conn->status = SMSCCONN_CONNECTING;
2836 
2837  /*
2838  * I/O threads are only started if the corresponding ports
2839  * have been configured with positive numbers. Use 0 to
2840  * disable the creation of the corresponding thread.
2841  */
2842  if (port != 0)
2844  (transceiver_mode ? 2 : 1)));
2845  if (receive_port != 0)
2846  smpp->receiver = gwthread_create(io_thread, io_arg_create(smpp, 0));
2847 
2848  if ((port != 0 && smpp->transmitter == -1) ||
2849  (receive_port != 0 && smpp->receiver == -1)) {
2850  error(0, "SMPP[%s]: Couldn't start I/O threads.",
2851  octstr_get_cstr(smpp->conn->id));
2852  smpp->quitting = 1;
2853  if (smpp->transmitter != -1) {
2855  gwthread_join(smpp->transmitter);
2856  }
2857  if (smpp->receiver != -1) {
2858  gwthread_wakeup(smpp->receiver);
2859  gwthread_join(smpp->receiver);
2860  }
2861  smpp_destroy(conn->data);
2862  conn->data = NULL;
2863  return -1;
2864  }
2865 
2866  conn->shutdown = shutdown_cb;
2867  conn->queued = queued_cb;
2868  conn->send_msg = send_msg_cb;
2869 
2870  return 0;
2871 }
Octstr * name
Definition: smscconn_p.h:173
void error(int err, const char *fmt,...)
Definition: log.c:648
static long our_port
Definition: radius_acct.c:87
static long queued_cb(SMSCConn *conn)
Definition: smsc_smpp.c:2537
Definition: http.c:2014
long bind_addr_npi
Definition: smsc_smpp.c:165
Octstr * id
Definition: smscconn_p.h:174
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:250
static struct io_arg * io_arg_create(SMPP *smpp, int transmitter)
Definition: smsc_smpp.c:2231
#define SMPP_ENQUIRE_LINK_INTERVAL
Definition: smsc_smpp.c:120
SMSCConn * conn
Definition: smsc_smpp.c:188
#define SMPP_DEFAULT_CONNECTION_TIMEOUT
Definition: smsc_smpp.c:125
static Octstr * host
Definition: fakesmsc.c:122
#define cfg_get(grp, varname)
Definition: cfg.h:86
long bind_addr_ton
Definition: smsc_smpp.c:164
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void io_thread(void *arg)
Definition: smsc_smpp.c:2311
unsigned char * username
Definition: test_cimd2.c:99
int use_ssl
Definition: smsc_smpp.c:168
static int port
Definition: fakesmsc.c:121
static int shutdown_cb(SMSCConn *conn, int finish_sending)
Definition: smsc_smpp.c:2559
unsigned char * password
Definition: test_cimd2.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
long receiver
Definition: smsc_smpp.c:146
#define SMPP_DEFAULT_VERSION
Definition: smsc_smpp.c:122
static void smpp_destroy(SMPP *smpp)
Definition: smsc_smpp.c:295
static int send_msg_cb(SMSCConn *conn, Msg *msg)
Definition: smsc_smpp.c:2548
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)
Definition: smsc_smpp.c:229
#define ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE
Definition: smpp_pdu.h:139
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
#define SMPP_DEFAULT_PORT
Definition: smsc_smpp.c:128
void warning(int err, const char *fmt,...)
Definition: log.c:660
#define SMPP_MAX_PENDING_SUBMITS
Definition: smsc_smpp.c:121
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int retry
Definition: smsc_smpp.c:182
long log_format
Definition: smsc_smpp.c:186
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:759
Definition: octstr.c:118
int(* shutdown)(SMSCConn *conn, int finish_sending)
Definition: smscconn_p.h:230
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
Definition: wtp_tid.h:82
#define SMPP_DEFAULT_WAITACK
Definition: smsc_smpp.c:126
#define panic
Definition: log.h:87
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
long(* queued)(SMSCConn *conn)
Definition: smscconn_p.h:241
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:236
#define SMPP_DEFAULT_PRIORITY
Definition: smsc_smpp.c:123
#define SMPP_WAITACK_REQUEUE
Definition: smsc_smpp.c:135
static Octstr * alt_charset
Definition: opensmppbox.c:129
long transmitter
Definition: smsc_smpp.c:145
volatile int quitting
Definition: smsc_smpp.c:170
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:169

◆ smscconn_failure_reason_to_smpp_status()

static long smscconn_failure_reason_to_smpp_status ( long  reason)
static
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.