Kannel: Open Source WAP and SMS gateway  svn-r5335
opensmppbox.c File Reference
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <math.h>
#include "gwlib/gwlib.h"
#include "gw/msg.h"
#include "gw/shared.h"
#include "gw/bb.h"
#include "gw/smsc/smpp_pdu.h"
#include "gw/sms.h"
#include "gw/dlr.h"
#include "gw/heartbeat.h"
#include "gw/meta_data.h"
#include "gw/bb_store.h"
#include "../sb-config.h"
#include "opensmppbox-cfg.def"

Go to the source code of this file.

Data Structures

struct  _boxc
 

Macros

#define SMPP_DEAD   0
 
#define SMPP_SHUTDOWN   1
 
#define SMPP_RUNNING   2
 
#define TIMEOUT_SECONDS   300
 
#define DEBUG   1
 
#define dump_pdu(msg, id, pdu)
 
#define OCTSTR(name)
 
#define SINGLE_GROUP(name, fields)
 
#define MULTI_GROUP(name, fields)
 
#define OCTSTR(name)
 
#define SINGLE_GROUP(name, fields)
 
#define MULTI_GROUP(name, fields)
 

Typedefs

typedef struct _boxc Boxc
 

Enumerations

enum  smpp_login { SMPP_LOGIN_NOTLOGGEDIN, SMPP_LOGIN_TRANSMITTER, SMPP_LOGIN_RECEIVER, SMPP_LOGIN_TRANSCEIVER }
 

Functions

void smpp_pdu_destroy_item (void *pdu)
 
static Octstrboxc_route_msg_to_smsc (Boxc *box, Msg *msg)
 
int check_login (Boxc *boxc, Octstr *system_id, Octstr *password, Octstr *system_type, smpp_login login_type)
 
static int timestamp_to_minutes (Octstr *timestamp)
 
static int send_msg (Connection *conn, Boxc *boxconn, Msg *pmsg)
 
static void identify_to_bearerbox (Boxc *conn)
 
static Msgread_from_box (Connection *conn, Boxc *boxconn)
 
Msgcatenate_msg (List *list, int total)
 
static long convert_addr_from_pdu (Octstr *id, Octstr *addr, long ton, long npi)
 
static int send_pdu (Connection *conn, Octstr *id, SMPP_PDU *pdu)
 
static Octstrgenerate_smppid (Msg *msg, int version)
 
static int read_pdu (Boxc *box, Connection *conn, long *len, SMPP_PDU **pdu)
 
static Listmsg_to_pdu (Boxc *box, Msg *msg)
 
static Msgpdu_to_msg (Boxc *box, SMPP_PDU *pdu, long *reason)
 
static Msgdata_sm_to_msg (Boxc *box, SMPP_PDU *pdu, long *reason)
 
Octstrconcat_msgids (Octstr *msgid, List *list)
 
void check_multipart (Boxc *box, Msg *msg, int *msg_to_send, Msg **msg2, List **parts_list)
 
static void handle_pdu (Connection *conn, Boxc *box, SMPP_PDU *pdu)
 
static Boxcboxc_create (int fd, Octstr *ip, int ssl)
 
static void boxc_destroy (Boxc *boxc)
 
static Boxcaccept_smpp (int fd, int ssl)
 
static void smpp_to_bearerbox (void *arg)
 
static Boxcfind_receiver_box (Boxc *box)
 
static void bearerbox_to_smpp (void *arg)
 
static void run_smppbox (void *arg)
 
static void wait_for_connections (int fd, void(*function)(void *arg), List *waited)
 
static void smppboxc_run (void *arg)
 
static void signal_handler (int signum)
 
static void setup_signal_handlers (void)
 
static void gw_smpp_enter (Cfg *cfg)
 
static void gw_smpp_leave ()
 
static void init_smsc_routes (Cfg *cfg)
 
static void destroy_smsc_routes (void)
 
static void init_smppbox (Cfg *cfg)
 
static int check_args (int i, int argc, char **argv)
 
static int smppbox_is_allowed_in_group (Octstr *group, Octstr *variable)
 
static int smppbox_is_single_group (Octstr *query)
 
int main (int argc, char **argv)
 

Variables

static Cfgcfg
 
static volatile sig_atomic_t restart_smppbox = 0
 
static volatile sig_atomic_t smppbox_status
 
static long smppbox_port
 
static int smppbox_port_ssl = 0
 
static long bearerbox_port
 
static Octstrbearerbox_host
 
static int bearerbox_port_ssl = 0
 
static Octstrsmpp_logins
 
static Counterboxid
 
static int restart = 0
 
static Listall_boxes
 
static Dictlist_dict
 
static Countercatenated_sms_counter
 
static long sms_max_length = MAX_SMS_OCTETS
 
static long smpp_source_addr_ton = -1
 
static long smpp_source_addr_npi = -1
 
static int smpp_autodetect_addr = 0
 
static long smpp_dest_addr_ton = -1
 
static long smpp_dest_addr_npi = -1
 
static Dictsmsc_by_receiver = NULL
 
static Dictsmsc_by_smsbox_id = NULL
 
static Dictsmsc_by_sender = NULL
 
static Dictsmsc_by_sender_smsbox_id = NULL
 
static Octstrsmppbox_id
 
static Octstrour_system_id
 
static Octstrroute_to_smsc
 
static time_t smpp_timeout
 
static Octstralt_charset
 
static int systemidisboxcid
 
static int enablepam
 
static Octstrpamacl
 
static int disable_multipart_catenation
 

Macro Definition Documentation

◆ DEBUG

#define DEBUG   1

Definition at line 341 of file opensmppbox.c.

◆ dump_pdu

#define dump_pdu (   msg,
  id,
  pdu 
)
Value:
do { \
debug("opensmppbox", 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

This version does dump.

Definition at line 347 of file opensmppbox.c.

Referenced by handle_pdu(), and send_pdu().

◆ MULTI_GROUP [1/2]

#define MULTI_GROUP (   name,
  fields 
)
Value:
if (octstr_compare(octstr_imm(#name), group) == 0) { \
if (octstr_compare(groupstr, variable) == 0) \
return 1; \
fields \
return 0; \
}
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ MULTI_GROUP [2/2]

#define MULTI_GROUP (   name,
  fields 
)
Value:
if (octstr_compare(octstr_imm(#name), query) == 0) \
return 0;
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ OCTSTR [1/2]

#define OCTSTR (   name)
Value:
if (octstr_compare(octstr_imm(#name), variable) == 0) \
return 1;
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ OCTSTR [2/2]

#define OCTSTR (   name)

◆ SINGLE_GROUP [1/2]

#define SINGLE_GROUP (   name,
  fields 
)
Value:
if (octstr_compare(octstr_imm(#name), group) == 0) { \
if (octstr_compare(groupstr, variable) == 0) \
return 1; \
fields \
return 0; \
}
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ SINGLE_GROUP [2/2]

#define SINGLE_GROUP (   name,
  fields 
)
Value:
if (octstr_compare(octstr_imm(#name), query) == 0) \
return 1;
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ SMPP_DEAD

#define SMPP_DEAD   0

Definition at line 99 of file opensmppbox.c.

◆ SMPP_RUNNING

#define SMPP_RUNNING   2

◆ SMPP_SHUTDOWN

#define SMPP_SHUTDOWN   1

Definition at line 100 of file opensmppbox.c.

Referenced by signal_handler(), and wait_for_connections().

◆ TIMEOUT_SECONDS

#define TIMEOUT_SECONDS   300

Definition at line 137 of file opensmppbox.c.

Referenced by init_smppbox().

Typedef Documentation

◆ Boxc

typedef struct _boxc Boxc

Enumeration Type Documentation

◆ smpp_login

enum smpp_login
Enumerator
SMPP_LOGIN_NOTLOGGEDIN 
SMPP_LOGIN_TRANSMITTER 
SMPP_LOGIN_RECEIVER 
SMPP_LOGIN_TRANSCEIVER 

Definition at line 139 of file opensmppbox.c.

Function Documentation

◆ accept_smpp()

static Boxc* accept_smpp ( int  fd,
int  ssl 
)
static

Definition at line 1841 of file opensmppbox.c.

References boxc_create(), host_ip(), info(), octstr_destroy(), octstr_get_cstr, _boxc::smpp_connection, and ssl.

Referenced by run_smppbox().

1842 {
1843  Boxc *newconn;
1844  Octstr *ip;
1845 
1846  int newfd;
1847  struct sockaddr_in client_addr;
1848  socklen_t client_addr_len;
1849 
1850  client_addr_len = sizeof(client_addr);
1851 
1852  newfd = accept(fd, (struct sockaddr *)&client_addr, &client_addr_len);
1853  if (newfd < 0)
1854  return NULL;
1855 
1856  ip = host_ip(client_addr);
1857 
1858  newconn = boxc_create(newfd, ip, 0);
1859 
1860  /*
1861  * check if the SSL handshake was successfull, otherwise
1862  * this is no valid box connection any more
1863  */
1864 #ifdef HAVE_LIBSSL
1865  if (ssl && !conn_get_ssl(newconn->smpp_connection))
1866  return NULL;
1867 #endif
1868 
1869  info(0, "Client connected from <%s>", octstr_get_cstr(ip));
1870  octstr_destroy(ip);
1871 
1872  /* XXX TODO: do the hand-shake, baby, yeah-yeah! */
1873 
1874  return newconn;
1875 }
void info(int err, const char *fmt,...)
Definition: log.c:672
int ssl
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
Definition: opensmppbox.c:1729
Connection * smpp_connection
Definition: opensmppbox.c:142
Definition: octstr.c:118
Octstr * host_ip(struct sockaddr_in addr)
Definition: socket.c:615
int socklen_t
Definition: socket.h:73

◆ bearerbox_to_smpp()

static void bearerbox_to_smpp ( void *  arg)
static

Definition at line 1928 of file opensmppbox.c.

References ack_buffered, ack_failed, ack_failed_tmp, ack_success, _boxc::alive, _boxc::bearerbox_connection, _boxc::boxc_id, cmd_restart, cmd_shutdown, conn_eof(), DC_7BIT, DC_UCS2, debug(), _boxc::deliver_acks, dict_get(), dict_put(), error(), find_receiver_box(), gwlist_destroy(), gwlist_extract_first(), info(), _boxc::mo_recode, msg, _boxc::msg_acks, msg_create, msg_destroy(), msg_dump(), msg_to_pdu(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_imm(), octstr_len(), octstr_recode(), octstr_search(), read_from_box(), report_mo, restart, send_msg(), send_pdu(), _boxc::smpp_connection, SMPP_ESME_RMSGQFUL, SMPP_ESME_RSUBMITFAIL, smpp_pdu_destroy(), SMPP_RUNNING, smppbox_status, text, SMPP_PDU::type, SMPP_PDU::type_name, SMPP_PDU::u, uuid_copy(), UUID_STR_LEN, uuid_unparse(), and warning().

Referenced by run_smppbox().

1929 {
1930  Msg *msg, *mack;
1931  Boxc *box = arg;
1932  SMPP_PDU *pdu;
1933  List *pdulist;
1934  int dreport, errcode;
1935  Boxc *receiver_box;
1936  char id[UUID_STR_LEN + 1];
1937  Octstr *msgid;
1938 
1939  while (smppbox_status == SMPP_RUNNING && box->alive) {
1940 
1941  msg = read_from_box(box->bearerbox_connection, box);
1942  if (msg == NULL) {
1943  if ((!box->alive) || conn_eof(box->bearerbox_connection)) {
1944  /* tell opensmppbox to die */
1945  /* the client closes the connection, after that die in receiver */
1946  box->alive = 0;
1947  }
1948  continue;
1949  }
1950  if (msg_type(msg) == admin) {
1951  if (msg->admin.command == cmd_shutdown) {
1952  info(0, "Bearerbox told us to die");
1953  box->alive = 0;
1954  } else if (msg->admin.command == cmd_restart) {
1955  info(0, "Bearerbox told us to restart");
1956  restart = 1;
1957  box->alive = 0;
1958  }
1959  }
1960  if (msg_type(msg) == heartbeat) {
1961  // todo
1962  debug("opensmppbox", 0, "bearerbox_to_smpp: catch an heartbeat - we are alive");
1963  msg_destroy(msg);
1964  continue;
1965  }
1966  if (msg_type(msg) == ack) {
1967  uuid_unparse(msg->ack.id, id);
1968  msgid = octstr_create(id);
1969  pdu = dict_get(box->msg_acks, msgid);
1970  errcode = SMPP_ESME_RMSGQFUL; /* in case we get ack_failed_tmp */
1971  if (pdu) {
1972  switch (msg->ack.nack) {
1973  case ack_buffered:
1974  case ack_success:
1975  /* we can send the submit_sm_resp as-is */
1976  break;
1977  case ack_failed:
1978  errcode = SMPP_ESME_RSUBMITFAIL;
1979  /* no break */
1980  case ack_failed_tmp:
1981  switch (pdu->type) {
1982  case submit_sm_resp:
1983  octstr_destroy(pdu->u.submit_sm_resp.message_id);
1984  pdu->u.submit_sm_resp.message_id = NULL;
1985  pdu->u.submit_sm_resp.command_status = errcode;
1986  break;
1987  case data_sm_resp:
1988  octstr_destroy(pdu->u.data_sm_resp.message_id);
1989  pdu->u.data_sm_resp.message_id = NULL;
1990  pdu->u.data_sm_resp.command_status = errcode;
1991  break;
1992  default:
1993  debug("opensmppbox", 0, "Getting failure ack on unexpected pdu: %s.", pdu->type_name);
1994  break;
1995  }
1996  break;
1997  default:
1998  debug("opensmppbox", 0, "Unknown ack.nack type: %ld.", msg->ack.nack);
1999  break;
2000  }
2001  send_pdu(box->smpp_connection, box->boxc_id, pdu);
2002  dict_put(box->msg_acks, msgid, NULL); /* also destroys item */
2003  }
2004  else {
2005  debug("opensmppbox", 0, "Ack to unknown message: %s.", id);
2006  }
2007  octstr_destroy(msgid);
2008  }
2009  if (!box->alive) {
2010  msg_destroy(msg);
2011  break;
2012  }
2013  if (msg_type(msg) == sms) {
2014  info(0, "We received an SMS message.");
2015  if (msg->sms.sms_type == report_mo)
2016  dreport = 1;
2017  else
2018  dreport = 0;
2019  /* Recode to iso-8859-1 the MO message if possible */
2020  if (box->mo_recode && msg->sms.coding == DC_UCS2) {
2021  int converted = 0;
2022  Octstr *text;
2023 
2024  text = octstr_duplicate(msg->sms.msgdata);
2025  if(0 == octstr_recode (octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text)) {
2026  if(octstr_search(text, octstr_imm("&#"), 0) == -1) {
2027  /* XXX I'm trying to search for &#xxxx; text, which indicates that the
2028  * text couldn't be recoded.
2029  * We should use other function to do the recode or detect it using
2030  * other method */
2031  info(0, "MO message converted from UCS-2 to UTF-8");
2032  octstr_destroy(msg->sms.msgdata);
2033  msg->sms.msgdata = octstr_duplicate(text);
2034  msg->sms.charset = octstr_create("UTF-8");
2035  msg->sms.coding = DC_7BIT;
2036  converted=1;
2037  } else {
2039  text = octstr_duplicate(msg->sms.msgdata);
2040  }
2041  }
2042  if(!converted && 0 == octstr_recode (octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text)) {
2043  if(octstr_search(text, octstr_imm("&#"), 0) == -1) {
2044  /* XXX I'm trying to search for &#xxxx; text, which indicates that the
2045  * text couldn't be recoded.
2046  * We should use other function to do the recode or detect it using
2047  * other method */
2048  info(0, "MO message converted from UCS-2 to UTF-8");
2049  octstr_destroy(msg->sms.msgdata);
2050  msg->sms.msgdata = octstr_duplicate(text);
2051  msg->sms.charset = octstr_create("UTF-8");
2052  msg->sms.coding = DC_7BIT;
2053  /* redundant, but this code could be used if another convertion is required
2054  converted=1;
2055  } else {
2056  octstr_destroy(text);
2057  text = octstr_duplicate(msg->sms.msgdata);
2058  */
2059  }
2060  }
2062  }
2063  if (octstr_len(msg->sms.sender) == 0 ||
2064  octstr_len(msg->sms.receiver) == 0) {
2065  error(0, "smppbox_req_thread: no sender/receiver, dump follows:");
2066  msg_dump(msg, 0);
2067  /*
2068  * Send NACK to bearerbox, otherwise message remains in store file.
2069  */
2070  mack = msg_create(ack);
2071  mack->ack.nack = ack_failed;
2072  mack->ack.time = msg->sms.time;
2073  uuid_copy(mack->ack.id, msg->sms.id);
2074  send_msg(box->bearerbox_connection, box, mack);
2075 
2076  msg_destroy(msg);
2077  continue;
2078  }
2079  /* create ack message to be sent afterwards */
2080  mack = msg_create(ack);
2081  mack->ack.nack = ack_success;
2082  mack->ack.time = msg->sms.time;
2083  uuid_copy(mack->ack.id, msg->sms.id);
2084 
2085  msgid = NULL;
2086  receiver_box = find_receiver_box(box);
2087  pdulist = msg_to_pdu(receiver_box, msg);
2088  if (pdulist != NULL) {
2089  while ((pdu = gwlist_extract_first(pdulist)) != NULL) {
2090  if (NULL == msgid) {
2091  /* Put ack in dict. We will send it as soon as we received a deliver_sm_resp */
2092  msgid = octstr_format("%ld", pdu->u.deliver_sm.sequence_number);
2093  dict_put(receiver_box->deliver_acks, msgid, mack);
2094  }
2095  send_pdu(receiver_box->smpp_connection, box->boxc_id, pdu);
2096  smpp_pdu_destroy(pdu);
2097  }
2098  if (msgid)
2099  octstr_destroy(msgid);
2100  gwlist_destroy(pdulist, NULL);
2101  }
2102  else {
2103  /* Send NACK to bearerbox, otherwise message remains in store file. */
2104  warning(0, "msg_to_pdu failed, sending negative ack");
2105  mack->ack.nack = ack_failed;
2106  send_msg(box->bearerbox_connection, box, mack);
2107  }
2108  }
2109  msg_destroy(msg);
2110  }
2111 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
void error(int err, const char *fmt,...)
Definition: log.c:648
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
void info(int err, const char *fmt,...)
Definition: log.c:672
Dict * msg_acks
Definition: opensmppbox.c:163
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
Definition: msg.h:109
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
Definition: octstr.c:2576
static List * msg_to_pdu(Boxc *box, Msg *msg)
Definition: opensmppbox.c:698
const char * type_name
Definition: smpp_pdu.h:92
msg_type
Definition: msg.h:73
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
unsigned long type
Definition: smpp_pdu.h:91
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
#define msg_create(type)
Definition: msg.h:136
int conn_eof(Connection *conn)
Definition: conn.c:705
int mo_recode
Definition: opensmppbox.c:179
Dict * deliver_acks
Definition: opensmppbox.c:164
static Boxc * find_receiver_box(Boxc *box)
Definition: opensmppbox.c:1911
static int restart
Definition: opensmppbox.c:109
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
Definition: opensmppbox.c:453
Connection * bearerbox_connection
Definition: opensmppbox.c:143
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
Definition: opensmppbox.c:620
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
void * gwlist_extract_first(List *list)
Definition: list.c:305
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
char * text
Definition: smsc_cimd2.c:921
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void uuid_copy(uuid_t dst, const uuid_t src)
Definition: gw_uuid.c:150
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Connection * smpp_connection
Definition: opensmppbox.c:142
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static Msg * read_from_box(Connection *conn, Boxc *boxconn)
Definition: opensmppbox.c:499
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Definition: list.c:102
#define SMPP_RUNNING
Definition: opensmppbox.c:101
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DC_UCS2
Definition: sms.h:112
#define DC_7BIT
Definition: sms.h:110
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ boxc_create()

static Boxc* boxc_create ( int  fd,
Octstr ip,
int  ssl 
)
static

Definition at line 1729 of file opensmppbox.c.

References _boxc::alive, alt_charset, _boxc::alt_charset, _boxc::alt_dcs, _boxc::autodetect_addr, _boxc::boxc_id, boxid, _boxc::client_ip, conn_wrap_fd(), _boxc::connect_time, counter_create(), counter_increase(), _boxc::deliver_acks, _boxc::dest_addr_npi, _boxc::dest_addr_ton, dict_create(), _boxc::id, _boxc::is_wap, _boxc::load, _boxc::logged_in, _boxc::mo_recode, _boxc::msg_acks, msg_destroy_item(), octstr_duplicate, _boxc::priority, _boxc::routable, route_to_smsc, _boxc::route_to_smsc, _boxc::service_type, smpp_autodetect_addr, _boxc::smpp_connection, smpp_dest_addr_npi, smpp_dest_addr_ton, _boxc::smpp_pdu_counter, smpp_pdu_destroy_item(), smpp_source_addr_npi, smpp_source_addr_ton, _boxc::sms_service, _boxc::source_addr_npi, _boxc::source_addr_ton, ssl, _boxc::validityperiod, and _boxc::version.

Referenced by accept_smpp().

1730 {
1731  Boxc *boxc;
1732 
1733  boxc = gw_malloc(sizeof(Boxc));
1734  boxc->logged_in = 0;
1735  boxc->is_wap = 0;
1736  boxc->load = 0;
1737  boxc->smpp_connection = conn_wrap_fd(fd, ssl);
1738  boxc->id = counter_increase(boxid);
1739  boxc->client_ip = octstr_duplicate(ip);
1740  boxc->alive = 1;
1741  boxc->connect_time = time(NULL);
1742  boxc->boxc_id = NULL;
1743  boxc->routable = 0;
1744  boxc->smpp_pdu_counter = counter_create();
1745  boxc->alt_charset = NULL;
1746  if (NULL != alt_charset) boxc->alt_charset = octstr_duplicate(alt_charset); /* todo: make this configurable on a per-esme basis */
1747  boxc->version = 0x33; /* default value, set upon receiving a bind */
1751 
1752  boxc->service_type = NULL;
1753 
1759 
1760  boxc->alt_dcs = 0;
1761  boxc->validityperiod = -1;
1762  boxc->priority = 0;
1763  boxc->mo_recode = 0;
1764  boxc->sms_service = NULL;
1765 
1766  return boxc;
1767 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static Octstr * route_to_smsc
Definition: opensmppbox.c:127
int autodetect_addr
Definition: opensmppbox.c:173
Dict * msg_acks
Definition: opensmppbox.c:163
Octstr * route_to_smsc
Definition: opensmppbox.c:162
static long smpp_dest_addr_npi
Definition: opensmppbox.c:118
int ssl
void smpp_pdu_destroy_item(void *pdu)
Definition: opensmppbox.c:184
Octstr * client_ip
Definition: opensmppbox.c:153
long source_addr_ton
Definition: opensmppbox.c:171
static long smpp_source_addr_ton
Definition: opensmppbox.c:114
int load
Definition: opensmppbox.c:148
long source_addr_npi
Definition: opensmppbox.c:172
Octstr * service_type
Definition: opensmppbox.c:170
int mo_recode
Definition: opensmppbox.c:179
int version
Definition: opensmppbox.c:149
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Dict * deliver_acks
Definition: opensmppbox.c:164
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
int alt_dcs
Definition: opensmppbox.c:176
Counter * smpp_pdu_counter
Definition: opensmppbox.c:152
void msg_destroy_item(void *msg)
Definition: msg.c:147
Octstr * boxc_id
Definition: opensmppbox.c:160
Counter * counter_create(void)
Definition: counter.c:94
Octstr * alt_charset
Definition: opensmppbox.c:150
static long smpp_dest_addr_ton
Definition: opensmppbox.c:117
static long smpp_source_addr_npi
Definition: opensmppbox.c:115
#define octstr_duplicate(ostr)
Definition: octstr.h:187
time_t connect_time
Definition: opensmppbox.c:151
static Counter * boxid
Definition: opensmppbox.c:108
int validityperiod
Definition: opensmppbox.c:177
Connection * smpp_connection
Definition: opensmppbox.c:142
int priority
Definition: opensmppbox.c:178
Octstr * sms_service
Definition: opensmppbox.c:161
long id
Definition: opensmppbox.c:147
int is_wap
Definition: opensmppbox.c:146
long dest_addr_ton
Definition: opensmppbox.c:174
volatile int routable
Definition: opensmppbox.c:167
static Octstr * alt_charset
Definition: opensmppbox.c:129
int logged_in
Definition: opensmppbox.c:145
static int smpp_autodetect_addr
Definition: opensmppbox.c:116
long dest_addr_npi
Definition: opensmppbox.c:175
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ boxc_destroy()

static void boxc_destroy ( Boxc boxc)
static

Definition at line 1769 of file opensmppbox.c.

References _boxc::alt_charset, _boxc::bearerbox_connection, _boxc::boxc_id, _boxc::client_ip, conn_destroy(), counter_destroy(), _boxc::deliver_acks, dict_destroy(), _boxc::msg_acks, octstr_destroy(), _boxc::route_to_smsc, _boxc::smpp_connection, _boxc::smpp_pdu_counter, and _boxc::sms_service.

Referenced by run_smppbox().

1770 {
1771  if (boxc == NULL)
1772  return;
1773 
1774  /* do nothing to the lists, as they are only references */
1775 
1776  if (boxc->smpp_connection)
1778  if (boxc->bearerbox_connection)
1780  if (boxc->boxc_id)
1781  octstr_destroy(boxc->boxc_id);
1782  if (boxc->alt_charset)
1783  octstr_destroy(boxc->alt_charset);
1785  if (boxc->route_to_smsc) {
1787  }
1788  if (boxc->client_ip)
1789  octstr_destroy(boxc->client_ip);
1790  if (boxc->alt_charset) {
1791  octstr_destroy(boxc->alt_charset);
1792  }
1793  dict_destroy(boxc->msg_acks);
1794  dict_destroy(boxc->deliver_acks);
1795  if (boxc->sms_service)
1796  octstr_destroy(boxc->sms_service);
1797  gw_free(boxc);
1798 }
Dict * msg_acks
Definition: opensmppbox.c:163
Octstr * route_to_smsc
Definition: opensmppbox.c:162
void counter_destroy(Counter *counter)
Definition: counter.c:110
Octstr * client_ip
Definition: opensmppbox.c:153
Dict * deliver_acks
Definition: opensmppbox.c:164
Connection * bearerbox_connection
Definition: opensmppbox.c:143
Counter * smpp_pdu_counter
Definition: opensmppbox.c:152
Octstr * boxc_id
Definition: opensmppbox.c:160
Octstr * alt_charset
Definition: opensmppbox.c:150
void conn_destroy(Connection *conn)
Definition: conn.c:627
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Connection * smpp_connection
Definition: opensmppbox.c:142
void dict_destroy(Dict *dict)
Definition: dict.c:215
Octstr * sms_service
Definition: opensmppbox.c:161

◆ boxc_route_msg_to_smsc()

static Octstr * boxc_route_msg_to_smsc ( Boxc box,
Msg msg 
)
static

Definition at line 1800 of file opensmppbox.c.

References _boxc::boxc_id, debug(), dict_get(), msg, octstr_destroy(), octstr_format(), octstr_get_cstr, _boxc::route_to_smsc, smsc_by_receiver, smsc_by_sender, smsc_by_sender_smsbox_id, smsc_by_smsbox_id, and smsc_id.

Referenced by check_multipart(), and handle_pdu().

1801 {
1802  Octstr *os = NULL, *smsc_id;
1803 
1804  if (msg->sms.smsc_id != NULL)
1805  return msg->sms.smsc_id;
1806 
1807  char *receiver = octstr_get_cstr(msg->sms.receiver);
1808  if ( (receiver) && (strlen(receiver) > 0) ) {
1809  smsc_id = dict_get(smsc_by_receiver, msg->sms.receiver);
1810  }
1811  else {
1812  receiver = "";
1813  }
1814 
1815  if (!smsc_id) {
1816  os = octstr_format("%s:%s", octstr_get_cstr(msg->sms.sender),
1817  octstr_get_cstr(box->boxc_id));
1819  octstr_destroy(os);
1820  };
1821  if (!smsc_id)
1822  smsc_id = dict_get(smsc_by_sender, msg->sms.sender);
1823  if (!smsc_id)
1825  if (!smsc_id)
1826  smsc_id = box->route_to_smsc;
1827 
1828  if (smsc_id)
1829  debug("opensmppbox", 0, "routed msg '%s' to smsc '%s'",
1831 
1832  return smsc_id;
1833 }
Octstr * route_to_smsc
Definition: opensmppbox.c:162
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * boxc_id
Definition: opensmppbox.c:160
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
static Octstr * smsc_id
Definition: mtbatch.c:98
static Dict * smsc_by_smsbox_id
Definition: opensmppbox.c:121
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static Dict * smsc_by_receiver
Definition: opensmppbox.c:120
static Dict * smsc_by_sender
Definition: opensmppbox.c:122
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static Dict * smsc_by_sender_smsbox_id
Definition: opensmppbox.c:123

◆ catenate_msg()

Msg* catenate_msg ( List list,
int  total 
)

Definition at line 524 of file opensmppbox.c.

References debug(), gwlist_get(), msg_destroy(), msg_duplicate(), octstr_append(), octstr_delete(), octstr_destroy(), octstr_get_char(), octstr_len(), and uuid_generate().

Referenced by check_multipart().

525 {
526  int current = 1, partno = 1, thismsg, max = 0;
527  Msg *current_msg;
528  Msg *ret = msg_duplicate(gwlist_get(list, 0));
529  uuid_generate(ret->sms.id);
530 
531  octstr_destroy(ret->sms.udhdata);
532  ret->sms.udhdata = NULL;
533  octstr_delete(ret->sms.msgdata, 0, octstr_len(ret->sms.msgdata));
534  while (max < total) {
535  current_msg = gwlist_get(list, current - 1);
536  if (current_msg) {
537  thismsg = octstr_get_char(current_msg->sms.udhdata, 5);
538  if (thismsg == partno) {
539  octstr_append(ret->sms.msgdata, current_msg->sms.msgdata);
540  max = 0;
541  if (++partno > total) {
542  return ret;
543  }
544  }
545  }
546  if (current >= total) {
547  current = 0;
548  }
549  current++;
550  max++;
551  }
552  /* fail */
553  debug("opensmppbox", 0, "re-assembling message failed.");
554  msg_destroy(ret);
555  return NULL;
556 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void uuid_generate(uuid_t out)
Definition: gw_uuid.c:393
Definition: msg.h:79
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void msg_destroy(Msg *msg)
Definition: msg.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ check_args()

static int check_args ( int  i,
int  argc,
char **  argv 
)
static

Definition at line 2560 of file opensmppbox.c.

Referenced by main().

2560  {
2561  if (strcmp(argv[i], "-H")==0 || strcmp(argv[i], "--tryhttp")==0) {
2562  //only_try_http = 1;
2563  } else
2564  return -1;
2565 
2566  return 0;
2567 }

◆ check_login()

int check_login ( Boxc boxc,
Octstr system_id,
Octstr password,
Octstr system_type,
smpp_login  login_type 
)

Definition at line 278 of file opensmppbox.c.

References _boxc::alive, all_boxes, _boxc::bearerbox_connection, _boxc::boxc_id, _boxc::client_ip, debug(), enablepam, gwlist_get(), gwlist_len(), info(), is_allowed_ip(), _boxc::login_type, octstr_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), pamacl, password, _boxc::smpp_connection, SMPP_LOGIN_TRANSCEIVER, smpp_logins, and systemidisboxcid.

Referenced by handle_pdu().

278  {
279  int box;
280  int success;
281  Boxc *thisbox;
282  FILE *fp;
283  char systemid[255], passw[255], systemtype[255], allowed_ips[1024];
284  Octstr *allowed_ips_str;
285 
286  fp = fopen(octstr_get_cstr(smpp_logins), "r");
287  if (fp == NULL) {
288  return 0;
289  }
290  while (!feof(fp)) {
291  fscanf(fp, "%s %s %s %s\n", systemid, passw, systemtype, allowed_ips);
292  if (systemidisboxcid) {
293  success = (strcmp(octstr_get_cstr(system_id), systemid) == 0 && strcmp(octstr_get_cstr(password), passw) == 0);
294  }
295  else {
296  success = (strcmp(octstr_get_cstr(system_id), systemid) == 0 && strcmp(octstr_get_cstr(password), passw) == 0 && strcmp(octstr_get_cstr(system_type), systemtype) == 0);
297  }
298  if (success) {
299  if (strcmp(allowed_ips, "") != 0) {
300  allowed_ips_str = octstr_create(allowed_ips);
301  if (is_allowed_ip(allowed_ips_str, octstr_imm("*.*.*.*"), boxc->client_ip) == 0) {
302  info(0, "Box connection tried from denied host <%s>, disconnected", octstr_get_cstr(boxc->client_ip));
303  octstr_destroy(allowed_ips_str);
304  continue;
305  }
306  octstr_destroy(allowed_ips_str);
307  }
308  fclose(fp);
309  goto valid_login;
310  }
311  }
312  fclose(fp);
313 #ifdef HAVE_PAM
314  if (enablepam && authenticate(octstr_get_cstr(pamacl), octstr_get_cstr(system_id), octstr_get_cstr(password))) {
315  goto valid_login;
316  }
317 #endif
318  return 0;
319 valid_login:
320  for (box = 0; box < gwlist_len(all_boxes); box++) {
321  thisbox = (Boxc *)gwlist_get(all_boxes, box);
322  if (octstr_compare(system_type, thisbox->boxc_id) == 0 && (thisbox->login_type == SMPP_LOGIN_TRANSCEIVER || (thisbox->login_type == login_type))) {
323  debug("bb.sms.smpp", 0, "opensmppbox[%s]: Multiple login: disconnect.",
324  octstr_get_cstr(thisbox->boxc_id));
325  thisbox->alive = 0;
326 #ifdef HAVE_SHUTDOWN_CONNECTION
327  shutdown_connection(thisbox->bearerbox_connection);
328  shutdown_connection(thisbox->smpp_connection);
329 #endif
330  }
331  }
332  return 1;
333 }
void info(int err, const char *fmt,...)
Definition: log.c:672
static List * all_boxes
Definition: opensmppbox.c:110
Octstr * client_ip
Definition: opensmppbox.c:153
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * pamacl
Definition: opensmppbox.c:133
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Definition: utils.c:815
Connection * bearerbox_connection
Definition: opensmppbox.c:143
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
unsigned char * password
Definition: test_cimd2.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
static int enablepam
Definition: opensmppbox.c:132
Octstr * boxc_id
Definition: opensmppbox.c:160
static int systemidisboxcid
Definition: opensmppbox.c:131
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Connection * smpp_connection
Definition: opensmppbox.c:142
static Octstr * smpp_logins
Definition: opensmppbox.c:107
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
smpp_login login_type
Definition: opensmppbox.c:144
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ check_multipart()

void check_multipart ( Boxc box,
Msg msg,
int *  msg_to_send,
Msg **  msg2,
List **  parts_list 
)

Definition at line 1464 of file opensmppbox.c.

References _boxc::boxc_id, boxc_route_msg_to_smsc(), catenate_msg(), debug(), dict_get(), dict_put(), disable_multipart_catenation, gwlist_append(), gwlist_create, gwlist_len(), list_dict, msg, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_char(), octstr_len(), and smsc_id.

Referenced by handle_pdu().

1465 {
1466  int reference, total;
1467  Octstr *key;
1468 
1469  if (!disable_multipart_catenation && msg->sms.udhdata && octstr_len(msg->sms.udhdata) == 6 && octstr_get_char(msg->sms.udhdata, 1) == 0) {
1470  /* We collect long messages as one and send them to bearerbox as a whole, so they can be sent
1471  from the same smsc. */
1472  (*msg_to_send) = 0;
1473  debug("opensmppbox", 0, "assemble multi-part message.");
1474  reference = octstr_get_char(msg->sms.udhdata, 3);
1475  total = octstr_get_char(msg->sms.udhdata, 4);
1476  key = octstr_format("%S-%i", msg->sms.receiver, reference);
1477  (*parts_list) = dict_get(list_dict, key);
1478  if (NULL == (*parts_list)) {
1479  (*parts_list) = gwlist_create();
1480  dict_put(list_dict, key, (*parts_list));
1481  }
1482  debug("opensmppbox", 0, "received %ld of %d.", gwlist_len((*parts_list)) + 1, total);
1483  if ((gwlist_len((*parts_list)) + 1) == total) {
1484  debug("opensmppbox", 0, "received all parts of multi-part message.");
1485  gwlist_append((*parts_list), msg);
1486  /* assemble message */
1487  (*msg2) = catenate_msg((*parts_list), total);
1488  dict_put(list_dict, key, NULL);
1489  octstr_destroy(key);
1490  if (NULL == (*msg2)) {
1491  /* we could not assemble an appropiate message */
1492  debug("opensmppbox", 0, "Invalid multi-part message.");
1493 
1494  }
1495  else {
1496  Octstr *smsc_id = boxc_route_msg_to_smsc(box, *msg2);
1497  (*msg2)->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1498  (*msg2)->sms.boxc_id = octstr_duplicate(box->boxc_id);
1499  debug("opensmppbox", 0, "multi-part message, length: %ld.", octstr_len((*msg2)->sms.msgdata));
1500  (*msg_to_send) = 1;
1501  }
1502  }
1503  else {
1504  gwlist_append((*parts_list), msg);
1505  octstr_destroy(key);
1506  }
1507  }
1508 }
static Octstr * boxc_route_msg_to_smsc(Boxc *box, Msg *msg)
Definition: opensmppbox.c:1800
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
static Dict * list_dict
Definition: opensmppbox.c:111
static int disable_multipart_catenation
Definition: opensmppbox.c:134
Octstr * boxc_id
Definition: opensmppbox.c:160
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Msg * catenate_msg(List *list, int total)
Definition: opensmppbox.c:524
#define gwlist_create()
Definition: list.h:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ concat_msgids()

Octstr* concat_msgids ( Octstr msgid,
List list 
)

Definition at line 1450 of file opensmppbox.c.

References gwlist_get(), gwlist_len(), msg, octstr_append(), octstr_duplicate, and octstr_imm().

Referenced by handle_pdu().

1451 {
1452  Octstr *ret = octstr_duplicate(msgid);
1453  int i;
1454  Msg *msg;
1455 
1456  for (i = 0; i < gwlist_len(list); i++) {
1457  msg = gwlist_get(list, i);
1458  octstr_append(ret, octstr_imm(";"));
1459  octstr_append(ret, msg->sms.dlr_url);
1460  }
1461  return ret;
1462 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Definition: octstr.c:118
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ convert_addr_from_pdu()

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

Definition at line 558 of file opensmppbox.c.

References 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(), SMPP_ESME_RINVSRCADR, and SMPP_ESME_ROK.

Referenced by data_sm_to_msg(), and pdu_to_msg().

559 {
560  long reason = SMPP_ESME_ROK;
561 
562  if (addr == NULL)
563  return reason;
564 
565  switch(ton) {
567  /*
568  * Checks to perform:
569  * 1) assume international number has at least 7 chars
570  * 2) the whole source addr consist of digits, exception '+' in front
571  */
572  if (octstr_len(addr) < 7) {
573  error(0, "SMPP[%s]: Mallformed addr `%s', expected at least 7 digits. ",
574  octstr_get_cstr(id),
575  octstr_get_cstr(addr));
576  reason = SMPP_ESME_RINVSRCADR;
577  goto error;
578  } else if (octstr_get_char(addr, 0) == '+' &&
579  !octstr_check_range(addr, 1, 256, gw_isdigit)) {
580  error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
581  octstr_get_cstr(id),
582  octstr_get_cstr(addr));
583  reason = SMPP_ESME_RINVSRCADR;
584  goto error;
585  } else if (octstr_get_char(addr, 0) != '+' &&
586  !octstr_check_range(addr, 0, 256, gw_isdigit)) {
587  error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
588  octstr_get_cstr(id),
589  octstr_get_cstr(addr));
590  reason = SMPP_ESME_RINVSRCADR;
591  goto error;
592  }
593  /* check if we received leading '00', then remove it*/
594  if (octstr_search(addr, octstr_imm("00"), 0) == 0)
595  octstr_delete(addr, 0, 2);
596 
597  /* international, insert '+' if not already here */
598  if (octstr_get_char(addr, 0) != '+')
599  octstr_insert_char(addr, 0, '+');
600 
601  break;
603  if (octstr_len(addr) > 11) {
604  /* alphanum sender, max. allowed length is 11 (according to GSM specs) */
605  error(0, "SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ",
606  octstr_get_cstr(id),
607  octstr_get_cstr(addr));
608  reason = SMPP_ESME_RINVSRCADR;
609  goto error;
610  }
611  break;
612  default: /* otherwise don't touch addr, user should handle it */
613  break;
614  }
615 
616 error:
617  return reason;
618 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1481
int gw_isdigit(int c)
Definition: utils.c:988
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define GSM_ADDR_TON_ALPHANUMERIC
Definition: smasi_pdu.h:107
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ data_sm_to_msg()

static Msg* data_sm_to_msg ( Boxc box,
SMPP_PDU pdu,
long *  reason 
)
static

Definition at line 1302 of file opensmppbox.c.

References _boxc::alt_charset, _boxc::boxc_id, charset_convert(), charset_gsm_to_utf8(), convert_addr_from_pdu(), DC_7BIT, DC_8BIT, DC_UCS2, DC_UNDEF, dcs_to_fields(), debug(), error(), ESM_CLASS_SUBMIT_RPI, ESM_CLASS_SUBMIT_UDH_INDICATOR, gw_assert(), meta_data_set_values(), msg, msg_create, msg_destroy(), mt_push, octstr_copy, octstr_create, octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_len(), SMPP_ESME_RINVDSTADR, SMPP_ESME_RINVESMCLASS, SMPP_ESME_ROK, SMPP_PDU::type, SMPP_PDU::u, and _boxc::version.

Referenced by handle_pdu().

1303 {
1304  Msg *msg;
1305  int ton, npi;
1306 
1307  gw_assert(pdu->type == data_sm);
1308 
1309  msg = msg_create(sms);
1310  gw_assert(msg != NULL);
1311  msg->sms.sms_type = mt_push;
1312  *reason = SMPP_ESME_ROK;
1313 
1314  /*
1315  * Reset source addr to have a prefixed '+' in case we have an
1316  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
1317  * between national and international numbers.
1318  */
1319  ton = pdu->u.data_sm.source_addr_ton;
1320  npi = pdu->u.data_sm.source_addr_npi;
1321  /* check source addr */
1322  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.data_sm.source_addr, ton, npi)) != SMPP_ESME_ROK)
1323  goto error;
1324  msg->sms.sender = pdu->u.data_sm.source_addr;
1325  pdu->u.data_sm.source_addr = NULL;
1326 
1327  /*
1328  * Follows SMPP spec. v3.4. issue 1.2
1329  * it's not allowed to have destination_addr NULL
1330  */
1331  if (pdu->u.data_sm.destination_addr == NULL) {
1332  error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
1333  "Discarding MO message.", octstr_get_cstr(box->boxc_id),
1334  octstr_get_cstr(pdu->u.data_sm.destination_addr));
1335  *reason = SMPP_ESME_RINVDSTADR;
1336  goto error;
1337  }
1338 
1339  /* Same reset of destination number as for source */
1340  ton = pdu->u.data_sm.dest_addr_ton;
1341  npi = pdu->u.data_sm.dest_addr_npi;
1342  /* check destination addr */
1343  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.data_sm.destination_addr, ton, npi)) != SMPP_ESME_ROK)
1344  goto error;
1345  msg->sms.receiver = pdu->u.data_sm.destination_addr;
1346  pdu->u.data_sm.destination_addr = NULL;
1347 
1348  /* SMSCs use service_type for billing information */
1349  msg->sms.binfo = pdu->u.data_sm.service_type;
1350  pdu->u.data_sm.service_type = NULL;
1351 
1352  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
1353  msg->sms.rpi = 1;
1354 
1355  msg->sms.msgdata = pdu->u.data_sm.message_payload;
1356  pdu->u.data_sm.message_payload = NULL;
1357 
1358  /*
1359  * Encode udh if udhi set
1360  * for reference see GSM03.40, section 9.2.3.24
1361  */
1362  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
1363  int udhl;
1364  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
1365  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
1366  octstr_get_cstr(box->boxc_id), udhl);
1367  if (udhl > octstr_len(msg->sms.msgdata)) {
1368  error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
1369  "0x%03lx. Discarding MO message.", octstr_get_cstr(box->boxc_id),
1370  udhl, octstr_len(msg->sms.msgdata));
1371  *reason = SMPP_ESME_RINVESMCLASS;
1372  goto error;
1373  }
1374  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
1375  octstr_delete(msg->sms.msgdata, 0, udhl);
1376  }
1377 
1378  dcs_to_fields(&msg, pdu->u.data_sm.data_coding);
1379 
1380  /* handle default data coding */
1381  switch (pdu->u.data_sm.data_coding) {
1382  case 0x00: /* default SMSC alphabet */
1383  /*
1384  * try to convert from something interesting if specified so
1385  * unless it was specified binary, ie. UDH indicator was detected
1386  */
1387  if (box->alt_charset && msg->sms.coding != DC_8BIT) {
1388  if (charset_convert(msg->sms.msgdata, "UTF-8", octstr_get_cstr(box->alt_charset)) != 0)
1389  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1390  "UTF-8", octstr_get_cstr(box->alt_charset));
1391  msg->sms.coding = DC_7BIT;
1392  } else { /* assume GSM 03.38 7-bit alphabet */
1393  charset_gsm_to_utf8(msg->sms.msgdata);
1394  msg->sms.coding = DC_7BIT;
1395  }
1396  break;
1397  case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
1398  case 0x03: /* ISO-8859-1 - do nothing */
1399  msg->sms.coding = DC_7BIT; break;
1400  case 0x02: /* 8 bit binary - do nothing */
1401  case 0x04: /* 8 bit binary - do nothing */
1402  msg->sms.coding = DC_8BIT; break;
1403  case 0x05: /* JIS - what do I do with that ? */
1404  break;
1405  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
1406  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UCS-2BE") != 0)
1407  error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1408  msg->sms.coding = DC_UCS2; break;
1409  case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
1410  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)
1411  error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1412  msg->sms.coding = DC_UCS2; break;
1413  case 0x08: /* unicode UCS-2, yey */
1414  msg->sms.coding = DC_UCS2; break;
1415 
1416  /*
1417  * don't much care about the others,
1418  * you implement them if you feel like it
1419  */
1420 
1421  default:
1422  /*
1423  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
1424  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
1425  * if we have an UDH indicator, we assume DC_8BIT.
1426  */
1427  if (msg->sms.coding == DC_UNDEF && pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
1428  msg->sms.coding = DC_8BIT;
1429  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
1430  msg->sms.coding = DC_7BIT;
1431  charset_gsm_to_utf8(msg->sms.msgdata);
1432  }
1433  }
1434 
1435  if (box->version > 0x33) {
1436  if (msg->sms.meta_data == NULL)
1437  msg->sms.meta_data = octstr_create("");
1438  meta_data_set_values(msg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 1);
1439  }
1440 
1441  msg->sms.time = time(NULL);
1442 
1443  return msg;
1444 
1445 error:
1446  msg_destroy(msg);
1447  return NULL;
1448 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
unsigned long type
Definition: smpp_pdu.h:91
#define DC_8BIT
Definition: sms.h:111
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int version
Definition: opensmppbox.c:149
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Definition: msg.h:108
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
Octstr * alt_charset
Definition: opensmppbox.c:150
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void msg_destroy(Msg *msg)
Definition: msg.c:132
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi)
Definition: opensmppbox.c:558
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
#define DC_UNDEF
Definition: sms.h:109
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273
#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

◆ destroy_smsc_routes()

static void destroy_smsc_routes ( void  )
static

Definition at line 2405 of file opensmppbox.c.

References dict_destroy(), smsc_by_receiver, smsc_by_sender, smsc_by_sender_smsbox_id, and smsc_by_smsbox_id.

Referenced by main().

2406 {
2408  smsc_by_receiver = NULL;
2409 
2411  smsc_by_smsbox_id = NULL;
2412 
2414  smsc_by_sender = NULL;
2415 
2417  smsc_by_sender_smsbox_id = NULL;
2418 }
static Dict * smsc_by_smsbox_id
Definition: opensmppbox.c:121
void dict_destroy(Dict *dict)
Definition: dict.c:215
static Dict * smsc_by_receiver
Definition: opensmppbox.c:120
static Dict * smsc_by_sender
Definition: opensmppbox.c:122
static Dict * smsc_by_sender_smsbox_id
Definition: opensmppbox.c:123

◆ find_receiver_box()

static Boxc* find_receiver_box ( Boxc box)
static

Definition at line 1911 of file opensmppbox.c.

References _boxc::alive, all_boxes, _boxc::boxc_id, gwlist_get(), gwlist_len(), _boxc::login_type, octstr_compare(), SMPP_LOGIN_RECEIVER, and SMPP_LOGIN_TRANSCEIVER.

Referenced by bearerbox_to_smpp().

1912 {
1913  Boxc *thisbox;
1914  int cnt;
1915 
1917  return box;
1918  }
1919  for (cnt = 0; cnt < gwlist_len(all_boxes); cnt++) {
1920  thisbox = (Boxc *)gwlist_get(all_boxes, cnt);
1921  if ((thisbox->login_type == SMPP_LOGIN_RECEIVER || thisbox->login_type == SMPP_LOGIN_TRANSCEIVER) && (octstr_compare(thisbox->boxc_id, box->boxc_id) == 0) && thisbox->alive) {
1922  return thisbox;
1923  }
1924  }
1925  return box;
1926 }
static List * all_boxes
Definition: opensmppbox.c:110
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
Octstr * boxc_id
Definition: opensmppbox.c:160
smpp_login login_type
Definition: opensmppbox.c:144
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ generate_smppid()

static Octstr* generate_smppid ( Msg msg,
int  version 
)
static

Definition at line 638 of file opensmppbox.c.

References msg, octstr_create_from_data, UUID_STR_LEN, and uuid_unparse().

Referenced by handle_pdu().

639 {
640  char uuidbuf[100];
641  Octstr *result;
642 
643  // gw_assert(msg->type == sms); // we segfault on this
644 
645  uuid_unparse(msg->sms.id, uuidbuf);
646  result = octstr_create_from_data(uuidbuf, version > 0x33 ? UUID_STR_LEN : 8);
647  return result;
648 }
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ gw_smpp_enter()

static void gw_smpp_enter ( Cfg cfg)
static

Definition at line 2270 of file opensmppbox.c.

Referenced by init_smppbox().

2271 {
2272 }

◆ gw_smpp_leave()

static void gw_smpp_leave ( )
static

Definition at line 2274 of file opensmppbox.c.

Referenced by main().

2275 {
2276 }

◆ handle_pdu()

static void handle_pdu ( Connection conn,
Boxc box,
SMPP_PDU pdu 
)
static

Definition at line 1510 of file opensmppbox.c.

References ack_failed, _boxc::alive, _boxc::bearerbox_connection, _boxc::boxc_id, boxc_route_msg_to_smsc(), check_login(), check_multipart(), concat_msgids(), data_sm_to_msg(), _boxc::deliver_acks, dict_get(), dict_put(), dlr_add(), DLR_IS_ENABLED, dump_pdu, error(), generate_smppid(), gwlist_destroy(), identify_to_bearerbox(), _boxc::logged_in, _boxc::login_type, msg, _boxc::msg_acks, msg_destroy(), msg_destroy_item(), msg_dump(), msg_duplicate(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), our_system_id, pdu_to_msg(), send_msg(), send_pdu(), SMPP_ESME_RINVCMDID, SMPP_ESME_RINVPASWD, SMPP_ESME_RUNKNOWNERR, SMPP_LOGIN_RECEIVER, SMPP_LOGIN_TRANSCEIVER, SMPP_LOGIN_TRANSMITTER, smpp_pdu_create(), smpp_pdu_destroy(), _boxc::sms_service, smsc_id, systemidisboxcid, SMPP_PDU::type, SMPP_PDU::u, UUID_STR_LEN, uuid_unparse(), and _boxc::version.

Referenced by smpp_to_bearerbox().

1510  {
1511  SMPP_PDU *resp = NULL;
1512  Msg *msg, *msg2, *mack;
1513  long reason;
1514  Octstr *msgid = NULL, *hold_service, *system_type;
1515  int msg_to_send = 1;
1516  List *parts_list = NULL;
1517  char id[UUID_STR_LEN + 1];
1518 
1519  dump_pdu("Got PDU:", box->boxc_id, pdu);
1520  switch (pdu->type) {
1521  case bind_transmitter:
1522  case bind_receiver:
1523  case bind_transceiver:
1524  break;
1525  default:
1526  if (!box->logged_in) {
1527  resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number);
1528  resp->u.generic_nack.command_status = SMPP_ESME_RINVPASWD;
1529  goto error;
1530  }
1531  break;
1532  }
1533  switch (pdu->type) {
1534  case bind_transmitter:
1535  system_type = pdu->u.bind_transmitter.system_type ? pdu->u.bind_transmitter.system_type : octstr_imm("");
1536  if (check_login(box, pdu->u.bind_transmitter.system_id, pdu->u.bind_transmitter.password, system_type, SMPP_LOGIN_TRANSMITTER)) {
1537  box->logged_in = 1;
1538  box->version = pdu->u.bind_transmitter.interface_version;
1540  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1541  box->sms_service = octstr_duplicate(pdu->u.bind_transmitter.system_id);
1542  identify_to_bearerbox(box);
1543  resp = smpp_pdu_create(bind_transmitter_resp, pdu->u.bind_transmitter.sequence_number);
1544  resp->u.bind_transmitter_resp.system_id = octstr_duplicate(our_system_id);
1545  }
1546  else {
1547  resp = smpp_pdu_create(bind_transmitter_resp, pdu->u.bind_transmitter_resp.sequence_number);
1548  resp->u.bind_transmitter.command_status = 0x0d; /* invalid login */
1549  }
1550  break;
1551  case bind_receiver:
1552  system_type = pdu->u.bind_receiver.system_type ? pdu->u.bind_receiver.system_type : octstr_imm("");
1553  if (check_login(box, pdu->u.bind_receiver.system_id, pdu->u.bind_receiver.password, system_type, SMPP_LOGIN_RECEIVER)) {
1554  box->logged_in = 1;
1555  box->version = pdu->u.bind_receiver.interface_version;
1557  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1558  box->sms_service = octstr_duplicate(pdu->u.bind_receiver.system_id);
1559  identify_to_bearerbox(box);
1560  resp = smpp_pdu_create(bind_receiver_resp, pdu->u.bind_receiver.sequence_number);
1561  resp->u.bind_receiver_resp.system_id = octstr_duplicate(our_system_id);
1562  }
1563  else {
1564  resp = smpp_pdu_create(bind_receiver_resp, pdu->u.bind_receiver.sequence_number);
1565  resp->u.bind_receiver_resp.command_status = 0x0d; /* invalid login */
1566  }
1567  break;
1568  case bind_transceiver:
1569  system_type = pdu->u.bind_transceiver.system_type ? pdu->u.bind_transceiver.system_type : octstr_imm("");
1570  if (check_login(box, pdu->u.bind_transceiver.system_id, pdu->u.bind_transceiver.password, system_type, SMPP_LOGIN_TRANSCEIVER)) {
1571  box->logged_in = 1;
1572  box->version = pdu->u.bind_transceiver.interface_version;
1574  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1575  box->sms_service = octstr_duplicate(pdu->u.bind_transceiver.system_id);
1576  identify_to_bearerbox(box);
1577  resp = smpp_pdu_create(bind_transceiver_resp, pdu->u.bind_transceiver.sequence_number);
1578  resp->u.bind_transceiver_resp.system_id = octstr_duplicate(our_system_id);
1579  }
1580  else {
1581  resp = smpp_pdu_create(bind_transceiver_resp, pdu->u.bind_transceiver.sequence_number);
1582  resp->u.bind_transceiver_resp.command_status = 0x0d; /* invalid login */
1583  }
1584  break;
1585  case unbind:
1586  resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
1587  box->logged_in = 0;
1588  box->alive = 0;
1589  break;
1590  case enquire_link:
1591  resp = smpp_pdu_create(enquire_link_resp,
1592  pdu->u.enquire_link.sequence_number);
1593  break;
1594  case data_sm:
1595  msg = data_sm_to_msg(box, pdu, &reason);
1596  msg2 = msg;
1597  if (msg == NULL) {
1598  resp = smpp_pdu_create(generic_nack, pdu->u.data_sm.sequence_number);
1599  resp->u.generic_nack.command_status = SMPP_ESME_RUNKNOWNERR;
1600  }
1601  else {
1603  check_multipart(box, msg, &msg_to_send, &msg2, &parts_list);
1604  msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1605  msg->sms.boxc_id = octstr_duplicate(box->boxc_id);
1606  msg_dump(msg, 0);
1607  resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);
1608  msgid = generate_smppid(msg, box->version);
1609  msg->sms.dlr_url = octstr_duplicate(msgid);
1610  resp->u.data_sm_resp.message_id = msgid;
1611  if (msg_to_send) {
1612  if (DLR_IS_ENABLED(msg2->sms.dlr_mask)) {
1613  hold_service = msg2->sms.service;
1614  msg2->sms.service = octstr_format("%ld", msg2->sms.time);
1615  msgid = generate_smppid(msg2, box->version);
1616  if (parts_list) {
1617  msg2->sms.dlr_url = concat_msgids(msgid, parts_list);
1618  }
1619  dlr_add(box->boxc_id, msgid, msg2, 0);
1620  octstr_destroy(msgid);
1621  octstr_destroy(msg2->sms.service);
1622  msg2->sms.service = hold_service;
1623  }
1624  uuid_unparse(msg2->sms.id, id);
1625  msgid = octstr_create(id);
1626  dict_put(box->msg_acks, msgid, resp);
1627  resp = NULL;
1628  send_msg(box->bearerbox_connection, box, msg2);
1629  if (parts_list) {
1630  /* destroy values */
1631  gwlist_destroy(parts_list, msg_destroy_item);
1632  }
1633  else if (msg != msg2) {
1634  msg_destroy(msg);
1635  }
1636  }
1637  }
1638  break;
1639  case submit_sm:
1640  msg = pdu_to_msg(box, pdu, &reason);
1641  msg2 = msg;
1642  if (msg == NULL) {
1643  resp = smpp_pdu_create(generic_nack, pdu->u.submit_sm.sequence_number);
1644  resp->u.generic_nack.command_status = SMPP_ESME_RUNKNOWNERR;
1645  }
1646  else {
1648  check_multipart(box, msg, &msg_to_send, &msg2, &parts_list);
1649  msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1650  msg->sms.boxc_id = octstr_duplicate(box->boxc_id);
1651  msg_dump(msg, 0);
1652  resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
1653  msgid = generate_smppid(msg, box->version);
1654  msg->sms.dlr_url = octstr_duplicate(msgid);
1655  resp->u.submit_sm_resp.message_id = msgid;
1656  if (msg_to_send) {
1657  if (DLR_IS_ENABLED(msg2->sms.dlr_mask)) {
1658  hold_service = msg2->sms.service;
1659  msg2->sms.service = octstr_format("%ld", msg2->sms.time);
1660  msgid = generate_smppid(msg2, box->version);
1661  if (parts_list) {
1662  msg2->sms.dlr_url = concat_msgids(msgid, parts_list);
1663  }
1664  dlr_add(box->boxc_id, msgid, msg2, 0);
1665  octstr_destroy(msgid);
1666  octstr_destroy(msg2->sms.service);
1667  msg2->sms.service = hold_service;
1668  }
1669  uuid_unparse(msg2->sms.id, id);
1670  msgid = octstr_create(id);
1671  dict_put(box->msg_acks, msgid, resp);
1672  octstr_destroy(msgid);
1673  resp = NULL;
1674  send_msg(box->bearerbox_connection, box, msg2);
1675  if (parts_list) {
1676  /* destroy values */
1677  gwlist_destroy(parts_list, msg_destroy_item);
1678  }
1679  else if (msg != msg2) {
1680  msg_destroy(msg);
1681  }
1682  }
1683  }
1684  break;
1685  case deliver_sm_resp:
1686  msgid = octstr_format("%ld", pdu->u.deliver_sm_resp.sequence_number);
1687  mack = dict_get(box->deliver_acks, msgid);
1688  if (mack) {
1689  msg = msg_duplicate(mack);
1690  /* TODO: ack_failed_tmp */
1691  if (pdu->u.deliver_sm_resp.command_status != 0) {
1692  msg->ack.nack = ack_failed;
1693  }
1694  send_msg(box->bearerbox_connection, box, msg);
1695  dict_put(box->deliver_acks, msgid, NULL);
1696  }
1697  octstr_destroy(msgid);
1698  break;
1699  case unbind_resp:
1700  box->logged_in = 0;
1701  box->alive = 0;
1702  default:
1703  error(0, "SMPP[%s]: Unknown PDU type 0x%08lx, ignored.",
1704  octstr_get_cstr(box->boxc_id), pdu->type);
1705  /*
1706  send gnack , see smpp3.4 spec., section 3.3
1707  because we doesn't know what kind of pdu received, we assume generick_nack_resp
1708  (header always the same)
1709  */
1710  resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number);
1711  resp->u.generic_nack.command_status = SMPP_ESME_RINVCMDID;
1712  break;
1713  }
1714 error:
1715  smpp_pdu_destroy(pdu);
1716  if (resp != NULL) {
1717  send_pdu(conn, box->boxc_id, resp);
1718  smpp_pdu_destroy(resp);
1719  }
1720 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
void error(int err, const char *fmt,...)
Definition: log.c:648
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
static Octstr * boxc_route_msg_to_smsc(Boxc *box, Msg *msg)
Definition: opensmppbox.c:1800
Dict * msg_acks
Definition: opensmppbox.c:163
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
static void identify_to_bearerbox(Boxc *conn)
Definition: opensmppbox.c:487
static Octstr * generate_smppid(Msg *msg, int version)
Definition: opensmppbox.c:638
void check_multipart(Boxc *box, Msg *msg, int *msg_to_send, Msg **msg2, List **parts_list)
Definition: opensmppbox.c:1464
unsigned long type
Definition: smpp_pdu.h:91
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
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
int version
Definition: opensmppbox.c:149
Dict * deliver_acks
Definition: opensmppbox.c:164
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
Definition: opensmppbox.c:453
Connection * bearerbox_connection
Definition: opensmppbox.c:143
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
#define dump_pdu(msg, id, pdu)
Definition: opensmppbox.c:347
void msg_destroy_item(void *msg)
Definition: msg.c:147
static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
Definition: opensmppbox.c:620
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
Octstr * concat_msgids(Octstr *msgid, List *list)
Definition: opensmppbox.c:1450
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
static int systemidisboxcid
Definition: opensmppbox.c:131
static Msg * pdu_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
Definition: opensmppbox.c:1100
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
static Octstr * our_system_id
Definition: opensmppbox.c:126
void msg_destroy(Msg *msg)
Definition: msg.c:132
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
union SMPP_PDU::@15 u
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
Octstr * sms_service
Definition: opensmppbox.c:161
int check_login(Boxc *boxc, Octstr *system_id, Octstr *password, Octstr *system_type, smpp_login login_type)
Definition: opensmppbox.c:278
static Msg * data_sm_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
Definition: opensmppbox.c:1302
smpp_login login_type
Definition: opensmppbox.c:144
#define DLR_IS_ENABLED(dlr)
Definition: dlr.h:81
Definition: list.c:102
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
int logged_in
Definition: opensmppbox.c:145
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ identify_to_bearerbox()

static void identify_to_bearerbox ( Boxc conn)
static

Definition at line 487 of file opensmppbox.c.

References _boxc::bearerbox_connection, _boxc::boxc_id, cmd_identify, msg, msg_create, octstr_duplicate, and send_msg().

Referenced by handle_pdu().

488 {
489  Msg *msg;
490 
491  msg = msg_create(admin);
492  msg->admin.command = cmd_identify;
493  msg->admin.boxc_id = octstr_duplicate(conn->boxc_id);
494  send_msg(conn->bearerbox_connection, conn, msg);
495 }
#define msg_create(type)
Definition: msg.h:136
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
Definition: opensmppbox.c:453
Connection * bearerbox_connection
Definition: opensmppbox.c:143
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ init_smppbox()

static void init_smppbox ( Cfg cfg)
static

Definition at line 2420 of file opensmppbox.c.

References alt_charset, BB_DEFAULT_HOST, BB_DEFAULT_SMSBOX_PORT, bearerbox_host, bearerbox_port, bearerbox_port_ssl, boxid, catenated_sms_counter, cfg, cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_single_group(), conn_config_ssl(), counter_create(), debug(), disable_multipart_catenation, dlr_init(), enablepam, GW_NON_EXCL, gw_smpp_enter(), info(), init_smsc_routes(), log_open(), msg_pack(), msg_unpack_wrapper(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), our_system_id, pamacl, panic, route_to_smsc, smpp_autodetect_addr, smpp_dest_addr_npi, smpp_dest_addr_ton, smpp_logins, smpp_pdu_init(), SMPP_RUNNING, smpp_source_addr_npi, smpp_source_addr_ton, smpp_timeout, smppbox_id, smppbox_port, smppbox_port_ssl, smppbox_status, store_init(), systemidisboxcid, TIMEOUT_SECONDS, and warning().

Referenced by main().

2421 {
2422  CfgGroup *grp;
2423  Octstr *logfile;
2424  long lvl;
2425  Octstr *val, *log; /* temporary store variables */
2426  long store_dump_freq = -1; /* dummy variable */
2427 
2428  /* some default values */
2429  smppbox_port = 13005;
2430  smppbox_port_ssl = 0;
2431  bearerbox_host = NULL;
2432  bearerbox_port_ssl = 0;
2433  logfile = NULL;
2434  lvl = 0;
2435  systemidisboxcid = 0; /* default backward compatible */
2436  enablepam = 0; /* also default false */
2437 
2438  /* init dlr storage */
2439  dlr_init(cfg);
2440  /* init storage store */
2441  grp= cfg_get_single_group(cfg, octstr_imm("core"));
2442  if (grp != NULL) {
2443  log = cfg_get(grp, octstr_imm("store-file"));
2444  if (log != NULL) {
2445  warning(0, "'store-file' option deprecated, please use 'store-location' and 'store-type' instead.");
2446  val = octstr_create("file");
2447  } else {
2448  log = cfg_get(grp, octstr_imm("store-location"));
2449  val = cfg_get(grp, octstr_imm("store-type"));
2450  }
2451  if (val != NULL) {
2452  if (store_init(cfg, val, log, store_dump_freq, msg_pack, msg_unpack_wrapper) == -1) {
2453  panic(0, "Could not start with store init failed.");
2454  }
2455  }
2456  octstr_destroy(val);
2457  octstr_destroy(log);
2458  }
2459 
2460  /* initialize low level PDUs */
2461  if (smpp_pdu_init(cfg) == -1)
2462  panic(0, "Connot start with PDU init failed.");
2463 
2464  /*
2465  * first we take the port number in bearerbox and other values from the
2466  * opensmppbox group in configuration file
2467  */
2468 
2469  grp = cfg_get_single_group(cfg, octstr_imm("opensmppbox"));
2470  if (grp == NULL)
2471  panic(0, "No 'opensmppbox' group in configuration");
2472 
2473  bearerbox_host = cfg_get(grp, octstr_imm("bearerbox-host"));
2474  if (!bearerbox_host) {
2476  }
2477  if (cfg_get_integer(&bearerbox_port, grp, octstr_imm("bearerbox-port")) == -1)
2479 #ifdef HAVE_LIBSSL
2480 #if 0
2481  cfg_get_bool(&bearerbox_port_ssl, grp, octstr_imm("bearerbox-port-ssl"));
2482  conn_config_ssl(grp);
2483 #endif
2484 #endif
2485 
2486  smppbox_id = cfg_get(grp, octstr_imm("opensmppbox-id"));
2487  our_system_id = cfg_get(grp, octstr_imm("our-system-id"));
2488  route_to_smsc = cfg_get(grp, octstr_imm("route-to-smsc"));
2489  if (our_system_id == NULL) {
2490  panic(0, "our-system-id is not set.");
2491  }
2492  alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
2493 
2494  /* setup logfile stuff */
2495  logfile = cfg_get(grp, octstr_imm("log-file"));
2496 
2497  cfg_get_integer(&lvl, grp, octstr_imm("log-level"));
2498 
2499  if (cfg_get_integer(&smppbox_port, grp, octstr_imm("opensmppbox-port")) == -1)
2500  smppbox_port = 2345;
2501 
2502  smpp_logins = cfg_get(grp, octstr_imm("smpp-logins"));
2503 
2504  if (smpp_logins == NULL) {
2505  panic(0, "No user file specified.");
2506  }
2507 
2508  if (logfile != NULL) {
2509  info(0, "Starting to log to file %s level %ld",
2510  octstr_get_cstr(logfile), lvl);
2511  log_open(octstr_get_cstr(logfile), lvl, GW_NON_EXCL);
2512  octstr_destroy(logfile);
2513  }
2514 
2515  if (cfg_get_integer(&smpp_timeout, grp, octstr_imm("timeout")) == -1)
2517  if (cfg_get_integer(&smpp_source_addr_ton, grp, octstr_imm("source-addr-ton")) == -1)
2518  smpp_source_addr_ton = -1;
2519  if (cfg_get_integer(&smpp_source_addr_npi, grp, octstr_imm("source-addr-npi")) == -1)
2520  smpp_source_addr_npi = -1;
2521  if (cfg_get_bool(&smpp_autodetect_addr, grp, octstr_imm("source-addr-auto")) == -1)
2523  if (cfg_get_integer(&smpp_dest_addr_ton, grp, octstr_imm("dest-addr-ton")) == -1)
2524  smpp_dest_addr_ton = -1;
2525  if (cfg_get_integer(&smpp_dest_addr_npi, grp, octstr_imm("dest-addr-npi")) == -1)
2526  smpp_dest_addr_npi = -1;
2527 
2528  cfg_get_bool(&systemidisboxcid, grp, octstr_imm("use-systemid-as-smsboxid"));
2529  cfg_get_bool(&enablepam, grp, octstr_imm("enable-pam"));
2530  pamacl = cfg_get(grp, octstr_imm("pam-acl"));
2531  if (NULL == pamacl) {
2532  pamacl = octstr_create("kannel");
2533  }
2534  if (enablepam && !systemidisboxcid) {
2535  panic(0, "enable-pam requires systemid-is-boxcid=true.");
2536  }
2537 #ifndef HAVE_PAM
2538  if (enablepam) {
2539  panic(0, "enable-pam is set but we are compiled without pam support.");
2540  }
2541 #endif
2542  if (enablepam) {
2543  info(0, "Using PAM authentication.");
2544  }
2545 
2546  cfg_get_bool(&disable_multipart_catenation, grp, octstr_imm("disable-multipart-catenation"));
2548  debug("opensmppbox", 0, "disable-multipart-catenation: %d.", disable_multipart_catenation);
2549  }
2550 
2552 
2554  boxid = counter_create();
2555  gw_smpp_enter(cfg);
2556 
2558 }
static Octstr * route_to_smsc
Definition: opensmppbox.c:127
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
void info(int err, const char *fmt,...)
Definition: log.c:672
static Octstr * smppbox_id
Definition: opensmppbox.c:125
static Counter * catenated_sms_counter
Definition: opensmppbox.c:112
static long smpp_dest_addr_npi
Definition: opensmppbox.c:118
static long smpp_source_addr_ton
Definition: opensmppbox.c:114
Msg * msg_unpack_wrapper(Octstr *os)
Definition: msg.c:256
#define BB_DEFAULT_HOST
Definition: bb.h:67
#define cfg_get(grp, varname)
Definition: cfg.h:86
static void init_smsc_routes(Cfg *cfg)
Definition: opensmppbox.c:2278
#define TIMEOUT_SECONDS
Definition: opensmppbox.c:137
static Cfg * cfg
Definition: opensmppbox.c:95
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * pamacl
Definition: opensmppbox.c:133
static int bearerbox_port_ssl
Definition: opensmppbox.c:106
static int disable_multipart_catenation
Definition: opensmppbox.c:134
static long smppbox_port
Definition: opensmppbox.c:102
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
static int enablepam
Definition: opensmppbox.c:132
Counter * counter_create(void)
Definition: counter.c:94
static long smpp_dest_addr_ton
Definition: opensmppbox.c:117
void conn_config_ssl(CfgGroup *grp)
Definition: conn.c:1546
static long smpp_source_addr_npi
Definition: opensmppbox.c:115
static int systemidisboxcid
Definition: opensmppbox.c:131
int store_init(Cfg *cfg, const Octstr *type, const Octstr *fname, long dump_freq, void *pack_func, void *unpack_func)
Definition: bb_store.c:82
static void gw_smpp_enter(Cfg *cfg)
Definition: opensmppbox.c:2270
static Octstr * our_system_id
Definition: opensmppbox.c:126
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Counter * boxid
Definition: opensmppbox.c:108
#define octstr_create(cstr)
Definition: octstr.h:125
static Octstr * smpp_logins
Definition: opensmppbox.c:107
static long bearerbox_port
Definition: opensmppbox.c:104
int log_open(char *filename, int level, enum excl_state excl)
Definition: log.c:375
void dlr_init(Cfg *cfg)
Definition: dlr.c:233
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:759
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
#define panic
Definition: log.h:87
static time_t smpp_timeout
Definition: opensmppbox.c:128
Definition: cfg.c:73
static int smppbox_port_ssl
Definition: opensmppbox.c:103
Octstr * msg_pack(Msg *msg)
Definition: msg.c:181
int smpp_pdu_init(Cfg *cfg)
Definition: smpp_pdu.c:184
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:639
#define BB_DEFAULT_SMSBOX_PORT
Definition: bb.h:68
static Octstr * alt_charset
Definition: opensmppbox.c:129
#define SMPP_RUNNING
Definition: opensmppbox.c:101
static int smpp_autodetect_addr
Definition: opensmppbox.c:116
static Octstr * bearerbox_host
Definition: opensmppbox.c:105

◆ init_smsc_routes()

static void init_smsc_routes ( Cfg cfg)
static

Definition at line 2278 of file opensmppbox.c.

References cfg, cfg_get, cfg_get_multi_group(), debug(), dict_create(), dict_put_once(), grp_dump(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), octstr_destroy(), octstr_destroy_item(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_insert(), octstr_insert_char(), octstr_len(), octstr_split(), octstr_strip_blanks(), panic, smsc_by_receiver, smsc_by_sender, smsc_by_sender_smsbox_id, smsc_by_smsbox_id, and smsc_id.

Referenced by init_smppbox().

2279 {
2280  CfgGroup *grp;
2281  List *list, *items;
2282  Octstr *smsc_id, *boxc_ids, *shortcodes, *receiver_shortcodes;
2283  int i, j;
2284 
2285  smsc_by_receiver = dict_create(1000, (void(*)(void *)) octstr_destroy);
2286  smsc_by_smsbox_id = dict_create(30, (void(*)(void *)) octstr_destroy);
2287  smsc_by_sender = dict_create(50, (void(*)(void *)) octstr_destroy);
2288  smsc_by_sender_smsbox_id = dict_create(50, (void(*)(void *)) octstr_destroy);
2289 
2290  smsc_id = boxc_ids = shortcodes = receiver_shortcodes = NULL;
2291  list = items = NULL;
2292 
2293  list = cfg_get_multi_group(cfg, octstr_imm("smsc-route"));
2294 
2295  /* loop multi-group "client-route" */
2296  while (list && (grp = gwlist_extract_first(list)) != NULL) {
2297  if ((smsc_id = cfg_get(grp, octstr_imm("smsc-id"))) == NULL) {
2298  grp_dump(grp);
2299  panic(0,"'smsc-id-route' group without valid 'smsc-id' directive!");
2300  }
2301 
2302  /*
2303  * If smsbox-id is given, then any message coming from the specified
2304  * smsbox-id in the list will be routed to this smsc.
2305  * If shortcode is given, then any message with sender number
2306  * matching those will be routed to this smsc.
2307  * If both are given, then only sender within shortcode originating
2308  * from sysmtem-id list will be routed to this smsc. So if both are
2309  * present then this is a logical AND operation.
2310  */
2311  boxc_ids = cfg_get(grp, octstr_imm("smsbox-id"));
2312  shortcodes = cfg_get(grp, octstr_imm("shortcode"));
2313  receiver_shortcodes = cfg_get(grp, octstr_imm("receiver-shortcode"));
2314 
2315  /* Consider the receiver options: receiver-shortcode. */
2316  if (receiver_shortcodes) {
2317  /* receiver-shortcode applies to all MTs from all smscs */
2318  items = octstr_split(receiver_shortcodes, octstr_imm(";"));
2319  for (i = 0; i < gwlist_len(items); i++) {
2320  Octstr *item = gwlist_get(items, i);
2321  octstr_strip_blanks(item);
2322 
2323  debug("opensmppbox",0,"Adding smsc routing to id <%s> for receiver no <%s>",
2325 
2327  panic(0, "Routing for receiver no <%s> already exists!",
2328  octstr_get_cstr(item));
2329  }
2331  octstr_destroy(receiver_shortcodes);
2332  }
2333 
2334  /* consider now the 3 possibilities: */
2335  if (boxc_ids && !shortcodes) {
2336  /* smsbox-id only, so all MT traffic */
2337  items = octstr_split(boxc_ids, octstr_imm(";"));
2338  for (i = 0; i < gwlist_len(items); i++) {
2339  Octstr *item = gwlist_get(items, i);
2340  octstr_strip_blanks(item);
2341 
2342  debug("opensmppbox",0,"Adding smsc routing to id <%s> for box id <%s>",
2344 
2346  panic(0, "Routing for box-id <%s> already exists!",
2347  octstr_get_cstr(item));
2348  }
2350  octstr_destroy(boxc_ids);
2351  }
2352  else if (!boxc_ids && shortcodes) {
2353  /* shortcode only, so these MTs from all smscs */
2354  items = octstr_split(shortcodes, octstr_imm(";"));
2355  for (i = 0; i < gwlist_len(items); i++) {
2356  Octstr *item = gwlist_get(items, i);
2357  octstr_strip_blanks(item);
2358 
2359  debug("opensmppbox",0,"Adding smsc routing to id <%s> for sender no <%s>",
2361 
2363  panic(0, "Routing for sender no <%s> already exists!",
2364  octstr_get_cstr(item));
2365  }
2367  octstr_destroy(shortcodes);
2368  }
2369  else if (boxc_ids && shortcodes) {
2370  /* both, so only specified MTs from specified smsbox ids */
2371  items = octstr_split(shortcodes, octstr_imm(";"));
2372  for (i = 0; i < gwlist_len(items); i++) {
2373  List *subitems;
2374  Octstr *item = gwlist_get(items, i);
2375  octstr_strip_blanks(item);
2376  subitems = octstr_split(boxc_ids, octstr_imm(";"));
2377  for (j = 0; j < gwlist_len(subitems); j++) {
2378  Octstr *subitem = gwlist_get(subitems, j);
2379  octstr_strip_blanks(subitem);
2380 
2381  debug("opensmppbox",0,"Adding smsc routing to id <%s> "
2382  "for sender no <%s> and smsbox id <%s>",
2384  octstr_get_cstr(subitem));
2385 
2386  /* construct the dict key '<shortcode>:<smsbox-id>' */
2387  octstr_insert(subitem, item, 0);
2388  octstr_insert_char(subitem, octstr_len(item), ':');
2390  panic(0, "Routing for sender:smsbox-id <%s> already exists!",
2391  octstr_get_cstr(subitem));
2392  }
2394  }
2396  octstr_destroy(boxc_ids);
2397  octstr_destroy(shortcodes);
2398  }
2400  }
2401 
2402  gwlist_destroy(list, NULL);
2403 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define cfg_get(grp, varname)
Definition: cfg.h:86
static Cfg * cfg
Definition: opensmppbox.c:95
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void * gwlist_extract_first(List *list)
Definition: list.c:305
void grp_dump(CfgGroup *grp)
Definition: cfg.c:811
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1481
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
static Dict * smsc_by_smsbox_id
Definition: opensmppbox.c:121
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Dict * smsc_by_receiver
Definition: opensmppbox.c:120
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
static Dict * smsc_by_sender
Definition: opensmppbox.c:122
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1640
Definition: list.c:102
static Dict * smsc_by_sender_smsbox_id
Definition: opensmppbox.c:123
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 2620 of file opensmppbox.c.

References all_boxes, ALL_HEARTBEATS, boxid, catenated_sms_counter, cfg, cfg_add_hooks(), cfg_create(), cfg_read(), check_args(), counter_destroy(), destroy_smsc_routes(), dict_create(), dlr_shutdown(), filename, get_and_set_debugs(), gw_smpp_leave(), gwlib_init(), gwlib_shutdown(), gwlist_create, gwlist_destroy(), gwthread_sleep(), heartbeat_stop(), init_smppbox(), list_dict, octstr_create, octstr_destroy(), octstr_format(), octstr_get_cstr, panic, report_versions(), restart_smppbox, setup_signal_handlers(), smppbox_is_allowed_in_group(), smppbox_is_single_group(), smppbox_port, and smppboxc_run().

2621 {
2622  int cf_index;
2623  Octstr *filename, *version;
2624 
2625  gwlib_init();
2627  list_dict = dict_create(1, NULL);
2628 
2629  cf_index = get_and_set_debugs(argc, argv, check_args);
2631 
2632  if (argv[cf_index] == NULL)
2633  filename = octstr_create("opensmppbox.conf");
2634  else
2635  filename = octstr_create(argv[cf_index]);
2636 
2637  cfg = cfg_create(filename);
2638 
2639  /* Adding cfg-checks to core */
2640 
2642 
2643  if (cfg_read(cfg) == -1)
2644  panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
2645 
2647 
2648  version = octstr_format("opensmppbox version %s gwlib", GW_VERSION);
2649  report_versions(octstr_get_cstr(version));
2650  octstr_destroy(version);
2651 
2652  init_smppbox(cfg);
2653 
2654  smppboxc_run((void *)smppbox_port);
2655 
2656  /* shutdown dlr storage */
2658  dlr_shutdown();
2662 
2663  if (restart_smppbox) {
2664  gwthread_sleep(1.0);
2665  }
2666 
2667  gwlist_destroy(all_boxes, NULL);
2668  gw_smpp_leave();
2669  gwlib_shutdown();
2670 
2671  if (restart_smppbox)
2672  execvp(argv[0], argv);
2673  return 0;
2674 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static volatile sig_atomic_t restart_smppbox
Definition: opensmppbox.c:97
static Counter * catenated_sms_counter
Definition: opensmppbox.c:112
static List * all_boxes
Definition: opensmppbox.c:110
void counter_destroy(Counter *counter)
Definition: counter.c:110
static void init_smppbox(Cfg *cfg)
Definition: opensmppbox.c:2420
static void destroy_smsc_routes(void)
Definition: opensmppbox.c:2405
static Dict * list_dict
Definition: opensmppbox.c:111
static void setup_signal_handlers(void)
Definition: opensmppbox.c:2256
static Cfg * cfg
Definition: opensmppbox.c:95
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Cfg * cfg_create(Octstr *filename)
Definition: cfg.c:318
void heartbeat_stop(long hb_thread)
Definition: heartbeat.c:160
int cfg_read(Cfg *cfg)
Definition: cfg.c:452
static long smppbox_port
Definition: opensmppbox.c:102
void cfg_add_hooks(void *allowed, void *single)
Definition: cfg.c:253
static int smppbox_is_allowed_in_group(Octstr *group, Octstr *variable)
Definition: opensmppbox.c:2575
static void smppboxc_run(void *arg)
Definition: opensmppbox.c:2186
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
char filename[FILENAME_MAX+1]
Definition: log.c:171
static Counter * boxid
Definition: opensmppbox.c:108
#define octstr_create(cstr)
Definition: octstr.h:125
void gwthread_sleep(double seconds)
static void gw_smpp_leave()
Definition: opensmppbox.c:2274
#define ALL_HEARTBEATS
Definition: heartbeat.h:68
void report_versions(const char *boxname)
Definition: utils.c:539
static int smppbox_is_single_group(Octstr *query)
Definition: opensmppbox.c:2607
Definition: octstr.c:118
#define panic
Definition: log.h:87
void gwlib_shutdown(void)
Definition: gwlib.c:94
#define gwlist_create()
Definition: list.h:136
void gwlib_init(void)
Definition: gwlib.c:78
static int check_args(int i, int argc, char **argv)
Definition: opensmppbox.c:2560
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
Definition: utils.c:626
void dlr_shutdown()
Definition: dlr.c:299
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ msg_to_pdu()

static List* msg_to_pdu ( Boxc box,
Msg msg 
)
static

Definition at line 698 of file opensmppbox.c.

References _boxc::alt_charset, _boxc::alt_dcs, _boxc::autodetect_addr, _boxc::boxc_id, catenated_sms_counter, charset_convert(), charset_utf8_to_gsm(), counter_increase(), DC_7BIT, DC_UNDEF, debug(), _boxc::dest_addr_npi, _boxc::dest_addr_ton, dict_destroy(), DLR_BUFFERED, DLR_EXPIRED, DLR_FAIL, dlr_find(), DLR_IS_FAIL, DLR_IS_SUCCESS, DLR_IS_SUCCESS_OR_FAIL, DLR_NOTHING, DLR_SMSC_FAIL, DLR_SMSC_SUCCESS, DLR_SUCCESS, DLR_UNDEFINED, error(), ESM_CLASS_DELIVER_SMSC_DELIVER_ACK, ESM_CLASS_DELIVER_UDH_INDICATOR, 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_isdigit(), gw_localtime(), gw_strftime(), gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), MC_UNDEF, meta_data_get_value(), meta_data_get_values(), msg, msg_destroy(), msg_destroy_item(), MWI_UNDEF, octstr_cat(), octstr_check_range(), octstr_delete(), octstr_destroy(), octstr_destroy_item(), octstr_duplicate, octstr_format(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_insert(), octstr_len(), octstr_split(), _boxc::priority, report_mo, _boxc::service_type, _boxc::smpp_pdu_counter, smpp_pdu_create(), smpp_pdu_destroy(), sms_max_length, SMS_PARAM_UNDEFINED, sms_split(), _boxc::source_addr_npi, _boxc::source_addr_ton, text, SMPP_PDU::u, and _boxc::version.

Referenced by bearerbox_to_smpp().

699 {
700  SMPP_PDU *pdu, *pdu2;
701  List *pdulist = gwlist_create(), *parts;
702  int dlrtype, catenate;
703  int dlr_state = 7; /* UNKNOWN */
704  Msg *dlr;
705  char *text, *tmps, err[4] = { '0', '0', '0', '\0' };
706  char submit_date_c_str[11] = { '\0' }, done_date_c_str[11] = { '\0' };
707  struct tm tm_tmp;
708  Octstr *msgid, *msgid2, *dlr_status, *dlvrd;
709  /* split variables */
710  unsigned long msg_sequence, msg_count;
711  unsigned long submit_date;
712  int max_msgs;
713  Octstr *header, *footer, *suffix, *split_chars;
714  Msg *msg2;
715 
716  pdu = smpp_pdu_create(deliver_sm,
718 
719  pdu->u.deliver_sm.source_addr = octstr_duplicate(msg->sms.sender);
720  pdu->u.deliver_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
721 
722  /* Set the service type of the outgoing message. We'll use the config
723  * directive as default and 'binfo' as specific parameter. */
724  pdu->u.deliver_sm.service_type = octstr_len(msg->sms.binfo) ?
725  octstr_duplicate(msg->sms.binfo) : octstr_duplicate(box->service_type);
726 
727  /* Check for manual override of source ton and npi values */
728  if(box->source_addr_ton > -1 && box->source_addr_npi > -1) {
729  pdu->u.deliver_sm.source_addr_ton = box->source_addr_ton;
730  pdu->u.deliver_sm.source_addr_npi = box->source_addr_npi;
731  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %ld, source add npi = %ld",
733  box->source_addr_npi);
734  } else {
735  /* setup default values */
736  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
737  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
738  }
739 
740  if (box->autodetect_addr) {
741  /* lets see if its international or alphanumeric sender */
742  if (octstr_get_char(pdu->u.deliver_sm.source_addr, 0) == '+') {
743  if (!octstr_check_range(pdu->u.deliver_sm.source_addr, 1, 256, gw_isdigit)) {
744  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
745  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; /* short code */
746  } else {
747  /* numeric sender address with + in front -> international (remove the +) */
748  octstr_delete(pdu->u.deliver_sm.source_addr, 0, 1);
749  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
750  }
751  } else {
752  if (!octstr_check_range(pdu->u.deliver_sm.source_addr,0, 256, gw_isdigit)) {
753  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
754  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
755  }
756  }
757  }
758 
759  /* Check for manual override of destination ton and npi values */
760  if (box->dest_addr_ton > -1 && box->dest_addr_npi > -1) {
761  pdu->u.deliver_sm.dest_addr_ton = box->dest_addr_ton;
762  pdu->u.deliver_sm.dest_addr_npi = box->dest_addr_npi;
763  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %ld, dest add npi = %ld",
765  box->dest_addr_npi);
766  } else {
767  pdu->u.deliver_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
768  pdu->u.deliver_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
769  }
770 
771  /*
772  * if its a international number starting with +, lets remove the
773  * '+' and set number type to international instead
774  */
775  if (octstr_get_char(pdu->u.deliver_sm.destination_addr,0) == '+') {
776  octstr_delete(pdu->u.deliver_sm.destination_addr, 0,1);
777  pdu->u.deliver_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
778  }
779 
780  /* check length of src/dst address */
781  if (octstr_len(pdu->u.deliver_sm.destination_addr) > 20 ||
782  octstr_len(pdu->u.deliver_sm.source_addr) > 20) {
783  smpp_pdu_destroy(pdu);
784  gwlist_destroy(pdulist, NULL);
785  return NULL;
786  }
787 
788  /*
789  * set the data coding scheme (DCS) field
790  * check if we have a forced value for this from the smsc-group.
791  * Note: if message class is set, then we _must_ force alt_dcs otherwise
792  * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
793  * first here, because MWI and MCLASS can not be set at the same time and
794  * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
795  * if MWI is set.
796  */
797  if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
798  pdu->u.deliver_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
799  else
800  pdu->u.deliver_sm.data_coding = fields_to_dcs(msg,
801  (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
802  msg->sms.alt_dcs : box->alt_dcs));
803 
804  /* set protocol id */
805  if(msg->sms.pid != SMS_PARAM_UNDEFINED)
806  pdu->u.deliver_sm.protocol_id = msg->sms.pid;
807 
808  /*
809  * set the esm_class field
810  * default is store and forward, plus udh and rpi if requested
811  */
812  pdu->u.deliver_sm.esm_class = 0;
813  if (octstr_len(msg->sms.udhdata))
814  pdu->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class |
816  if (msg->sms.rpi > 0)
817  pdu->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class |
819 
820  /* Is this a delivery report? */
821  if (msg->sms.sms_type == report_mo) {
822  pdu->u.deliver_sm.esm_class |= ESM_CLASS_DELIVER_SMSC_DELIVER_ACK;
823  dlrtype = msg->sms.dlr_mask;
824  parts = octstr_split(msg->sms.dlr_url, octstr_imm(";"));
825  msgid = gwlist_extract_first(parts);
826  dlr = dlr_find(box->boxc_id, msgid, msg->sms.receiver, dlrtype, 0);
827  if (dlr == NULL) {
828  /* we could not find a corresponding dlr; nothing to send */
829  smpp_pdu_destroy(pdu);
830  gwlist_destroy(pdulist, NULL);
831  octstr_destroy(msgid);
833  return NULL;
834  }
835  dlvrd = octstr_imm("000");
836  switch (dlrtype) {
837  case DLR_UNDEFINED:
838  case DLR_NOTHING:
839  dlr_state = 8;
840  dlr_status = octstr_imm("REJECTD");
841  break;
842  case DLR_SUCCESS:
843  dlr_state = 2;
844  dlr_status = octstr_imm("DELIVRD");
845  dlvrd = octstr_imm("001");
846  break;
847  case DLR_EXPIRED:
848  dlr_state = 3;
849  dlr_status = octstr_imm("EXPIRED");
850  case DLR_BUFFERED:
851  dlr_state = 6;
852  dlr_status = octstr_imm("ACCEPTD");
853  break;
854  case DLR_SMSC_SUCCESS:
855  /* please note that this state does not quite conform to the SMMP v3.4 spec */
856  dlr_state = 0;
857  dlr_status = octstr_imm("BUFFRED");
858  break;
859  case DLR_FAIL:
860  case DLR_SMSC_FAIL:
861  dlr_state = 5;
862  dlr_status = octstr_imm("UNDELIV");
863  break;
864  }
865 
866  text = octstr_get_cstr(msg->sms.msgdata);
867 
868  tmps = strstr(text, "err:");
869  if (tmps != NULL) {
870  /* we can't use 0-padding with %s, if this is really required,
871  * then convert the numeric string to a real integer. - st */
872  snprintf(err, sizeof(err), "%3.3s", tmps + (4 * sizeof(char)));
873  tmps = strstr(tmps, " ");
874  text = tmps ? tmps + (1 * sizeof(char)) : "";
875  }
876 
877  tmps = strstr(text, "text:");
878  if (tmps != NULL) {
879  text = tmps + (5 * sizeof(char));
880  }
881 
882  /* restore original submission date from service */
883  submit_date = 0;
884  if (octstr_len(dlr->sms.service) > 0) {
885  sscanf(octstr_get_cstr(dlr->sms.service), "%ld", &submit_date);
886  }
887  if (!submit_date || submit_date > dlr->sms.time) {
888  submit_date = msg->sms.time;
889  }
890 
891  tm_tmp = gw_localtime(submit_date);
892  gw_strftime(submit_date_c_str, sizeof(submit_date_c_str), "%y%m%d%H%M", &tm_tmp);
893 
894  tm_tmp = gw_localtime(dlr->sms.time);
895  gw_strftime(done_date_c_str, sizeof(done_date_c_str), "%y%m%d%H%M", &tm_tmp);
896 
897  /* the msgids are in dlr->dlr_url as reported by Victor Luchitz */
899  parts = octstr_split(dlr->sms.dlr_url, octstr_imm(";"));
901  if (gwlist_len(parts) > 0) {
902  while ((msgid2 = gwlist_extract_first(parts)) != NULL) {
903  debug("opensmppbox", 0, "DLR for multipart message: sending %s.", octstr_get_cstr(msgid2));
904  pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
905  pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class;
906  pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
907  pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
908  pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
909  pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
910  pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
911  pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
912  pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
913  pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
914  pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
915  if (box->version > 0x33) {
916  pdu2->u.deliver_sm.receipted_message_id = octstr_duplicate(msgid2);
917  pdu2->u.deliver_sm.message_state = dlr_state;
918  dict_destroy(pdu2->u.deliver_sm.tlv);
919  pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
920  }
921  pdu2->u.deliver_sm.short_message = octstr_format("id:%S sub:001 dlvrd:%S submit date:%s done date:%s stat:%S err:%s text:%12s", msgid2, dlvrd, submit_date_c_str, done_date_c_str, dlr_status, err, text);
922  octstr_destroy(msgid2);
923  gwlist_append(pdulist, pdu2);
924  }
925  smpp_pdu_destroy(pdu);
926  }
927  else {
928  if (box->version > 0x33) {
929  pdu->u.deliver_sm.receipted_message_id = octstr_duplicate(msgid);
930  pdu->u.deliver_sm.message_state = dlr_state;
931  dict_destroy(pdu->u.deliver_sm.tlv);
932  pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
933  }
934  pdu->u.deliver_sm.short_message = octstr_format("id:%S sub:001 dlvrd:%S submit date:%s done date:%s stat:%S err:%s text:%12s", msgid, dlvrd, submit_date_c_str, done_date_c_str, dlr_status, err, text);
935  gwlist_append(pdulist, pdu);
936  }
937  octstr_destroy(msgid);
938  msg_destroy(dlr);
940  return pdulist;
941  }
942  else {
943  /* ask for the delivery reports if needed */
944  if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
945  pdu->u.deliver_sm.registered_delivery = 1;
946  else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
947  pdu->u.deliver_sm.registered_delivery = 2;
948  /*
949  * set data segments and length
950  */
951 
952  pdu->u.deliver_sm.short_message = octstr_duplicate(msg->sms.msgdata);
953 
954  }
955 
956 
957  /*
958  * only re-encoding if using default smsc charset that is defined via
959  * alt-charset in smsc group and if MT is not binary
960  */
961  if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata))) {
962  /*
963  * consider 3 cases:
964  * a) data_coding 0xFX: encoding should always be GSM 03.38 charset
965  * b) data_coding 0x00: encoding may be converted according to alt-charset
966  * c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
967  */
968  if ((pdu->u.deliver_sm.data_coding & 0xF0) ||
969  (!box->alt_charset && pdu->u.deliver_sm.data_coding == 0)) {
970  charset_utf8_to_gsm(pdu->u.deliver_sm.short_message);
971  }
972  else if (pdu->u.deliver_sm.data_coding == 0 && box->alt_charset) {
973  /*
974  * convert to the given alternative charset
975  */
976  if (charset_convert(pdu->u.deliver_sm.short_message, "UTF-8", octstr_get_cstr(box->alt_charset)) != 0)
977  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
978  octstr_get_cstr(box->alt_charset), "UTF-8");
979  pdu->u.deliver_sm.sm_length = octstr_len(pdu->u.deliver_sm.short_message);
980  }
981  }
982 
983  /* prepend udh if present */
984  if (octstr_len(msg->sms.udhdata)) {
985  octstr_insert(pdu->u.deliver_sm.short_message, msg->sms.udhdata, 0);
986  }
987 
988  pdu->u.deliver_sm.sm_length = octstr_len(pdu->u.deliver_sm.short_message);
989 
990  /* set priority */
991  if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
992  pdu->u.deliver_sm.priority_flag = msg->sms.priority;
993  else
994  pdu->u.deliver_sm.priority_flag = box->priority;
995 
996  /* set more messages to send */
997 /*
998  if (box->version > 0x33 && msg->sms.msg_left > 0)
999  pdu->u.deliver_sm.more_messages_to_send = 1;
1000 */
1001 
1002  header = NULL;
1003  footer = NULL;
1004  suffix = NULL;
1005  split_chars = NULL;
1006  catenate = 1;
1007  max_msgs = 255;
1008  if (catenate)
1009  msg_sequence = counter_increase(catenated_sms_counter) & 0xFF;
1010  else
1011  msg_sequence = 0;
1012 
1013  /* split sms */
1014  parts = sms_split(msg, header, footer, suffix, split_chars, catenate,
1015  msg_sequence, max_msgs, sms_max_length);
1016  msg_count = gwlist_len(parts);
1017 
1018  if ((msg_count > 1) && (box->version > 0x33)) {
1019  Octstr *use_message_payload_meta;
1020  long use_message_payload;
1021 
1022  use_message_payload_meta = meta_data_get_value(msg->sms.meta_data, "smpp", octstr_imm("use_message_payload"));
1023  use_message_payload = strtol(octstr_get_cstr(use_message_payload_meta), 0, 0);
1024 
1025  if (use_message_payload) {
1026  /* copy short message data to message_payload TLV */
1027  pdu->u.deliver_sm.message_payload = octstr_duplicate(pdu->u.deliver_sm.short_message);
1028  octstr_destroy(pdu->u.deliver_sm.short_message);
1029  pdu->u.deliver_sm.short_message = NULL;
1030  pdu->u.deliver_sm.sm_length = 0;
1031 
1032  /* pass the message as a single pdu */
1033  msg_count = 1;
1034  }
1035 
1036  octstr_destroy(use_message_payload_meta);
1037  }
1038 
1039  if (msg_count == 1) {
1040  /* don't create split_parts of sms fit into one */
1042  parts = NULL;
1043  }
1044 
1045  debug("SMPP", 0, "message length %ld, sending %ld message%s",
1046  octstr_len(msg->sms.msgdata), msg_count, msg_count == 1 ? "" : "s");
1047 
1048  if (parts) {
1049  while((msg2 = gwlist_extract_first(parts)) != NULL) {
1050  pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
1051  pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
1052  pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
1053  pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
1054  pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
1055  pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
1056  pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
1057  pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
1058  pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
1059  pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
1060 
1061  /* the following condition is currently always true */
1062  /* uncomment in case we're doing a SAR-split instead */
1063  if (/*octstr_len(msg2->sms.udhdata) > 0*/1) {
1064  pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class | ESM_CLASS_DELIVER_UDH_INDICATOR;
1065  pdu2->u.deliver_sm.short_message = octstr_cat(msg2->sms.udhdata, msg2->sms.msgdata);
1066  }
1067  else {
1068  pdu2->u.deliver_sm.short_message = octstr_duplicate(msg2->sms.msgdata);
1069  }
1070 
1071  if (box->version > 0x33) {
1072  dict_destroy(pdu2->u.deliver_sm.tlv);
1073  pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1074  }
1075 
1076  gwlist_append(pdulist, pdu2);
1077  msg_destroy(msg2);
1078  }
1079 
1080  smpp_pdu_destroy(pdu);
1081  }
1082  else {
1083  if (box->version > 0x33) {
1084  dict_destroy(pdu->u.deliver_sm.tlv);
1085  pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1086  }
1087 
1088  gwlist_append(pdulist, pdu);
1089  }
1090 
1091  return pdulist;
1092 }
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 autodetect_addr
Definition: opensmppbox.c:173
static Counter * catenated_sms_counter
Definition: opensmppbox.c:112
void gwlist_append(List *list, void *item)
Definition: list.c:179
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:814
#define DLR_IS_SUCCESS(dlr)
Definition: dlr.h:86
Definition: msg.h:109
long source_addr_ton
Definition: opensmppbox.c:171
long gwlist_len(List *list)
Definition: list.c:166
#define DLR_NOTHING
Definition: dlr.h:71
#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
#define DLR_EXPIRED
Definition: dlr.h:77
long source_addr_npi
Definition: opensmppbox.c:172
Octstr * meta_data_get_value(Octstr *data, const char *group, const Octstr *key)
Definition: meta_data.c:368
size_t gw_strftime(char *s, size_t max, const char *format, const struct tm *tm)
Definition: protected.c:164
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
int version
Definition: opensmppbox.c:149
List * sms_split(Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
Definition: sms.c:309
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
int alt_dcs
Definition: opensmppbox.c:176
#define DLR_SUCCESS
Definition: dlr.h:72
Counter * smpp_pdu_counter
Definition: opensmppbox.c:152
void msg_destroy_item(void *msg)
Definition: msg.c:147
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
Octstr * boxc_id
Definition: opensmppbox.c:160
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * alt_charset
Definition: opensmppbox.c:150
#define ESM_CLASS_DELIVER_UDH_INDICATOR
Definition: smpp_pdu.h:151
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
char * text
Definition: smsc_cimd2.c:921
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_isdigit(int c)
Definition: utils.c:988
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
#define DLR_SMSC_FAIL
Definition: dlr.h:76
int fields_to_dcs(Msg *msg, int mode)
Definition: sms.c:73
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
union SMPP_PDU::@15 u
#define DLR_UNDEFINED
Definition: dlr.h:70
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define GSM_ADDR_NPI_UNKNOWN
Definition: smasi_pdu.h:111
void dict_destroy(Dict *dict)
Definition: dict.c:215
#define MC_UNDEF
Definition: sms.h:93
int priority
Definition: opensmppbox.c:178
Definition: octstr.c:118
#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
struct tm gw_localtime(time_t t)
Definition: protected.c:121
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
Definition: octstr.c:383
#define gwlist_create()
Definition: list.h:136
#define DLR_BUFFERED
Definition: dlr.h:74
#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
long dest_addr_ton
Definition: opensmppbox.c:174
#define DLR_SMSC_SUCCESS
Definition: dlr.h:75
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1640
Definition: list.c:102
static long sms_max_length
Definition: opensmppbox.c:113
#define DLR_IS_SUCCESS_OR_FAIL(dlr)
Definition: dlr.h:85
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DLR_FAIL
Definition: dlr.h:73
long dest_addr_npi
Definition: opensmppbox.c:175
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
#define ESM_CLASS_DELIVER_SMSC_DELIVER_ACK
Definition: smpp_pdu.h:147
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ pdu_to_msg()

static Msg* pdu_to_msg ( Boxc box,
SMPP_PDU pdu,
long *  reason 
)
static

Definition at line 1100 of file opensmppbox.c.

References _boxc::alt_charset, _boxc::boxc_id, charset_convert(), charset_gsm_to_utf8(), convert_addr_from_pdu(), DC_7BIT, DC_8BIT, DC_UCS2, DC_UNDEF, dcs_to_fields(), debug(), DLR_FAIL, DLR_SMSC_FAIL, DLR_SUCCESS, error(), ESM_CLASS_SUBMIT_RPI, ESM_CLASS_SUBMIT_UDH_INDICATOR, gw_assert(), meta_data_set_values(), msg, msg_create, msg_destroy(), mt_push, octstr_copy, octstr_create, octstr_delete(), octstr_duplicate, octstr_get_char(), octstr_get_cstr, octstr_len(), report_mo, SMPP_ESME_RINVDSTADR, SMPP_ESME_RINVESMCLASS, SMPP_ESME_ROK, _boxc::sms_service, timestamp_to_minutes(), SMPP_PDU::type, SMPP_PDU::u, and _boxc::version.

Referenced by handle_pdu().

1101 {
1102  Msg *msg;
1103  int ton, npi;
1104 
1105  gw_assert(pdu->type == submit_sm);
1106 
1107  msg = msg_create(sms);
1108  gw_assert(msg != NULL);
1109  msg->sms.sms_type = mt_push;
1110  *reason = SMPP_ESME_ROK;
1111 
1112  /*
1113  * Reset source addr to have a prefixed '+' in case we have an
1114  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
1115  * between national and international numbers.
1116  */
1117  ton = pdu->u.submit_sm.source_addr_ton;
1118  npi = pdu->u.submit_sm.source_addr_npi;
1119  /* check source addr */
1120  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.submit_sm.source_addr, ton, npi)) != SMPP_ESME_ROK)
1121  goto error;
1122  msg->sms.sender = pdu->u.submit_sm.source_addr;
1123  pdu->u.submit_sm.source_addr = NULL;
1124  msg->sms.service = octstr_duplicate(box->sms_service);
1125 
1126  /*
1127  * Follows SMPP spec. v3.4. issue 1.2
1128  * it's not allowed to have destination_addr NULL
1129  */
1130  if (pdu->u.submit_sm.destination_addr == NULL) {
1131  error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
1132  "Discarding MO message.", octstr_get_cstr(box->boxc_id),
1133  octstr_get_cstr(pdu->u.submit_sm.destination_addr));
1134  *reason = SMPP_ESME_RINVDSTADR;
1135  goto error;
1136  }
1137 
1138  /* copy priority_flag into msg */
1139  if (pdu->u.submit_sm.priority_flag >= 0 && pdu->u.submit_sm.priority_flag <= 3) {
1140  msg->sms.priority = pdu->u.submit_sm.priority_flag;
1141  }
1142 
1143  /* Same reset of destination number as for source */
1144  ton = pdu->u.submit_sm.dest_addr_ton;
1145  npi = pdu->u.submit_sm.dest_addr_npi;
1146  /* check destination addr */
1147  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.submit_sm.destination_addr, ton, npi)) != SMPP_ESME_ROK)
1148  goto error;
1149  msg->sms.receiver = pdu->u.submit_sm.destination_addr;
1150  pdu->u.submit_sm.destination_addr = NULL;
1151 
1152  /* SMSCs use service_type for billing information */
1153  msg->sms.binfo = pdu->u.submit_sm.service_type;
1154  pdu->u.submit_sm.service_type = NULL;
1155 
1156  if (pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
1157  msg->sms.rpi = 1;
1158 
1159  /*
1160  * Check for message_payload if version > 0x33 and sm_length == 0
1161  * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!
1162  */
1163  if (box->version > 0x33 && pdu->u.submit_sm.sm_length == 0 && pdu->u.submit_sm.message_payload) {
1164  msg->sms.msgdata = pdu->u.submit_sm.message_payload;
1165  pdu->u.submit_sm.message_payload = NULL;
1166  }
1167  else {
1168  msg->sms.msgdata = pdu->u.submit_sm.short_message;
1169  pdu->u.submit_sm.short_message = NULL;
1170  }
1171 
1172  /*
1173  * Encode udh if udhi set
1174  * for reference see GSM03.40, section 9.2.3.24
1175  */
1176  if (pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
1177  int udhl;
1178  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
1179  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
1180  octstr_get_cstr(box->boxc_id), udhl);
1181  if (udhl > octstr_len(msg->sms.msgdata)) {
1182  error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
1183  "0x%03lx. Discarding MO message.", octstr_get_cstr(box->boxc_id),
1184  udhl, octstr_len(msg->sms.msgdata));
1185  *reason = SMPP_ESME_RINVESMCLASS;
1186  goto error;
1187  }
1188  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
1189  octstr_delete(msg->sms.msgdata, 0, udhl);
1190  }
1191 
1192  dcs_to_fields(&msg, pdu->u.submit_sm.data_coding);
1193 
1194  /* handle default data coding */
1195  switch (pdu->u.submit_sm.data_coding) {
1196  case 0x00: /* default SMSC alphabet */
1197  /*
1198  * try to convert from something interesting if specified so
1199  * unless it was specified binary, ie. UDH indicator was detected
1200  */
1201  if (box->alt_charset && msg->sms.coding != DC_8BIT) {
1202  if (charset_convert(msg->sms.msgdata, octstr_get_cstr(box->alt_charset), "UTF-8") != 0)
1203  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1204  "UTF-8", octstr_get_cstr(box->alt_charset));
1205  msg->sms.coding = DC_7BIT;
1206  } else { /* assume GSM 03.38 7-bit alphabet */
1207  charset_gsm_to_utf8(msg->sms.msgdata);
1208  msg->sms.coding = DC_7BIT;
1209  }
1210  break;
1211  case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
1212  case 0x03: /* ISO-8859-1 - do nothing */
1213  msg->sms.coding = DC_7BIT; break;
1214  case 0x02: /* 8 bit binary - do nothing */
1215  case 0x04: /* 8 bit binary - do nothing */
1216  msg->sms.coding = DC_8BIT; break;
1217  case 0x05: /* JIS - what do I do with that ? */
1218  break;
1219  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
1220  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UCS-2BE") != 0)
1221  error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1222  msg->sms.coding = DC_UCS2; break;
1223  case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
1224  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)
1225  error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1226  msg->sms.coding = DC_UCS2; break;
1227  case 0x08: /* unicode UCS-2, yey */
1228  msg->sms.coding = DC_UCS2; break;
1229 
1230  /*
1231  * don't much care about the others,
1232  * you implement them if you feel like it
1233  */
1234 
1235  default:
1236  /*
1237  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
1238  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
1239  * if we have an UDH indicator, we assume DC_8BIT.
1240  */
1241  if (msg->sms.coding == DC_UNDEF && pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
1242  msg->sms.coding = DC_8BIT;
1243  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
1244  msg->sms.coding = DC_7BIT;
1245  charset_gsm_to_utf8(msg->sms.msgdata);
1246  }
1247  }
1248  msg->sms.pid = pdu->u.submit_sm.protocol_id;
1249 
1250  /* set priority flag */
1251  msg->sms.priority = pdu->u.submit_sm.priority_flag;
1252 
1253  /* ask for the delivery reports if needed */
1254  switch (pdu->u.submit_sm.registered_delivery & 0x03) {
1255  case 1:
1256  msg->sms.dlr_mask = (DLR_SUCCESS | DLR_FAIL | DLR_SMSC_FAIL);
1257  break;
1258  case 2:
1259  msg->sms.dlr_mask = (DLR_FAIL | DLR_SMSC_FAIL);
1260  break;
1261  default:
1262  msg->sms.dlr_mask = 0;
1263  break;
1264  }
1265  if (pdu->u.submit_sm.esm_class & (0x04|0x08)) {
1266  msg->sms.sms_type = report_mo;
1267  }
1268 
1269  if (box->version > 0x33) {
1270  if (msg->sms.meta_data == NULL)
1271  msg->sms.meta_data = octstr_create("");
1272  meta_data_set_values(msg->sms.meta_data, pdu->u.submit_sm.tlv, "smpp", 1);
1273  }
1274 
1275  msg->sms.time = time(NULL);
1276 
1277  /* set validity period if needed */
1278  if (pdu->u.submit_sm.validity_period) {
1279  msg->sms.validity = time(NULL) + timestamp_to_minutes(pdu->u.submit_sm.validity_period) * 60;
1280  }
1281 
1282 
1283  /* set schedule delivery time if needed */
1284  if (pdu->u.submit_sm.schedule_delivery_time) {
1285  msg->sms.deferred = time(NULL) + timestamp_to_minutes(pdu->u.submit_sm.schedule_delivery_time) * 60;
1286  }
1287 
1288  return msg;
1289 
1290 error:
1291  msg_destroy(msg);
1292  return NULL;
1293 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static int timestamp_to_minutes(Octstr *timestamp)
Definition: opensmppbox.c:362
gw_assert(wtls_machine->packet_to_send !=NULL)
Definition: msg.h:109
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
unsigned long type
Definition: smpp_pdu.h:91
#define DC_8BIT
Definition: sms.h:111
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int version
Definition: opensmppbox.c:149
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
#define DLR_SUCCESS
Definition: dlr.h:72
Definition: msg.h:108
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
Octstr * alt_charset
Definition: opensmppbox.c:150
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void msg_destroy(Msg *msg)
Definition: msg.c:132
#define octstr_create(cstr)
Definition: octstr.h:125
#define DLR_SMSC_FAIL
Definition: dlr.h:76
union SMPP_PDU::@15 u
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi)
Definition: opensmppbox.c:558
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Octstr * sms_service
Definition: opensmppbox.c:161
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
#define DC_UNDEF
Definition: sms.h:109
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DLR_FAIL
Definition: dlr.h:73
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273
#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

◆ read_from_box()

static Msg* read_from_box ( Connection conn,
Boxc boxconn 
)
static

Definition at line 499 of file opensmppbox.c.

References _boxc::alive, msg, and read_from_bearerbox_real().

Referenced by bearerbox_to_smpp().

500 {
501  Octstr *pack;
502  Msg *msg;
503 
504  pack = NULL;
505  while (boxconn->alive) {
506  switch (read_from_bearerbox_real(conn, &msg, 1.0)) {
507  case -1:
508  /* connection to bearerbox lost */
509  return NULL;
510  break;
511  case 0:
512  /* all is well */
513  return msg;
514  break;
515  case 1:
516  /* timeout */
517  break;
518  }
519  }
520 
521  return msg;
522 }
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
Definition: shared.c:172
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
Definition: msg.h:79
Definition: octstr.c:118
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ read_pdu()

static int read_pdu ( Boxc box,
Connection conn,
long *  len,
SMPP_PDU **  pdu 
)
static

Definition at line 658 of file opensmppbox.c.

References _boxc::boxc_id, conn_eof(), conn_error(), debug(), error(), octstr_destroy(), octstr_get_cstr, smpp_pdu_read_data(), smpp_pdu_read_len(), and smpp_pdu_unpack().

Referenced by smpp_to_bearerbox().

659 {
660  Octstr *os;
661 
662  if (*len == 0) {
663  *len = smpp_pdu_read_len(conn);
664  if (*len == -1) {
665  error(0, "opensmppbox[%s]: Server sent garbage, ignored.",
666  octstr_get_cstr(box->boxc_id));
667  return -1;
668  } else if (*len == 0) {
669  if (conn_eof(conn) || conn_error(conn))
670  return -1;
671  return 0;
672  }
673  }
674 
675  os = smpp_pdu_read_data(conn, *len);
676  if (os == NULL) {
677  if (conn_eof(conn) || conn_error(conn))
678  return -1;
679  return 0;
680  }
681  *len = 0;
682 
683  *pdu = smpp_pdu_unpack(box->boxc_id, os);
684  if (*pdu == NULL) {
685  error(0, "opensmppbox[%s]: PDU unpacking failed.",
686  octstr_get_cstr(box->boxc_id));
687  debug("bb.sms.smpp", 0, "opensmppbox[%s]: Failed PDU omitted.",
688  octstr_get_cstr(box->boxc_id));
689  /* octstr_dump(os, 0); */
690  octstr_destroy(os);
691  return -1;
692  }
693 
694  octstr_destroy(os);
695  return 1;
696 }
void error(int err, const char *fmt,...)
Definition: log.c:648
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:869
int conn_eof(Connection *conn)
Definition: conn.c:705
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * boxc_id
Definition: opensmppbox.c:160
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
Definition: smpp_pdu.c:597
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr * smpp_pdu_read_data(Connection *conn, long len)
Definition: smpp_pdu.c:895
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int conn_error(Connection *conn)
Definition: conn.c:716

◆ run_smppbox()

static void run_smppbox ( void *  arg)
static

Definition at line 2113 of file opensmppbox.c.

References accept_smpp(), all_boxes, _boxc::bearerbox_connection, bearerbox_host, bearerbox_port, bearerbox_port_ssl, bearerbox_to_smpp(), boxc_destroy(), _boxc::boxc_id, _boxc::client_ip, connect_to_bearerbox_real(), DEFAULT_HEARTBEAT, error(), gwlist_append(), gwlist_delete_equal(), gwthread_create, gwthread_join(), heartbeat_start(), info(), octstr_duplicate, octstr_get_cstr, outstanding_requests(), panic, smpp_to_bearerbox(), and smppbox_id.

Referenced by smppboxc_run().

2114 {
2115  int fd;
2116  Boxc *newconn;
2117  long sender;
2118 
2119  fd = (int)arg;
2120  newconn = accept_smpp(fd, 0);
2121  if (newconn == NULL) {
2122  panic(0, "Socket accept failed");
2123  return;
2124  }
2125  newconn->boxc_id = octstr_duplicate(smppbox_id);
2127  /* XXX add our_host if required */
2128  if (newconn->bearerbox_connection == NULL) {
2129  error(0, "opensmppbox: Failed to connect to bearerbox." );
2130  boxc_destroy(newconn);
2131  return;
2132  }
2133 
2134  gwlist_append(all_boxes, newconn);
2135 
2136 #ifdef DO_HEARTBEATS
2137  /* we dont do heartbeats for now */
2138  if (0 > heartbeat_start(write_to_bearerboxes, DEFAULT_HEARTBEAT,
2140  info(0, "OpenSMPPBox: Could not start heartbeat.");
2141  }
2142 #endif
2143 
2144  sender = gwthread_create(smpp_to_bearerbox, newconn);
2145  if (sender == -1) {
2146  error(0, "Failed to start a new thread, disconnecting client <%s>",
2147  octstr_get_cstr(newconn->client_ip));
2148  boxc_destroy(newconn);
2149  return;
2150  }
2151  bearerbox_to_smpp(newconn);
2152  gwthread_join(sender);
2153  gwlist_delete_equal(all_boxes, newconn);
2154  boxc_destroy(newconn);
2155 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static Octstr * smppbox_id
Definition: opensmppbox.c:125
Connection * connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:83
static List * all_boxes
Definition: opensmppbox.c:110
void gwlist_append(List *list, void *item)
Definition: list.c:179
Octstr * client_ip
Definition: opensmppbox.c:153
void gwthread_join(long thread)
static long outstanding_requests(void)
Definition: smsbox.c:515
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static int bearerbox_port_ssl
Definition: opensmppbox.c:106
Connection * bearerbox_connection
Definition: opensmppbox.c:143
Octstr * boxc_id
Definition: opensmppbox.c:160
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Boxc * accept_smpp(int fd, int ssl)
Definition: opensmppbox.c:1841
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static void smpp_to_bearerbox(void *arg)
Definition: opensmppbox.c:1877
static long bearerbox_port
Definition: opensmppbox.c:104
#define DEFAULT_HEARTBEAT
Definition: heartbeat.h:67
long heartbeat_start(hb_send_func_t *send_func, double freq, hb_load_func_t *load_func)
Definition: heartbeat.c:126
#define panic
Definition: log.h:87
static void bearerbox_to_smpp(void *arg)
Definition: opensmppbox.c:1928
static void boxc_destroy(Boxc *boxc)
Definition: opensmppbox.c:1769
static Octstr * bearerbox_host
Definition: opensmppbox.c:105

◆ send_msg()

static int send_msg ( Connection conn,
Boxc boxconn,
Msg pmsg 
)
static

Definition at line 453 of file opensmppbox.c.

References write_to_bearerbox_real().

Referenced by bearerbox_to_smpp(), handle_pdu(), and identify_to_bearerbox().

454 {
455  /* Caution: implicit msg_destroy */
456  write_to_bearerbox_real(conn, pmsg);
457  return 0;
458 }
void write_to_bearerbox_real(Connection *conn, Msg *pmsg)
Definition: shared.c:129

◆ send_pdu()

static int send_pdu ( Connection conn,
Octstr id,
SMPP_PDU pdu 
)
static

Definition at line 620 of file opensmppbox.c.

References conn_write(), dump_pdu, octstr_destroy(), and smpp_pdu_pack().

Referenced by bearerbox_to_smpp(), and handle_pdu().

621 {
622  Octstr *os;
623  int ret;
624 
625  dump_pdu("Sending PDU:", id, pdu);
626  os = smpp_pdu_pack(id, pdu);
627  if (os) {
628  ret = conn_write(conn, os); /* Caller checks for write errors later */
629  octstr_destroy(os);
630  }
631  else {
632  ret = -1;
633  }
634  return ret;
635 }
#define dump_pdu(msg, id, pdu)
Definition: opensmppbox.c:347
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118

◆ setup_signal_handlers()

static void setup_signal_handlers ( void  )
static

Definition at line 2256 of file opensmppbox.c.

References signal_handler().

Referenced by main().

2256  {
2257  struct sigaction act;
2258 
2259  act.sa_handler = signal_handler;
2260  sigemptyset(&act.sa_mask);
2261  act.sa_flags = 0;
2262  sigaction(SIGINT, &act, NULL);
2263  sigaction(SIGQUIT, &act, NULL);
2264  sigaction(SIGHUP, &act, NULL);
2265  sigaction(SIGPIPE, &act, NULL);
2266 }
static void signal_handler(int signum)
Definition: opensmppbox.c:2220

◆ signal_handler()

static void signal_handler ( int  signum)
static

Definition at line 2220 of file opensmppbox.c.

References alog_reopen(), error(), gwthread_shouldhandlesignal(), log_reopen(), SMPP_RUNNING, SMPP_SHUTDOWN, smppbox_status, and warning().

Referenced by setup_signal_handlers().

2220  {
2221  /* On some implementations (i.e. linuxthreads), signals are delivered
2222  * to all threads. We only want to handle each signal once for the
2223  * entire box, and we let the gwthread wrapper take care of choosing
2224  * one.
2225  */
2226  if (!gwthread_shouldhandlesignal(signum))
2227  return;
2228 
2229  switch (signum) {
2230  case SIGINT:
2231 
2232  if (smppbox_status == SMPP_RUNNING) {
2233  error(0, "SIGINT received, aborting program...");
2235  }
2236  break;
2237 
2238  case SIGHUP:
2239  warning(0, "SIGHUP received, catching and re-opening logs");
2240  log_reopen();
2241  alog_reopen();
2242  break;
2243 
2244  /*
2245  * It would be more proper to use SIGUSR1 for this, but on some
2246  * platforms that's reserved by the pthread support.
2247  */
2248  case SIGQUIT:
2249  warning(0, "SIGQUIT received, reporting memory usage.");
2250  gw_check_leaks();
2251  break;
2252  }
2253 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
void log_reopen(void)
Definition: log.c:297
int gwthread_shouldhandlesignal(int signal)
#define SMPP_SHUTDOWN
Definition: opensmppbox.c:100
void warning(int err, const char *fmt,...)
Definition: log.c:660
void alog_reopen(void)
Definition: accesslog.c:85
#define SMPP_RUNNING
Definition: opensmppbox.c:101

◆ smpp_pdu_destroy_item()

void smpp_pdu_destroy_item ( void *  pdu)

Definition at line 184 of file opensmppbox.c.

References smpp_pdu_destroy().

Referenced by boxc_create().

185 {
186  smpp_pdu_destroy(pdu);
187 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434

◆ smpp_to_bearerbox()

static void smpp_to_bearerbox ( void *  arg)
static

Definition at line 1877 of file opensmppbox.c.

References _boxc::alive, _boxc::bearerbox_connection, error(), gwthread_sleep(), handle_pdu(), _boxc::last_pdu_received, read_pdu(), _boxc::smpp_connection, SMPP_RUNNING, smpp_timeout, and smppbox_status.

Referenced by run_smppbox().

1878 {
1879  Boxc *box = arg;
1880  Connection *conn = box->smpp_connection;
1881  SMPP_PDU *pdu;
1882  long len;
1883 
1884  box->last_pdu_received = time(NULL);
1885  len = 0;
1886  while (smppbox_status == SMPP_RUNNING && box->alive) {
1887  switch (read_pdu(box, conn, &len, &pdu)) {
1888  case -1:
1889  error(0, "Invalid SMPP PDU received.");
1890  box->alive = 0;
1891  break;
1892  case 0:
1893  // idling
1894  if (time(NULL) - box->last_pdu_received > smpp_timeout) {
1895  box->alive = 0;
1896  }
1897  gwthread_sleep(1);
1898  break;
1899  case 1:
1900  box->last_pdu_received = time(NULL);
1901  handle_pdu(conn, box, pdu);
1902  break;
1903  }
1904  }
1905 #ifdef HAVE_SHUTDOWN_CONNECTION
1906  shutdown_connection(box->bearerbox_connection);
1907 #endif
1908 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
Connection * bearerbox_connection
Definition: opensmppbox.c:143
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
static void handle_pdu(Connection *conn, Boxc *box, SMPP_PDU *pdu)
Definition: opensmppbox.c:1510
void gwthread_sleep(double seconds)
Connection * smpp_connection
Definition: opensmppbox.c:142
static time_t smpp_timeout
Definition: opensmppbox.c:128
static int read_pdu(Boxc *box, Connection *conn, long *len, SMPP_PDU **pdu)
Definition: opensmppbox.c:658
#define SMPP_RUNNING
Definition: opensmppbox.c:101
time_t last_pdu_received
Definition: opensmppbox.c:165

◆ smppbox_is_allowed_in_group()

static int smppbox_is_allowed_in_group ( Octstr group,
Octstr variable 
)
static

Definition at line 2575 of file opensmppbox.c.

References octstr_imm().

Referenced by main().

2576 {
2577  Octstr *groupstr;
2578 
2579  groupstr = octstr_imm("group");
2580 
2581  #define OCTSTR(name) \
2582  if (octstr_compare(octstr_imm(#name), variable) == 0) \
2583  return 1;
2584  #define SINGLE_GROUP(name, fields) \
2585  if (octstr_compare(octstr_imm(#name), group) == 0) { \
2586  if (octstr_compare(groupstr, variable) == 0) \
2587  return 1; \
2588  fields \
2589  return 0; \
2590  }
2591  #define MULTI_GROUP(name, fields) \
2592  if (octstr_compare(octstr_imm(#name), group) == 0) { \
2593  if (octstr_compare(groupstr, variable) == 0) \
2594  return 1; \
2595  fields \
2596  return 0; \
2597  }
2598  #include "opensmppbox-cfg.def"
2599 
2600  return 0;
2601 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: octstr.c:118

◆ smppbox_is_single_group()

static int smppbox_is_single_group ( Octstr query)
static

Definition at line 2607 of file opensmppbox.c.

Referenced by main().

2608 {
2609  #define OCTSTR(name)
2610  #define SINGLE_GROUP(name, fields) \
2611  if (octstr_compare(octstr_imm(#name), query) == 0) \
2612  return 1;
2613  #define MULTI_GROUP(name, fields) \
2614  if (octstr_compare(octstr_imm(#name), query) == 0) \
2615  return 0;
2616  #include "opensmppbox-cfg.def"
2617  return 0;
2618 }

◆ smppboxc_run()

static void smppboxc_run ( void *  arg)
static

Definition at line 2186 of file opensmppbox.c.

References info(), make_server_socket(), panic, port, run_smppbox(), and wait_for_connections().

Referenced by main().

2187 {
2188  int fd;
2189  int port;
2190 
2191  port = (int)arg;
2192 
2193  fd = make_server_socket(port, NULL);
2194  /* XXX add interface_name if required */
2195 
2196  if (fd < 0) {
2197  panic(0, "Could not open opensmppbox port %d", port);
2198  }
2199 
2200  /*
2201  * infinitely wait for new connections;
2202  * to shut down the system, SIGTERM is send and then
2203  * select drops with error, so we can check the status
2204  */
2205 
2206  info(0, "Waiting for SMPP connections on port %d.", port);
2207  wait_for_connections(fd, run_smppbox, NULL);
2208  info(0, "No more waiting for SMPP connections.");
2209 
2210  /* close listen socket */
2211  close(fd);
2212 }
void info(int err, const char *fmt,...)
Definition: log.c:672
Definition: http.c:2014
static void run_smppbox(void *arg)
Definition: opensmppbox.c:2113
static int port
Definition: fakesmsc.c:121
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited)
Definition: opensmppbox.c:2157
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
#define panic
Definition: log.h:87

◆ timestamp_to_minutes()

static int timestamp_to_minutes ( Octstr timestamp)
static

Definition at line 362 of file opensmppbox.c.

References debug(), gw_gmtime(), gw_localtime(), gw_mktime(), octstr_get_cstr, and octstr_len().

Referenced by pdu_to_msg().

363 {
364  struct tm tm, local;
365  time_t valutc, utc;
366  int rc, diff, dummy, localdiff;
367  char relation;
368 
369  if (octstr_len(timestamp) == 0)
370  return 0;
371 
372  if (octstr_len(timestamp) != 16)
373  return -1;
374 
375  /*
376  * Timestamp format:
377  * YYMMDDhhmmsstnn[+-R]
378  * t - tenths of second (not used by us)
379  * nn - Time difference in quarter hours between local and UTC time
380  */
381  rc = sscanf(octstr_get_cstr(timestamp),
382  "%02d%02d%02d%02d%02d%02d%1d%02d%1c",
383  &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
384  &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
385  &dummy, &diff, &relation);
386  if (rc != 9)
387  return -1;
388 
389  utc = time(NULL);
390  if (utc == ((time_t)-1))
391  return 0;
392 
393  if (relation == '+' || relation == '-') {
394  tm.tm_year += 100; /* number of years since 1900 */
395  tm.tm_mon--; /* month 0-11 */
396  tm.tm_isdst = -1;
397  /* convert to sec. since 1970 */
398  valutc = gw_mktime(&tm);
399  if (valutc == ((time_t)-1))
400  return -1;
401 
402  /* work out local time, because gw_mktime assume local time */
403  local = gw_localtime(utc);
404  tm = gw_gmtime(utc);
405  local.tm_isdst = tm.tm_isdst = -1;
406  localdiff = difftime(gw_mktime(&local), gw_mktime(&tm));
407  valutc += localdiff;
408 
409  debug("sms.smpp",0, "diff between utc and localtime (%d)", localdiff);
410  diff = diff*15*60;
411  switch(relation) {
412  case '+':
413  valutc -= diff;
414  break;
415  case '-':
416  valutc += diff;
417  break;
418  }
419  } else if (relation == 'R') { /* relative to SMSC localtime */
420  local = gw_localtime(utc);
421  local.tm_year += tm.tm_year;
422  local.tm_mon += tm.tm_mon;
423  local.tm_mday += tm.tm_mday;
424  local.tm_hour += tm.tm_hour;
425  local.tm_min += tm.tm_min;
426  local.tm_sec += tm.tm_sec;
427  valutc = gw_mktime(&local);
428  if (valutc == ((time_t)-1))
429  return -1;
430  } else {
431  return -1;
432  }
433  tm = gw_gmtime(valutc);
434  debug("sms.smpp",0,"Requested UTC timestamp: %02d-%02d-%02d %02d:%02d:%02d",
435  tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
436 
437  debug("sms.smpp", 0, "requested timestamp in min. (%ld)", (valutc - utc)/60);
438 
439  return ceil ( difftime (valutc, utc) / 60 );
440 }
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
time_t gw_mktime(struct tm *tm)
Definition: protected.c:153
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
struct tm gw_localtime(time_t t)
Definition: protected.c:121

◆ wait_for_connections()

static void wait_for_connections ( int  fd,
void(*)(void *arg)  function,
List waited 
)
static

Definition at line 2157 of file opensmppbox.c.

References error(), gw_assert(), gwthread_create, gwthread_pollfd(), gwthread_sleep(), POLLIN, SMPP_RUNNING, SMPP_SHUTDOWN, and smppbox_status.

Referenced by smppboxc_run().

2159 {
2160  int ret = 0;
2161  int timeout = 10; /* 10 sec. */
2162 
2163  gw_assert(function != NULL);
2164 
2165  while(smppbox_status == SMPP_RUNNING) {
2166 
2167  ret = gwthread_pollfd(fd, POLLIN, 1.0);
2168  if (smppbox_status == SMPP_SHUTDOWN) {
2169  if (ret == -1 || !timeout)
2170  break;
2171  else
2172  timeout--;
2173  }
2174 
2175  if (ret > 0) {
2176  gwthread_create(function, (void *)fd);
2177  gwthread_sleep(1.0);
2178  } else if (ret < 0) {
2179  if(errno==EINTR) continue;
2180  if(errno==EAGAIN) continue;
2181  error(errno, "wait_for_connections failed");
2182  }
2183  }
2184 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
gw_assert(wtls_machine->packet_to_send !=NULL)
#define SMPP_SHUTDOWN
Definition: opensmppbox.c:100
#define POLLIN
Definition: gwpoll.h:91
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void gwthread_sleep(double seconds)
int gwthread_pollfd(int fd, int events, double timeout)
#define SMPP_RUNNING
Definition: opensmppbox.c:101

Variable Documentation

◆ all_boxes

List* all_boxes
static

Definition at line 110 of file opensmppbox.c.

Referenced by check_login(), find_receiver_box(), main(), and run_smppbox().

◆ alt_charset

◆ bearerbox_host

Octstr* bearerbox_host
static

Definition at line 105 of file opensmppbox.c.

Referenced by init_smppbox(), and run_smppbox().

◆ bearerbox_port

long bearerbox_port
static

Definition at line 104 of file opensmppbox.c.

Referenced by init_smppbox(), and run_smppbox().

◆ bearerbox_port_ssl

int bearerbox_port_ssl = 0
static

Definition at line 106 of file opensmppbox.c.

Referenced by init_smppbox(), and run_smppbox().

◆ boxid

Counter* boxid
static

Definition at line 108 of file opensmppbox.c.

Referenced by boxc_create(), init_smppbox(), and main().

◆ catenated_sms_counter

Counter* catenated_sms_counter
static

Definition at line 112 of file opensmppbox.c.

Referenced by init_smppbox(), main(), and msg_to_pdu().

◆ cfg

◆ disable_multipart_catenation

int disable_multipart_catenation
static

Definition at line 134 of file opensmppbox.c.

Referenced by check_multipart(), and init_smppbox().

◆ enablepam

int enablepam
static

Definition at line 132 of file opensmppbox.c.

Referenced by check_login(), and init_smppbox().

◆ list_dict

Dict* list_dict
static

Definition at line 111 of file opensmppbox.c.

Referenced by check_multipart(), and main().

◆ our_system_id

Octstr* our_system_id
static

Definition at line 126 of file opensmppbox.c.

Referenced by handle_pdu(), and init_smppbox().

◆ pamacl

Octstr* pamacl
static

Definition at line 133 of file opensmppbox.c.

Referenced by check_login(), and init_smppbox().

◆ restart

int restart = 0
static

Definition at line 109 of file opensmppbox.c.

Referenced by bearerbox_to_smpp(), and main().

◆ restart_smppbox

volatile sig_atomic_t restart_smppbox = 0
static

Definition at line 97 of file opensmppbox.c.

Referenced by main().

◆ route_to_smsc

Octstr* route_to_smsc
static

Definition at line 127 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_autodetect_addr

int smpp_autodetect_addr = 0
static

Definition at line 116 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_dest_addr_npi

long smpp_dest_addr_npi = -1
static

Definition at line 118 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_dest_addr_ton

long smpp_dest_addr_ton = -1
static

Definition at line 117 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_logins

Octstr* smpp_logins
static

Definition at line 107 of file opensmppbox.c.

Referenced by check_login(), and init_smppbox().

◆ smpp_source_addr_npi

long smpp_source_addr_npi = -1
static

Definition at line 115 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_source_addr_ton

long smpp_source_addr_ton = -1
static

Definition at line 114 of file opensmppbox.c.

Referenced by boxc_create(), and init_smppbox().

◆ smpp_timeout

time_t smpp_timeout
static

Definition at line 128 of file opensmppbox.c.

Referenced by init_smppbox(), and smpp_to_bearerbox().

◆ smppbox_id

Octstr* smppbox_id
static

Definition at line 125 of file opensmppbox.c.

Referenced by init_smppbox(), and run_smppbox().

◆ smppbox_port

long smppbox_port
static

Definition at line 102 of file opensmppbox.c.

Referenced by init_smppbox(), and main().

◆ smppbox_port_ssl

int smppbox_port_ssl = 0
static

Definition at line 103 of file opensmppbox.c.

Referenced by init_smppbox().

◆ smppbox_status

volatile sig_atomic_t smppbox_status
static

◆ sms_max_length

long sms_max_length = MAX_SMS_OCTETS
static

Definition at line 113 of file opensmppbox.c.

Referenced by msg_to_pdu().

◆ smsc_by_receiver

Dict* smsc_by_receiver = NULL
static

Definition at line 120 of file opensmppbox.c.

Referenced by boxc_route_msg_to_smsc(), destroy_smsc_routes(), and init_smsc_routes().

◆ smsc_by_sender

Dict* smsc_by_sender = NULL
static

Definition at line 122 of file opensmppbox.c.

Referenced by boxc_route_msg_to_smsc(), destroy_smsc_routes(), and init_smsc_routes().

◆ smsc_by_sender_smsbox_id

Dict* smsc_by_sender_smsbox_id = NULL
static

Definition at line 123 of file opensmppbox.c.

Referenced by boxc_route_msg_to_smsc(), destroy_smsc_routes(), and init_smsc_routes().

◆ smsc_by_smsbox_id

Dict* smsc_by_smsbox_id = NULL
static

Definition at line 121 of file opensmppbox.c.

Referenced by boxc_route_msg_to_smsc(), destroy_smsc_routes(), and init_smsc_routes().

◆ systemidisboxcid

int systemidisboxcid
static

Definition at line 131 of file opensmppbox.c.

Referenced by check_login(), handle_pdu(), and init_smppbox().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.