107 #include <sys/types.h> 108 #include <sys/socket.h> 123 #define CGW_DEFPORT 21772 125 #define CGW_TRN_MAX 500 127 #define CGWOP_MAXARGS 10 135 #define CGW_OP_DELIVERY 4 136 #define CGW_OP_HELLO 5 137 #define CGW_OP_STATUS 6 148 static char *
cgw_ops[6] = {
"nop",
"msg",
"ok",
"err",
"delivery",
"hello"};
209 info(0,
"cgw: CGWOP_MAXARGS exceeded.");
219 ret = gw_malloc(
sizeof(
struct cgwop));
296 if (dta == NULL)
return -1;
383 Octstr *sender, *udh, *dta;
387 if (
cgwop == NULL)
return NULL;
476 error(0,
"'host' missing in cgw configuration.");
527 error(0,
"Failed to create CGW smsc connection");
566 debug(
"bb.sms", 0,
"Shutting down SMSCConn CGW, %s",
567 finish_sending ?
"slow" :
"instant");
575 if (finish_sending == 0) {
595 debug(
"smsc.cgw", 0,
"smsc_cgw: start called");
636 error(0,
"Unable to connect to CGW server");
676 debug(
"bb.sms", 0,
"smsc_cgw connection has completed shutdown.");
703 info(0,
"smsc_cgw: waiting for %d minutes before trying to connect again", wait);
705 wait = wait > 5 ? 10 : wait * 2;
755 info(0,
"cgw: Saturated, increase size of CGW_TRN_MAX!");
764 info(0,
"cgw: cgwop == NULL");
773 info(0,
"cgw: Unable to send (cgwop_send() == -1)");
792 current_time = time(NULL);
799 warning(0,
"smsc_cgw: received neither OK nor ERR for message %d " 825 info(0,
"cgw: Connection closed by SMSC");
831 error(0,
"cgw: Error trying to read ACKs from SMSC");
914 info(0,
"cgw: cgwop != null");
954 error(0,
"smsc_cgw: couldn't make listening socket port %d non-blocking",
privdata->
rport);
971 struct sockaddr_in server_addr;
981 server_addr_len =
sizeof(server_addr);
987 error(0,
"Poll for cgw smsc connections failed, shutting down");
999 warning(errno,
"cgw_listener: accept() failed, retrying...");
1005 info(0,
"CGW smsc connection tried from denied host <%s>, disconnected",
octstr_get_cstr(ip));
1012 error(0,
"cgw_listener: conn_wrap_fd failed on accept()ed fd");
1025 warning(errno,
"smsc_cgw: couldn't close listening socket at shutdown");
1036 info(0,
"cgw: receive connection closed by SMSC");
1040 error(0,
"cgw: receive connection broken");
1046 if (
cgwop != NULL) {
1073 Msg *dlrmsg = NULL, *origmsg = NULL;
1076 if (
cgwop == NULL)
return 0;
1092 info(0,
"cgw: Invalid transaction number: %d", (
int)
trn);
1102 time(&
msg->sms.time);
1123 if (origmsg == NULL)
break;
1152 if (dlrmsg != NULL) {
1161 if (
trn == -1)
break;
1193 info(0,
"CGW: Warning: Got session status");
1206 if (
trn == -1)
break;
Octstr * conn_read_line(Connection *conn)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
Msg * msg_duplicate(Msg *msg)
int smsc_cgw_create(SMSCConn *conn, CfgGroup *cfg)
static void cgw_start_cb(SMSCConn *conn)
void bb_smscconn_connected(SMSCConn *conn)
int socket_set_blocking(int fd, int blocking)
Msg * sendmsg[CGW_TRN_MAX]
static Connection * cgw_open_send_connection(SMSCConn *conn)
void bb_smscconn_killed(void)
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
static void cgwop_add(struct cgwop *cgwop, Octstr *name, Octstr *value)
static int cgw_handle_op(SMSCConn *conn, Connection *server, struct cgwop *cgwop)
void octstr_append_char(Octstr *ostr, int ch)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
#define cfg_get(grp, varname)
static int cgw_add_msg_cb(SMSCConn *conn, Msg *sms)
static Octstr * cgwop_get(struct cgwop *cgwop, Octstr *name)
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
int conn_eof(Connection *conn)
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
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)
int cgw_wait_command(PrivData *privdata, SMSCConn *conn, Connection *server, int timeout)
static int cgw_send_loop(SMSCConn *conn, Connection *server)
void log_thread_to(int idx)
static void cgw_receiver(SMSCConn *conn, Connection *server)
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
smscconn_killed_t why_killed
void conn_claim(Connection *conn)
static void cgwop_destroy(struct cgwop *cgwop)
Octstr * octstr_imm(const char *cstr)
int conn_write(Connection *conn, Octstr *data)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
static struct cgwop * cgwop_create(int op, int trn)
void * gwlist_extract_first(List *list)
static int cgw_shutdown_cb(SMSCConn *conn, int finish_sending)
void octstr_delete(Octstr *ostr1, long pos, long len)
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
void conn_destroy(Connection *conn)
void cgw_check_acks(PrivData *privdata)
#define octstr_duplicate(ostr)
static struct cgwop * msg_to_cgwop(PrivData *privdata, Msg *msg, int trn)
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,...)
static int cgwop_send(Connection *conn, struct cgwop *cgwop)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
static void cgw_sender(void *arg)
void gwthread_sleep(double seconds)
int gwthread_pollfd(int fd, int events, double timeout)
static Octstr * cgwop_tostr(struct cgwop *cgwop)
long octstr_len(const Octstr *ostr)
static long cgw_queued_cb(SMSCConn *conn)
void octstr_append_decimal(Octstr *ostr, long value)
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
int conn_wait(Connection *conn, double seconds)
int(* shutdown)(SMSCConn *conn, int finish_sending)
struct cgwop * cgw_read_op(PrivData *privdata, SMSCConn *conn, Connection *server, time_t timeout)
Octstr * host_ip(struct sockaddr_in addr)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
void gwthread_wakeup(long thread)
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
static void server(int lport, int pport)
long(* queued)(SMSCConn *conn)
int(* send_msg)(SMSCConn *conn, Msg *msg)
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
int conn_error(Connection *conn)
static Octstr * cgw_decode_msg(Octstr *str)
time_t sendtime[CGW_TRN_MAX]
static void cgw_listener(void *arg)
#define DLR_IS_ENABLED_DEVICE(dlr)
static int cgw_open_listening_socket(SMSCConn *conn, PrivData *privdata)
static XMLRPCDocument * msg
static Octstr * cgw_encode_msg(Octstr *str)
Connection * conn_wrap_fd(int fd, int ssl)
static void reply(HTTPClient *c, List *push_headers)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)