75 #include <sys/types.h>    76 #include <sys/socket.h>    93 #define EMI2_MAX_TRN 100   144 #define PRIVDATA(conn) ((PrivData *)((conn)->data))   146 #define SLOTBUSY(conn,i) (PRIVDATA(conn)->slots[(i)].sendtime != 0)   148 #define CONNECTIONIDLE(conn)                                \   149 ((PRIVDATA(conn)->unacked == 0) &&                          \   150  (PRIVDATA(conn)->idle_timeout ?                            \   151   (PRIVDATA(conn)->last_activity_time + PRIVDATA(conn)->idle_timeout) <= time(0):0))   153 #define emi2_can_send(conn)                 \   154 ((PRIVDATA(conn)->can_write || !PRIVDATA(conn)->flowcontrol) && \   155  (PRIVDATA(conn)->unacked < PRIVDATA(conn)->window) &&      \   156  (!PRIVDATA(conn)->shutdown))   158 #define emi2_needs_keepalive(conn)                          \   159 (emi2_can_send(conn) &&                                 \   160  (PRIVDATA(conn)->keepalive > 0) &&                         \   161  (time(NULL) > (PRIVDATA(conn)->last_activity_time + PRIVDATA(conn)->keepalive)))   171     PRIVDATA(conn)->last_activity_time = time (NULL);
   189     timeout_time = time(NULL) + t;
   193         error(0, 
"EMI2[%s]: connection closed in wait_for_ack",
   198         error(0, 
"EMI2[%s]: connection error in wait_for_ack",
   212         warning(0, 
"EMI2[%s]: ignoring message %s while waiting for ack to"   218     time_left = timeout_time - time(NULL);
   219     if (time_left < 0 || privdata->shutdown)
   270     int result, alt_host, do_alt_host;
   274     int connect_error = 0;
   293     if (alt_host == 0 && connect_error) {
   294         error(0, 
"EMI2[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
   300         info(0, 
"EMI2[%s]: connecting to Primary SMSC",
   314         info(0, 
"EMI2[%s]: connecting to Alternate SMSC",
   334         error(0, 
"EMI2[%s]: opening TCP connection to %s failed",
   352             error(0, 
"EMI2[%s]: Server rejected our login",
   357         } 
else if (result == 0) {
   358             error(0, 
"EMI2[%s]: Got no reply to login attempt "   364         } 
else if (result == -1) { 
   394     for (i = 0; i < len; i++) {
   452     if (
msg->sms.pid >= 0) {
   457     if (
msg->sms.rpi == 2)
   459     else if (
msg->sms.rpi > 0)
   489     if (dcs != 0 && dcs != 4) {
   533         error(0, 
"EMI2[%s]: Message to send is longer "   534           "than 160 gsm characters",
   542     sprintf(p, 
"%02d%02d%02d%02d%02d",
   543         tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, 
   544         tm.tm_hour, tm.tm_min);
   552     sprintf(p, 
"%02d%02d%02d%02d%02d",
   553         tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, 
   554         tm.tm_hour, tm.tm_min);
   601         warning(0, 
"EMI2[%s]: Couldn't decode message text",
   605         warning(0, 
"EMI2[%s]: required field MT missing",
   623         error(0, 
"EMI2[%s]: MT == %s isn't supported for operation type 01",
   630     if (
msg->sms.sender == NULL) {
   631         warning(0, 
"EMI2[%s]: Empty sender field in received message",
   642     if (
msg->sms.receiver == NULL) {
   643         warning(0, 
"EMI2[%s]: Empty receiver field in received message",
   649     time(&
msg->sms.time);
   671         warning(0, 
"EMI2[%s]: Couldn't decode message text",
   680         error(0, 
"EMI2[%s]: Invalid XSer",
   686         error(0, 
"EMI2[%s]: Malformed emi XSer field",
   697                     error(0, 
"EMI2[%s]: Invalid UDH contents",
   699                 msg->sms.udhdata = tempstr;
   708                     error(0, 
"EMI2[%s]: Invalid DCS received",
   724                     error(0, 
"EMI2[%s] Invalid XSer 0c billing identifier <%s>",
   728                     msg->sms.binfo = tempstr;
   738                     info(0, 
"EMI2[%s]: Single shot indicator set.",
   745                 warning(0, 
"EMI2[%s]: Unsupported EMI XSer field %d",
   754         warning(0, 
"EMI2[%s]: required field MT missing",
   775         error(0, 
"EMI2[%s]: MT == %s isn't supported yet",
   782     if (
msg->sms.sender == NULL) {
   783         warning(0, 
"EMI2[%s]: Empty sender field in received message",
   794     if (
msg->sms.receiver == NULL) {
   795         warning(0, 
"EMI2[%s]: Empty receiver field in received message",
   801     if (tempstr == NULL) {
   802         warning(0, 
"EMI2[%s]: Received EMI message doesn't have required timestamp",
   807         warning(0, 
"EMI2[%s]: EMI SCTS field must have length 12, now %ld",
   822         error(0, 
"EMI2[%s]: EMI delivery time stamp looks malformed",
   825         time(&
msg->sms.time);
   828         unitime.
year += 2000; 
   908         return (st_code < 0 ? -1 : 1);
   911     error(0, 
"EMI2[%s]: I don't know how to handle operation type %d", 
   924     debug(
"smsc.emi2", 0, 
"EMI2[%s]: clear_sent called",
   962 #define INC_TRN(x) ((x)=((x) + 1) % EMI2_MAX_TRN)   968     result = 
PRIVDATA(conn)->priv_nexttrn;
   985         PRIVDATA(conn)->slots[nexttrn].sendtype= 31;
   986         PRIVDATA(conn)->slots[nexttrn].sendtime = time(NULL);
  1028         PRIVDATA(conn)->slots[nexttrn].sendtype = 51;
  1029         PRIVDATA(conn)->slots[nexttrn].sendtime = time(NULL);
  1061     debug(
"smsc.emi2", 0, 
"EMI2[%s]: Got packet from the main socket",
  1081         info(0, 
"EMI2[%s]: Ignoring operation from main socket "  1082              "because the connection is stopped.",
  1088         error(0, 
"EMI2[%s]: Got ack for TRN %d, don't remember sending O?",
  1113                     info(0,
"EMI2[%s]: uhhh m is NULL, very bad",
  1165             panic(0, 
"EMI2[%s]: Bug, ACK handler missing for sent packet",
  1174     error(0, 
"EMI2[%s]: Error trying to read ACKs from SMSC",
  1180     info(0, 
"EMI2[%s]: Main connection closed by SMSC",
  1190     time_t current_time;
  1198     current_time = time(NULL);
  1200     if (
PRIVDATA(conn)->unacked && (current_time > (
PRIVDATA(conn)->check_time + 30))) {
  1201     PRIVDATA(conn)->check_time = current_time;
  1202         for (i = 0; i < 
PRIVDATA(conn)->window; i++) {
  1204         && 
PRIVDATA(conn)->slots[i].sendtime < (current_time - 
PRIVDATA(conn)->waitack)) {
  1206                 if (
PRIVDATA(conn)->slots[i].sendtype == 51) {
  1207                     if (
PRIVDATA(conn)->waitack_expire == 0x00) {
  1209                         warning(0, 
"EMI2[%s]: received neither ACK nor NACK for message %d "  1210                             "in %d seconds, disconnecting and reconnection",
  1212         PRIVDATA(conn)->slots[i].sendtime = 0;
  1214                         info(0, 
"EMI2[%s]: closing connection.",
  1219                     } 
else if (
PRIVDATA(conn)->waitack_expire == 0x01) {
  1221             warning(0, 
"EMI2[%s]: received neither ACK nor NACK for message %d "   1226                         PRIVDATA(conn)->slots[i].sendtime = 0;
  1232                     } 
else if (
PRIVDATA(conn)->waitack_expire == 0x02) {
  1234                            warning(0, 
"EMI2[%s]: received neither ACK nor NACK for message %d "  1238         } 
else if (
PRIVDATA(conn)->slots[i].sendtype == 31) {
  1239             warning(0, 
"EMI2[%s]: Alert (operation 31) was not "  1244             panic(0, 
"EMI2[%s]: Bug, no timeout handler for sent packet",
  1260     info(0, 
"EMI2[%s]: closing idle connection.",
  1272     double ka_timeouttime = 
PRIVDATA(conn)->keepalive ? 
PRIVDATA(conn)->keepalive + 1 : DBL_MAX;
  1273     double idle_timeouttime = (
PRIVDATA(conn)->idle_timeout && 
server) ? 
PRIVDATA(conn)->idle_timeout : DBL_MAX;
  1274     double result = ka_timeouttime < idle_timeouttime ? ka_timeouttime : idle_timeouttime;
  1276     if (result == DBL_MAX)
  1343         warning(0, 
"EMI2[%s]: Error reading from the main connection",
  1349         info(0, 
"EMI2[%s]: Main connection closed by SMSC",
  1390     debug(
"bb.sms", 0, 
"EMI2[%s]: connection has completed shutdown.",
  1420         info(0, 
"EMI2[%s]: receive connection closed by SMSC",
  1425         error(0, 
"EMI2[%s]: receive connection broken",
  1434         debug(
"smsc.emi2", 0, 
"EMI2[%s]: Got packet from the receive connection.",
  1444             error(0, 
"EMI2[%s]: No ACKs expected on receive connection!",
  1464     error(0, 
"EMI2[%s]: could not create listening socket in port %d",
  1469     error(0, 
"EMI2[%s]: couldn't make listening socket port %d "  1483     struct sockaddr_in server_addr;
  1501         server_addr_len = 
sizeof(server_addr);
  1506             error(0, 
"EMI2[%s]: Poll for emi2 smsc connections failed, shutting down",
  1517             warning(errno, 
"EMI2[%s]: emi2_listener: accept() failed, retrying...",
  1523             info(0, 
"EMI2[%s]: smsc connection tried from denied host <%s>,"  1532             error(0, 
"EMI2[%s]: emi2_listener: conn_wrap_fd failed on accept()ed fd",
  1539         info(0, 
"EMI2[%s]: smsc connected from %s",
  1554         warning(errno, 
"EMI2[%s]: couldn't close listening socket at shutdown",
  1580     debug(
"bb.sms", 0, 
"EMI2[%s]: Shutting down SMSCConn EMI2, %s",
  1582           finish_sending ? 
"slow" : 
"instant");
  1590     if (finish_sending == 0) {
  1610     debug(
"smsc.emi2", 0, 
"EMI2[%s]: start called",
  1633     long portno, 
our_port, keepalive, flowcontrol, waitack, 
  1634          idle_timeout, alt_portno, 
alt_charset, waitack_expire;
  1657         error(0, 
"EMI2[%s]: 'port' missing/invalid in emi2 configuration.",
  1715         error(0, 
"EMI2[-]: 'receive-port' missing/invalid in emi2 configuration, "  1716                  "while no 'host' and 'port' defined.");
  1748         error(0, 
"EMI2[%s]: 'flow-control' invalid in emi2 configuration.",
  1758         warning(0, 
"EMI2[%s]: Value of 'window' should be lesser or equal to %d..",
  1768         error(0, 
"EMI2[%s]: 'wait-ack' invalid in emi2 configuration.",
  1778         error(0, 
"EMI2[%s]: 'wait-ack-expire' invalid in emi2 configuration.",
  1784         error(0, 
"EMI2[%s]: 'receive-port' missing/invalid in emi2 configuration.",
  1842     error(0, 
"EMI2[%s]: Failed to create emi2 smsc connection",
 
static int emi2_next_trn(SMSCConn *conn)
 
void error(int err, const char *fmt,...)
 
static struct emimsg * make_emi60(PrivData *privdata)
 
void info(int err, const char *fmt,...)
 
Msg * msg_duplicate(Msg *msg)
 
void bb_smscconn_connected(SMSCConn *conn)
 
int socket_set_blocking(int fd, int blocking)
 
Msg * sendmsg[CGW_TRN_MAX]
 
time_t last_activity_time
 
int emimsg_send(Connection *conn, struct emimsg *emimsg, Octstr *whoami)
 
static double emi2_get_timeouttime(SMSCConn *conn, Connection *server)
 
static int emi2_do_send(SMSCConn *conn, Connection *server)
 
void bb_smscconn_killed(void)
 
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
 
static Connection * open_send_connection(SMSCConn *conn)
 
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
 
void emimsg_destroy(struct emimsg *emimsg)
 
static EMI2Event emi2_wait(SMSCConn *conn, Connection *server, double seconds)
 
void gwthread_join(long thread)
 
#define SLOTBUSY(conn, i)
 
void octstr_append_char(Octstr *ostr, int ch)
 
void charset_utf8_to_gsm(Octstr *ostr)
 
int smsc_emi2_create(SMSCConn *conn, CfgGroup *cfg)
 
#define cfg_get(grp, varname)
 
struct emimsg * emimsg_create_op(int ot, int trn, Octstr *whoami)
 
#define gw_prioqueue_produce(queue, item)
 
void charset_nrc_iso_21_german_to_gsm(Octstr *ostr)
 
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
 
int conn_eof(Connection *conn)
 
static int emi2_handle_smscreq(SMSCConn *conn, Connection *server)
 
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
 
struct emimsg * get_fields(Octstr *message, Octstr *whoami)
 
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
 
#define octstr_get_cstr(ostr)
 
#define octstr_copy(ostr, from, len)
 
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
 
void(* start_conn)(SMSCConn *conn)
 
long octstr_search_char(const Octstr *ostr, int ch, long pos)
 
void log_thread_to(int idx)
 
static struct emimsg * make_emi31(PrivData *privdata, int trn)
 
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
 
static void clear_sent(PrivData *privdata)
 
static void emi2_receiver(SMSCConn *conn, Connection *server)
 
static int shutdown_cb(SMSCConn *conn, int finish_sending)
 
smscconn_killed_t why_killed
 
static void emi2_sender(void *arg)
 
static int emi2_keepalive_handling(SMSCConn *conn, Connection *server)
 
struct privdata::@23 slots[EMI2_MAX_TRN]
 
void conn_claim(Connection *conn)
 
static struct emimsg * msg_to_emimsg(Msg *msg, int trn, PrivData *privdata)
 
Octstr * octstr_imm(const char *cstr)
 
int sms_priority_compare(const void *a, const void *b)
 
static int emi2_open_listening_socket(SMSCConn *conn, PrivData *privdata)
 
Octstr * conn_read_packet(Connection *conn, int startmark, int endmark)
 
void octstr_delete(Octstr *ostr1, long pos, long len)
 
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
 
#define emi2_needs_keepalive(conn)
 
void conn_destroy(Connection *conn)
 
#define emi2_can_send(conn)
 
#define octstr_duplicate(ostr)
 
struct emimsg * emimsg_create_reply(int ot, int trn, int positive, Octstr *whoami)
 
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
 
int make_server_socket(int port, const char *interface_name)
 
void warning(int err, const char *fmt,...)
 
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
 
Octstr * octstr_format(const char *fmt,...)
 
long gw_prioqueue_len(gw_prioqueue_t *queue)
 
void octstr_destroy(Octstr *ostr)
 
#define gwthread_create(func, arg)
 
#define octstr_create(cstr)
 
static void pack_7bit(Octstr *str)
 
int fields_to_dcs(Msg *msg, int mode)
 
gw_prioqueue_t * gw_prioqueue_create(int(*cmp)(const void *, const void *))
 
void gwthread_sleep(double seconds)
 
#define SMS_PARAM_UNDEFINED
 
volatile sig_atomic_t is_stopped
 
static int add_msg_cb(SMSCConn *conn, Msg *sms)
 
int gwthread_pollfd(int fd, int events, double timeout)
 
#define DLR_IS_BUFFERED(dlr)
 
long octstr_len(const Octstr *ostr)
 
void octstr_append_decimal(Octstr *ostr, long value)
 
void gw_prioqueue_destroy(gw_prioqueue_t *queue, void(*item_destroy)(void *))
 
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
 
int conn_wait(Connection *conn, double seconds)
 
int(* shutdown)(SMSCConn *conn, int finish_sending)
 
Octstr * host_ip(struct sockaddr_in addr)
 
static int wait_for_ack(PrivData *privdata, Connection *server, int ot, int t)
 
static int handle_operation(SMSCConn *conn, Connection *server, struct emimsg *emimsg)
 
void debug(const char *place, int err, const char *fmt,...)
 
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
 
static void emi2_idletimeout_handling(SMSCConn *conn, Connection **server)
 
static void emi2_listener(void *arg)
 
static void start_cb(SMSCConn *conn)
 
struct tm gw_localtime(time_t t)
 
void gwthread_wakeup(long thread)
 
int octstr_hex_to_binary(Octstr *ostr)
 
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
 
static int emi2_emimsg_send(SMSCConn *conn, Connection *server, struct emimsg *emimsg)
 
static void server(int lport, int pport)
 
long(* queued)(SMSCConn *conn)
 
void octstr_truncate(Octstr *ostr, int new_len)
 
int(* send_msg)(SMSCConn *conn, Msg *msg)
 
void charset_gsm_to_nrc_iso_21_german(Octstr *ostr)
 
gw_prioqueue_t * outgoing_queue
 
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
 
int dcs_to_fields(Msg **msg, int dcs)
 
int conn_error(Connection *conn)
 
long date_convert_universal(struct universaltime *t)
 
time_t sendtime[CGW_TRN_MAX]
 
int octstr_get_char(const Octstr *ostr, long pos)
 
void octstr_set_char(Octstr *ostr, long pos, int ch)
 
static long queued_cb(SMSCConn *conn)
 
#define DLR_IS_ENABLED_DEVICE(dlr)
 
static Octstr * alt_charset
 
static XMLRPCDocument * msg
 
int charset_gsm_truncate(Octstr *gsm, long max)
 
#define CONNECTIONIDLE(conn)
 
static void emi2_send_loop(SMSCConn *conn, Connection **server)
 
Connection * conn_wrap_fd(int fd, int ssl)
 
static void reply(HTTPClient *c, List *push_headers)
 
static void emi2_idleprocessing(SMSCConn *conn, Connection **server)
 
void charset_gsm_to_utf8(Octstr *ostr)