Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
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 367 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().

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

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

2243 {
2244  List *keys;
2245  Octstr *key;
2246  struct smpp_msg *smpp_msg;
2247  time_t now = time(NULL);
2248 
2249  if (*pending_submits <= 0)
2250  return 0;
2251 
2252  /* check if action set to wait ack for ever */
2254  return 0;
2255 
2256  keys = dict_keys(smpp->sent_msgs);
2257  if (keys == NULL)
2258  return 0;
2259 
2260  while ((key = gwlist_extract_first(keys)) != NULL) {
2261  smpp_msg = dict_get(smpp->sent_msgs, key);
2262  if (smpp_msg != NULL && difftime(now, smpp_msg->sent_time) > smpp->wait_ack) {
2263  switch(smpp->wait_ack_action) {
2264  case SMPP_WAITACK_RECONNECT: /* reconnect */
2265  /* found at least one not acked msg */
2266  warning(0, "SMPP[%s]: Not ACKED message found, reconnecting.",
2267  octstr_get_cstr(smpp->conn->id));
2268  octstr_destroy(key);
2270  return 1; /* io_thread will reconnect */
2271  case SMPP_WAITACK_REQUEUE: /* requeue */
2272  smpp_msg = dict_remove(smpp->sent_msgs, key);
2273  if (smpp_msg != NULL) {
2274  warning(0, "SMPP[%s]: Not ACKED message found, will retransmit."
2275  " SENT<%ld>sec. ago, SEQ<%s>, DST<%s>",
2276  octstr_get_cstr(smpp->conn->id),
2277  (long)difftime(now, smpp_msg->sent_time) ,
2278  octstr_get_cstr(key),
2279  octstr_get_cstr(smpp_msg->msg->sms.receiver));
2281  smpp_msg_destroy(smpp_msg, 0);
2282  (*pending_submits)--;
2283  }
2284  break;
2285  default:
2286  error(0, "SMPP[%s] Unknown clenup action defined 0x%02x.",
2287  octstr_get_cstr(smpp->conn->id), smpp->wait_ack_action);
2288  octstr_destroy(key);
2290  return 0;
2291  }
2292  }
2293  octstr_destroy(key);
2294  }
2296 
2297  return 0;
2298 }
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:187
#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:192
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:322
void octstr_destroy_item(void *os)
Definition: octstr.c:334
long wait_ack
Definition: smsc_smpp.c:182
Msg * msg
Definition: smsc_smpp.c:193
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
int wait_ack_action
Definition: smsc_smpp.c:183
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:328
#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:215
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 1467 of file smsc_smpp.c.

References octstr_get_cstr, octstr_len(), and type.

Referenced by handle_dlr().

1468 {
1469  unsigned char *nec;
1470  int type;
1471  int err;
1472 
1473  if (network_error_code == NULL || octstr_len(network_error_code) != 3)
1474  return 0;
1475 
1476  nec = (unsigned char*) octstr_get_cstr(network_error_code);
1477  type = nec[0];
1478  err = (nec[1] << 8) | nec[2];
1479 
1480  if ((type >= '0') && (type <= '9')) {
1481  /* this is a bogous SMSC sending back network_error_code as
1482  * 3 digit string instead as in the delivery report. */
1483  sscanf((char*) nec, "%03d", &err);
1484  return err;
1485  }
1486 
1487  return err;
1488 }
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:340

◆ 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 1491 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().

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

◆ handle_mo_dcs()

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

Definition at line 508 of file smsc_smpp.c.

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

Referenced by data_sm_to_msg(), and pdu_to_msg().

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

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

Referenced by msg_to_pdu().

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

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

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

Referenced by smsc_smpp_create().

2228 {
2229  struct io_arg *io_arg;
2230 
2231  io_arg = gw_malloc(sizeof(*io_arg));
2232  io_arg->smpp = smpp;
2233  io_arg->transmitter = transmitter;
2234  return io_arg;
2235 }
int transmitter
Definition: smsc_smpp.c:2223
SMPP * smpp
Definition: smsc_smpp.c:2222

◆ io_thread()

static void io_thread ( void *  arg)
static

Definition at line 2307 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, 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().

2308 {
2309  SMPP *smpp;
2310  struct io_arg *io_arg;
2311  int transmitter;
2312  Connection *conn;
2313  int ret;
2314  long pending_submits;
2315  long len;
2316  SMPP_PDU *pdu;
2317  double timeout;
2318  time_t last_cleanup, last_enquire_sent, last_response, now;
2319 
2320  io_arg = arg;
2321  smpp = io_arg->smpp;
2322  transmitter = io_arg->transmitter;
2323  gw_free(io_arg);
2324 
2325  /* Make sure we log into our own log-file if defined */
2326  log_thread_to(smpp->conn->log_idx);
2327 
2328 #define IS_ACTIVE (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)
2329 
2330  conn = NULL;
2331  while (!smpp->quitting) {
2332  if (transmitter == 1)
2333  conn = open_transmitter(smpp);
2334  else if (transmitter == 2)
2335  conn = open_transceiver(smpp);
2336  else
2337  conn = open_receiver(smpp);
2338 
2339  pending_submits = -1;
2340  len = 0;
2341  last_response = last_cleanup = last_enquire_sent = time(NULL);
2342  while(conn != NULL) {
2343  ret = read_pdu(smpp, conn, &len, &pdu);
2344  if (ret == -1) { /* connection broken */
2345  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2346  octstr_get_cstr(smpp->conn->id));
2347  break;
2348  } else if (ret == -2) {
2349  /* wrong pdu length , send gnack */
2350  len = 0;
2351  if (send_gnack(smpp, conn, SMPP_ESME_RINVCMDLEN, 0) == -1) {
2352  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2353  octstr_get_cstr(smpp->conn->id));
2354  break;
2355  }
2356  } else if (ret == 1) { /* data available */
2357  /* Deal with the PDU we just got */
2358  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2359  ret = handle_pdu(smpp, conn, pdu, &pending_submits);
2360  smpp_pdu_destroy(pdu);
2361  if (ret == -1) {
2362  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2363  octstr_get_cstr(smpp->conn->id));
2364  break;
2365  }
2366 
2367  /*
2368  * check if we are still connected
2369  * Note: Function handle_pdu will set status to SMSCCONN_DISCONNECTED
2370  * when unbind was received.
2371  */
2372  if (smpp->conn->status == SMSCCONN_DISCONNECTED)
2373  break;
2374 
2375  /*
2376  * If we are not bounded then no PDU may coming from SMSC.
2377  * It's just a workaround for buggy SMSC's who send enquire_link's
2378  * although link is not bounded. Means: we doesn't notice these and if link
2379  * keep to be not bounden we are reconnect after defined timeout elapsed.
2380  */
2381  if (IS_ACTIVE) {
2382  /*
2383  * Store last response time.
2384  */
2385  time(&last_response);
2386  }
2387  } else { /* no data available */
2388  /* check last enquire_resp, if difftime > as idle_timeout
2389  * mark connection as broken.
2390  * We have some SMSC connections where connection seems to be OK, but
2391  * in reality is broken, because no responses received.
2392  */
2393  if (smpp->connection_timeout > 0 &&
2394  difftime(time(NULL), last_response) > smpp->connection_timeout) {
2395  /* connection seems to be broken */
2396  warning(0, "Got no responses within %ld sec., reconnecting...",
2397  (long) difftime(time(NULL), last_response));
2398  break;
2399  }
2400 
2401  time(&now);
2402  timeout = last_enquire_sent + smpp->enquire_link_interval - now;
2403  if (!IS_ACTIVE && timeout <= 0)
2404  timeout = smpp->enquire_link_interval;
2405  if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 &&
2406  smpp->throttling_err_time > 0 && pending_submits < smpp->max_pending_submits) {
2407  time_t tr_timeout = smpp->throttling_err_time + SMPP_THROTTLING_SLEEP_TIME - now;
2408  timeout = timeout > tr_timeout ? tr_timeout : timeout;
2409  } else if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 && smpp->conn->throughput > 0 &&
2410  smpp->max_pending_submits > pending_submits) {
2411  double t = 1.0 / smpp->conn->throughput;
2412  timeout = t < timeout ? t : timeout;
2413  }
2414  /* sleep a while */
2415  if (timeout > 0 && conn_wait(conn, timeout) == -1)
2416  break;
2417  }
2418 
2419  /* send enquire link, only if connection is active */
2420  if (IS_ACTIVE && send_enquire_link(smpp, conn, &last_enquire_sent) == -1)
2421  break;
2422 
2423  /* cleanup sent queue */
2424  if (transmitter && difftime(time(NULL), last_cleanup) > smpp->wait_ack) {
2425  if (do_queue_cleanup(smpp, &pending_submits))
2426  break; /* reconnect */
2427  time(&last_cleanup);
2428  }
2429 
2430  /* make sure we send */
2431  if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
2432  smpp->throttling_err_time = 0;
2433  if (send_messages(smpp, conn, &pending_submits) == -1)
2434  break;
2435  }
2436 
2437  /* unbind
2438  * Read so long as unbind_resp received or timeout passed. Otherwise we have
2439  * double delivered messages.
2440  */
2441  if (smpp->quitting) {
2442  if (!IS_ACTIVE || send_unbind(smpp, conn) == -1)
2443  break;
2444  time(&last_response);
2445  while(conn_wait(conn, 1.00) != -1 && IS_ACTIVE &&
2446  difftime(time(NULL), last_response) < SMPP_DEFAULT_SHUTDOWN_TIMEOUT) {
2447  if (read_pdu(smpp, conn, &len, &pdu) == 1) {
2448  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2449  handle_pdu(smpp, conn, pdu, &pending_submits);
2450  smpp_pdu_destroy(pdu);
2451  }
2452  }
2453  debug("bb.sms.smpp", 0, "SMPP[%s]: %s: break and shutting down",
2454  octstr_get_cstr(smpp->conn->id), __PRETTY_FUNCTION__);
2455 
2456  break;
2457  }
2458  }
2459 
2460  if (conn != NULL) {
2461  conn_destroy(conn);
2462  conn = NULL;
2463  }
2464  /* set reconnecting status first so that core don't put msgs into our queue */
2465  if (!smpp->quitting) {
2466  error(0, "SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
2467  octstr_get_cstr(smpp->conn->id), smpp->conn->reconnect_delay);
2468  mutex_lock(smpp->conn->flow_mutex);
2470  mutex_unlock(smpp->conn->flow_mutex);
2472  }
2473  /*
2474  * put all queued messages back into global queue,so if
2475  * we have another link running than messages will be delivered
2476  * quickly
2477  */
2478  if (transmitter) {
2479  Msg *msg;
2480  struct smpp_msg *smpp_msg;
2481  List *noresp;
2482  Octstr *key;
2483 
2485 
2486  while((msg = gw_prioqueue_remove(smpp->msgs_to_send)) != NULL)
2487  bb_smscconn_send_failed(smpp->conn, msg, reason, NULL);
2488 
2489  noresp = dict_keys(smpp->sent_msgs);
2490  while((key = gwlist_extract_first(noresp)) != NULL) {
2491  smpp_msg = dict_remove(smpp->sent_msgs, key);
2492  if (smpp_msg != NULL) {
2493  bb_smscconn_send_failed(smpp->conn, smpp_msg->msg, reason, NULL);
2494  smpp_msg_destroy(smpp_msg, 0);
2495  }
2496  octstr_destroy(key);
2497  }
2498  gwlist_destroy(noresp, NULL);
2499  }
2500  }
2501 
2502 #undef IS_ACTIVE
2503 
2504  /*
2505  * Shutdown sequence as follow:
2506  * 1) if this is TX session so join receiver and free SMPP
2507  * 2) if RX session available but no TX session so nothing to join then free SMPP
2508  */
2509  if (transmitter && smpp->receiver != -1) {
2510  gwthread_wakeup(smpp->receiver);
2511  gwthread_join(smpp->receiver);
2512  }
2513  if (transmitter || smpp->transmitter == -1) {
2514  debug("bb.smpp", 0, "SMSCConn %s shut down.",
2515  octstr_get_cstr(smpp->conn->name));
2516 
2517  mutex_lock(smpp->conn->flow_mutex);
2518  smpp->conn->status = SMSCCONN_DEAD;
2519  smpp->conn->data = NULL;
2520  mutex_unlock(smpp->conn->flow_mutex);
2521 
2522  smpp_destroy(smpp);
2524  }
2525 }
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:1311
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:1173
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:1196
#define IS_ACTIVE
Octstr * id
Definition: smscconn_p.h:174
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:249
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:187
static int do_queue_cleanup(SMPP *smpp, long *pending_submits)
Definition: smsc_smpp.c:2242
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:326
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:1216
int transmitter
Definition: smsc_smpp.c:2223
static void smpp_destroy(SMPP *smpp)
Definition: smsc_smpp.c:294
void conn_destroy(Connection *conn)
Definition: conn.c:621
static Connection * open_transceiver(SMPP *smpp)
Definition: smsc_smpp.c:1364
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:1725
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:322
void gwthread_sleep(double seconds)
long connection_timeout
Definition: smsc_smpp.c:181
long wait_ack
Definition: smsc_smpp.c:182
long log_format
Definition: smsc_smpp.c:185
Msg * msg
Definition: smsc_smpp.c:193
static int send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
Definition: smsc_smpp.c:1255
Dict * sent_msgs
Definition: smsc_smpp.c:148
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:898
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:1415
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:328
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT
Definition: smsc_smpp.c:127
SMPP * smpp
Definition: smsc_smpp.c:2222
#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:215
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 869 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, 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().

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

◆ open_receiver()

static Connection* open_receiver ( SMPP smpp)
static

Definition at line 1415 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().

1416 {
1417  SMPP_PDU *bind;
1418  Connection *conn;
1419 
1420 #ifdef HAVE_LIBSSL
1421  if (smpp->use_ssl)
1422  conn = conn_open_ssl(smpp->host, smpp->receive_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1423  else
1424 #endif
1425 
1426  if (smpp->our_receiver_port > 0)
1427  conn = conn_open_tcp_with_port(smpp->host, smpp->receive_port, smpp->our_receiver_port, smpp->conn->our_host);
1428  else
1429  conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host);
1430 
1431  if (conn == NULL) {
1432  error(0, "SMPP[%s]: Couldn't connect to server.",
1433  octstr_get_cstr(smpp->conn->id));
1434  return NULL;
1435  }
1436 
1437  bind = smpp_pdu_create(bind_receiver,
1439  bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username);
1440  bind->u.bind_receiver.password = octstr_duplicate(smpp->password);
1441  if (smpp->system_type == NULL)
1442  bind->u.bind_receiver.system_type = octstr_create("VMA");
1443  else
1444  bind->u.bind_receiver.system_type =
1446  bind->u.bind_receiver.interface_version = smpp->version;
1447  bind->u.bind_receiver.address_range =
1449  bind->u.bind_receiver.addr_ton = smpp->bind_addr_ton;
1450  bind->u.bind_receiver.addr_npi = smpp->bind_addr_npi;
1451  if (send_pdu(conn, smpp, bind) == -1) {
1452  error(0, "SMPP[%s]: Couldn't send bind_receiver to server.",
1453  octstr_get_cstr(smpp->conn->id));
1454  conn_destroy(conn);
1455  conn = NULL;
1456  }
1457  smpp_pdu_destroy(bind);
1458 
1459  return conn;
1460 }
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:490
int our_receiver_port
Definition: smsc_smpp.c:163
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1236
long bind_addr_npi
Definition: smsc_smpp.c:165
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:187
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:621
#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:542
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
union SMPP_PDU::@14 u
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 1364 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().

1365 {
1366  SMPP_PDU *bind;
1367  Connection *conn;
1368 
1369 #ifdef HAVE_LIBSSL
1370  if (smpp->use_ssl)
1371  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1372  else
1373 #endif
1374 
1375  if (smpp->our_port > 0)
1376  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1377  else
1378  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1379 
1380  if (conn == NULL) {
1381  error(0, "SMPP[%s]: Couldn't connect to server.",
1382  octstr_get_cstr(smpp->conn->id));
1383  return NULL;
1384  }
1385 
1386  bind = smpp_pdu_create(bind_transceiver,
1388  bind->u.bind_transceiver.system_id = octstr_duplicate(smpp->username);
1389  bind->u.bind_transceiver.password = octstr_duplicate(smpp->password);
1390  if (smpp->system_type == NULL)
1391  bind->u.bind_transceiver.system_type = octstr_create("VMA");
1392  else
1393  bind->u.bind_transceiver.system_type = octstr_duplicate(smpp->system_type);
1394  bind->u.bind_transceiver.interface_version = smpp->version;
1395  bind->u.bind_transceiver.address_range = octstr_duplicate(smpp->address_range);
1396  bind->u.bind_transceiver.addr_ton = smpp->bind_addr_ton;
1397  bind->u.bind_transceiver.addr_npi = smpp->bind_addr_npi;
1398  if (send_pdu(conn, smpp, bind) == -1) {
1399  error(0, "SMPP[%s]: Couldn't send bind_transceiver to server.",
1400  octstr_get_cstr(smpp->conn->id));
1401  conn_destroy(conn);
1402  conn = NULL;
1403  }
1404  smpp_pdu_destroy(bind);
1405 
1406  return conn;
1407 }
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:490
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1236
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:187
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:621
#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:542
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
union SMPP_PDU::@14 u
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 1311 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().

1312 {
1313  SMPP_PDU *bind;
1314  Connection *conn;
1315 
1316 #ifdef HAVE_LIBSSL
1317  if (smpp->use_ssl)
1318  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1319  else
1320 #endif
1321 
1322  if (smpp->our_port > 0)
1323  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1324  else
1325  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1326 
1327  if (conn == NULL) {
1328  error(0, "SMPP[%s]: Couldn't connect to server.",
1329  octstr_get_cstr(smpp->conn->id));
1330  return NULL;
1331  }
1332 
1333  bind = smpp_pdu_create(bind_transmitter,
1335  bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username);
1336  bind->u.bind_transmitter.password = octstr_duplicate(smpp->password);
1337  if (smpp->system_type == NULL)
1338  bind->u.bind_transmitter.system_type = octstr_create("VMA");
1339  else
1340  bind->u.bind_transmitter.system_type =
1342  bind->u.bind_transmitter.interface_version = smpp->version;
1343  bind->u.bind_transmitter.address_range =
1345  bind->u.bind_transmitter.addr_ton = smpp->bind_addr_ton;
1346  bind->u.bind_transmitter.addr_npi = smpp->bind_addr_npi;
1347  if (send_pdu(conn, smpp, bind) == -1) {
1348  error(0, "SMPP[%s]: Couldn't send bind_transmitter to server.",
1349  octstr_get_cstr(smpp->conn->id));
1350  conn_destroy(conn);
1351  conn = NULL;
1352  }
1353  smpp_pdu_destroy(bind);
1354 
1355  return conn;
1356 }
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:490
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1236
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:187
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:621
#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:542
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * system_type
Definition: smsc_smpp.c:152
Octstr * address_range
Definition: smsc_smpp.c:155
Octstr * host
Definition: smsc_smpp.c:151
union SMPP_PDU::@14 u
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 589 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(), smpp_msg::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().

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

2534 {
2535  SMPP *smpp;
2536 
2537  smpp = conn->data;
2538  conn->load = (smpp ? (conn->status != SMSCCONN_DEAD ?
2539  gw_prioqueue_len(smpp->msgs_to_send) : 0) : 0);
2540  return conn->load;
2541 }
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:147
void * data
Definition: smscconn_p.h:249
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 326 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().

327 {
328  Octstr *os;
329 
330  if (*len == 0) {
331  *len = smpp_pdu_read_len(conn);
332  if (*len == -1) {
333  error(0, "SMPP[%s]: Server sent garbage, ignored.",
334  octstr_get_cstr(smpp->conn->id));
335  return -2;
336  } else if (*len == 0) {
337  if (conn_eof(conn) || conn_error(conn))
338  return -1;
339  return 0;
340  }
341  }
342 
343  os = smpp_pdu_read_data(conn, *len);
344  if (os == NULL) {
345  if (conn_eof(conn) || conn_error(conn))
346  return -1;
347  return 0;
348  }
349  *len = 0;
350 
351  *pdu = smpp_pdu_unpack(smpp->conn->id, os);
352  if (*pdu == NULL) {
353  error(0, "SMPP[%s]: PDU unpacking failed.",
354  octstr_get_cstr(smpp->conn->id));
355  debug("bb.sms.smpp", 0, "SMPP[%s]: Failed PDU follows.",
356  octstr_get_cstr(smpp->conn->id));
357  octstr_dump(os, 0);
358  octstr_destroy(os);
359  return -2;
360  }
361 
362  octstr_destroy(os);
363  return 1;
364 }
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:187
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:869
int conn_eof(Connection *conn)
Definition: conn.c:699
#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:322
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:710

◆ send_enquire_link()

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

Definition at line 1173 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().

1174 {
1175  SMPP_PDU *pdu;
1176  Octstr *os;
1177  int ret;
1178 
1179  if (difftime(date_universal_now(),*last_sent) < smpp->enquire_link_interval)
1180  return 0;
1181  *last_sent = date_universal_now();
1182 
1183  pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));
1184  dump_pdu("Sending enquire link:", smpp->conn->id, pdu, smpp->log_format);
1185  os = smpp_pdu_pack(smpp->conn->id, pdu);
1186  if (os != NULL)
1187  ret = conn_write(conn, os); /* Write errors checked by caller. */
1188  else
1189  ret = -1;
1190  octstr_destroy(os);
1191  smpp_pdu_destroy(pdu);
1192 
1193  return ret;
1194 }
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:187
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1045
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long log_format
Definition: smsc_smpp.c:185
long date_universal_now(void)
Definition: date.c:304
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 1196 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().

1197 {
1198  SMPP_PDU *pdu;
1199  Octstr *os;
1200  int ret;
1201 
1202  pdu = smpp_pdu_create(generic_nack, seq_num);
1203  pdu->u.generic_nack.command_status = reason;
1204  dump_pdu("Sending generic_nack:", smpp->conn->id, pdu, smpp->log_format);
1205  os = smpp_pdu_pack(smpp->conn->id, pdu);
1206  if (os != NULL)
1207  ret = conn_write(conn, os);
1208  else
1209  ret = -1;
1210  octstr_destroy(os);
1211  smpp_pdu_destroy(pdu);
1212 
1213  return ret;
1214 }
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:187
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1045
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long log_format
Definition: smsc_smpp.c:185
Definition: octstr.c:118
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:104
union SMPP_PDU::@14 u
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 1255 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, smpp_msg::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().

1256 {
1257  Msg *msg;
1258  SMPP_PDU *pdu;
1259  Octstr *os;
1260 
1261  if (*pending_submits == -1)
1262  return 0;
1263 
1264  while (*pending_submits < smpp->max_pending_submits) {
1265  /* check our throughput */
1266  if (smpp->conn->throughput > 0 && load_get(smpp->load, 0) >= smpp->conn->throughput) {
1267  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput limit exceeded (%.02f,%.02f)",
1268  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1269  break;
1270  }
1271  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput (%.02f,%.02f)",
1272  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1273 
1274  /* Get next message, quit if none to be sent */
1275  msg = gw_prioqueue_remove(smpp->msgs_to_send);
1276  if (msg == NULL)
1277  break;
1278 
1279  /* Send PDU, record it as waiting for ack from SMS center */
1280  pdu = msg_to_pdu(smpp, msg);
1281  if (pdu == NULL) {
1283  continue;
1284  }
1285  /* check for write errors */
1286  if (send_pdu(conn, smpp, pdu) == 0) {
1287  struct smpp_msg *smpp_msg = smpp_msg_create(msg);
1288  os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
1289  dict_put(smpp->sent_msgs, os, smpp_msg);
1290  smpp_pdu_destroy(pdu);
1291  octstr_destroy(os);
1292  ++(*pending_submits);
1293  load_increase(smpp->load);
1294  }
1295  else { /* write error occurs */
1296  smpp_pdu_destroy(pdu);
1298  return -1;
1299  }
1300  }
1301 
1302  return 0;
1303 }
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:1236
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:187
static struct smpp_msg * smpp_msg_create(Msg *msg)
Definition: smsc_smpp.c:200
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:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
Load * load
Definition: smsc_smpp.c:186
#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:869
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
union SMPP_PDU::@14 u
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ send_msg_cb()

static int send_msg_cb ( SMSCConn conn,
Msg msg 
)
static

Definition at line 2544 of file smsc_smpp.c.

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

Referenced by smsc_smpp_create().

2545 {
2546  SMPP *smpp;
2547 
2548  smpp = conn->data;
2551  return 0;
2552 }
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:249
#define gw_prioqueue_produce(queue, item)
Definition: gw-prioqueue.h:98
void gwthread_wakeup(long thread)
long transmitter
Definition: smsc_smpp.c:145

◆ send_pdu()

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

Definition at line 1236 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().

1237 {
1238  Octstr *os;
1239  int ret;
1240 
1241  dump_pdu("Sending PDU:", smpp->conn->id, pdu, smpp->log_format);
1242  os = smpp_pdu_pack(smpp->conn->id, pdu);
1243  if (os) {
1244  /* Caller checks for write errors later */
1245  ret = conn_write(conn, os);
1246  /* it's not a error if we still have data buffered */
1247  ret = (ret == 1) ? 0 : ret;
1248  } else
1249  ret = -1;
1250  octstr_destroy(os);
1251  return ret;
1252 }
Octstr * id
Definition: smscconn_p.h:174
SMSCConn * conn
Definition: smsc_smpp.c:187
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1045
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long log_format
Definition: smsc_smpp.c:185
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 1216 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().

1217 {
1218  SMPP_PDU *pdu;
1219  Octstr *os;
1220  int ret;
1221 
1222  pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));
1223  dump_pdu("Sending unbind:", smpp->conn->id, pdu, smpp->log_format);
1224  os = smpp_pdu_pack(smpp->conn->id, pdu);
1225  if (os != NULL)
1226  ret = conn_write(conn, os);
1227  else
1228  ret = -1;
1229  octstr_destroy(os);
1230  smpp_pdu_destroy(pdu);
1231 
1232  return ret;
1233 }
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:187
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1045
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long log_format
Definition: smsc_smpp.c:185
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 2555 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().

2556 {
2557  SMPP *smpp;
2558 
2559  if (conn == NULL)
2560  return -1;
2561 
2562  debug("bb.smpp", 0, "Shutting down SMSCConn %s (%s)",
2563  octstr_get_cstr(conn->name),
2564  finish_sending ? "slow" : "instant");
2565 
2566  mutex_lock(conn->flow_mutex);
2567 
2569 
2570  smpp = conn->data;
2571  if (smpp == NULL) {
2572  mutex_unlock(conn->flow_mutex);
2573  return 0;
2574  }
2575 
2576  smpp->quitting = 1;
2577  if (smpp->transmitter != -1)
2579 
2580  if (smpp->receiver != -1)
2581  gwthread_wakeup(smpp->receiver);
2582 
2583  mutex_unlock(conn->flow_mutex);
2584 
2585  return 0;
2586 }
Octstr * name
Definition: smscconn_p.h:173
#define mutex_unlock(m)
Definition: thread.h:136
void * data
Definition: smscconn_p.h:249
#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 228 of file smsc_smpp.c.

References SMPP::address_range, SMPP::alt_addr_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, 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, 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, SMPP::username, SMPP::validityperiod, SMPP::version, SMPP::wait_ack, and SMPP::wait_ack_action.

Referenced by smsc_smpp_create().

240 {
241  SMPP *smpp;
242 
243  smpp = gw_malloc(sizeof(*smpp));
244  smpp->transmitter = -1;
245  smpp->receiver = -1;
247  smpp->sent_msgs = dict_create(max_pending_submits, NULL);
249  smpp->received_msgs = gwlist_create();
252  smpp->host = octstr_duplicate(host);
253  smpp->system_type = octstr_duplicate(system_type);
254  smpp->our_port = our_port;
255  smpp->our_receiver_port = our_receiver_port;
256  smpp->username = octstr_duplicate(username);
257  smpp->password = octstr_duplicate(password);
258  smpp->address_range = octstr_duplicate(address_range);
259  smpp->source_addr_ton = source_addr_ton;
260  smpp->source_addr_npi = source_addr_npi;
261  smpp->dest_addr_ton = dest_addr_ton;
262  smpp->dest_addr_npi = dest_addr_npi;
263  smpp->my_number = octstr_duplicate(my_number);
264  smpp->service_type = octstr_duplicate(service_type);
265  smpp->transmit_port = transmit_port;
266  smpp->receive_port = receive_port;
267  smpp->enquire_link_interval = enquire_link_interval;
268  smpp->max_pending_submits = max_pending_submits;
269  smpp->quitting = 0;
270  smpp->version = version;
271  smpp->priority = priority;
272  smpp->validityperiod = validity;
273  smpp->conn = conn;
274  smpp->throttling_err_time = 0;
275  smpp->smpp_msg_id_type = smpp_msg_id_type;
276  smpp->autodetect_addr = autodetect_addr;
277  smpp->alt_charset = octstr_duplicate(alt_charset);
278  smpp->alt_addr_charset = octstr_duplicate(alt_addr_charset);
279  smpp->connection_timeout = connection_timeout;
280  smpp->wait_ack = wait_ack;
281  smpp->wait_ack_action = wait_ack_action;
282  smpp->bind_addr_ton = 0;
283  smpp->bind_addr_npi = 0;
284  smpp->use_ssl = 0;
285  smpp->ssl_client_certkey_file = NULL;
286  smpp->load = load_create_real(0);
287  load_add_interval(smpp->load, 1);
288  smpp->esm_class = esm_class;
289 
290  return smpp;
291 }
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:187
int version
Definition: smsc_smpp.c:173
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
int use_ssl
Definition: smsc_smpp.c:168
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:186
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:182
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:183
#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
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:184
Octstr * password
Definition: smsc_smpp.c:154

◆ smpp_destroy()

static void smpp_destroy ( SMPP smpp)
static

Definition at line 294 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().

295 {
296  if (smpp != NULL) {
298  dict_destroy(smpp->sent_msgs);
301  octstr_destroy(smpp->host);
302  octstr_destroy(smpp->username);
303  octstr_destroy(smpp->password);
307  octstr_destroy(smpp->my_number);
311  load_destroy(smpp->load);
312  gw_free(smpp);
313  }
314 }
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:322
Load * load
Definition: smsc_smpp.c:186
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)
static

Definition at line 200 of file smsc_smpp.c.

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

Referenced by send_messages().

201 {
202  struct smpp_msg *result = gw_malloc(sizeof(struct smpp_msg));
203 
204  gw_assert(result != NULL);
205  result->sent_time = time(NULL);
206  result->msg = msg;
207 
208  return result;
209 }
gw_assert(wtls_machine->packet_to_send !=NULL)
time_t sent_time
Definition: smsc_smpp.c:192
Msg * msg
Definition: smsc_smpp.c:193
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 215 of file smsc_smpp.c.

References smpp_msg::msg, and msg_destroy().

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

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

◆ 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 2595 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, 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().

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