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)