static void accept_thread(void *arg) { int fd; int new_fd; int port; socklen_t addrlen; struct sockaddr addr; long smsbox_thread_id; port = *(int *) arg; fd = make_server_socket(port, NULL); if (fd == -1) panic(0, "Couldn't create SMPP listen port."); smsbox_thread_id = -1; for (;;) { if (gwthread_pollfd(fd, POLLIN, -1.0) != POLLIN) break; addrlen = sizeof(addr); new_fd = accept(fd, &addr, &addrlen); if (start_time == (time_t) -1) time(&start_time); gwthread_create(receive_smpp_thread, esme_create(conn_wrap_fd(new_fd, 0))); if (smsbox_thread_id == -1) smsbox_thread_id = gwthread_create(smsbox_thread, NULL); } debug("test.smpp", 0, "%s terminates.", __func__); }
int smsbox_start(Cfg *cfg) { CfgGroup *grp; if (smsbox_running) return -1; debug("bb", 0, "starting smsbox connection module"); grp = cfg_get_single_group(cfg, octstr_imm("core")); if (cfg_get_integer(&smsbox_port, grp, octstr_imm("smsbox-port")) == -1) { error(0, "Missing smsbox-port variable, cannot start smsboxes"); return -1; } #ifdef HAVE_LIBSSL cfg_get_bool(&smsbox_port_ssl, grp, octstr_imm("smsbox-port-ssl")); #endif /* HAVE_LIBSSL */ if (smsbox_port_ssl) debug("bb", 0, "smsbox connection module is SSL-enabled"); if (cfg_get_integer(&smsbox_max_pending, grp, octstr_imm("smsbox-max-pending")) == -1) { smsbox_max_pending = SMSBOX_MAX_PENDING; info(0, "BOXC: 'smsbox-max-pending' not set, using default (%ld).", smsbox_max_pending); } smsbox_list = gwlist_create(); /* have a list of connections */ smsbox_list_rwlock = gw_rwlock_create(); if (!boxid) boxid = counter_create(); /* the smsbox routing specific inits */ smsbox_by_id = dict_create(10, NULL); /* and a hash directory of identified */ smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy); smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy); smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy); /* load the defined smsbox routing rules */ init_smsbox_routes(cfg); gwlist_add_producer(outgoing_sms); gwlist_add_producer(smsbox_list); smsbox_running = 1; if ((sms_dequeue_thread = gwthread_create(sms_to_smsboxes, NULL)) == -1) panic(0, "Failed to start a new thread for smsbox routing"); if (gwthread_create(smsboxc_run, &smsbox_port) == -1) panic(0, "Failed to start a new thread for smsbox connections"); return 0; }
static void sql_to_bearerbox(void *arg) { Boxc *boxc; boxc = gw_malloc(sizeof(Boxc)); boxc->bearerbox_connection = connect_to_bearerbox_real(bearerbox_host, bearerbox_port, bearerbox_port_ssl, NULL /* bb_our_host */); boxc->smsbox_connection = NULL; boxc->client_ip = NULL; boxc->alive = 1; boxc->connect_time = time(NULL); boxc->boxc_id = octstr_duplicate(sqlbox_id); if (boxc->bearerbox_connection == NULL) { boxc_destroy(boxc); return; } gwthread_create(bearerbox_to_sql, boxc); identify_to_bearerbox(boxc); if (gw_sql_fetch_msg_list == NULL || gw_sql_save_list == NULL || limit_per_cycle <= 1) { sql_single(boxc); } else { sql_list(boxc); } boxc_destroy(boxc); }
static void wait_for_connections(int fd, void (*function) (void *arg), List *waited) { int ret; int timeout = 10; /* 10 sec. */ gw_assert(function != NULL); while(sqlbox_status == SQL_RUNNING) { ret = gwthread_pollfd(fd, POLLIN, 1.0); if (sqlbox_status == SQL_SHUTDOWN) { if (ret == -1 || !timeout) break; else timeout--; } if (ret > 0) { gwthread_create(function, (void *)fd); gwthread_sleep(1.0); } else if (ret < 0) { if(errno==EINTR) continue; if(errno==EAGAIN) continue; error(errno, "wait_for_connections failed"); } } }
static void run_sqlbox(void *arg) { int fd; Boxc *newconn; long sender; fd = (int)arg; newconn = accept_boxc(fd, sqlbox_port_ssl); if (newconn == NULL) { panic(0, "Socket accept failed"); return; } newconn->bearerbox_connection = connect_to_bearerbox_real(bearerbox_host, bearerbox_port, bearerbox_port_ssl, NULL /* bb_our_host */); /* XXX add our_host if required */ sender = gwthread_create(bearerbox_to_smsbox, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); //goto cleanup; } smsbox_to_bearerbox(newconn); gwthread_join(sender); boxc_destroy(newconn); }
static void sqlboxc_run(void *arg) { int fd; int port; /* we will use one thread for SQL sms injections */ gwthread_create(sql_to_bearerbox, NULL); port = (int)arg; fd = make_server_socket(port, NULL); /* XXX add interface_name if required */ if (fd < 0) { panic(0, "Could not open sqlbox port %d", port); } /* * infinitely wait for new connections; * to shut down the system, SIGTERM is send and then * select drops with error, so we can check the status */ wait_for_connections(fd, run_sqlbox, NULL); /* close listen socket */ close(fd); }
int mmsrelay() { if (!(settings->svc_list & (SvcMM1 | SvcRelay))) { mms_info(0, "mmsrelay", NULL, " " MM_NAME " MMSC Relay version %s, no services to be started.", MMSC_VERSION); return 0; } else mms_info(0, "mmsrelay", NULL, " " MM_NAME " MMSC Relay version %s starting", MMSC_VERSION); /* Start global queue runner. */ if (settings->svc_list & SvcRelay) { mms_info(0, "mmsrelay", NULL, "Starting Global Queue Runner..."); qthread = gwthread_create((gwthread_func_t *)mbuni_global_queue_runner, &rstop); } if (settings->svc_list & SvcMM1) { /* Start the local queue runner. */ mms_info(0, "mmsrelay", NULL,"Starting Local Queue Runner..."); mbuni_mm1_queue_runner(&rstop); } if (qthread >= 0) gwthread_join(qthread); /* Wait for it to die... */ mms_info(0, "mmsrelay", NULL, "MMSC Relay MM1 queue runner terminates..."); return 0; }
int httpadmin_start(Cfg *cfg) { CfgGroup *grp; int ssl = 0; #ifdef HAVE_LIBSSL Octstr *ssl_server_cert_file; Octstr *ssl_server_key_file; #endif /* HAVE_LIBSSL */ if (httpadmin_running) return -1; grp = cfg_get_single_group(cfg, octstr_imm("core")); if (cfg_get_integer(&ha_port, grp, octstr_imm("admin-port")) == -1) panic(0, "Missing admin-port variable, cannot start HTTP admin"); ha_interface = cfg_get(grp, octstr_imm("admin-interface")); ha_password = cfg_get(grp, octstr_imm("admin-password")); if (ha_password == NULL) panic(0, "You MUST set HTTP admin-password"); ha_status_pw = cfg_get(grp, octstr_imm("status-password")); ha_allow_ip = cfg_get(grp, octstr_imm("admin-allow-ip")); ha_deny_ip = cfg_get(grp, octstr_imm("admin-deny-ip")); #ifdef HAVE_LIBSSL cfg_get_bool(&ssl, grp, octstr_imm("admin-port-ssl")); /* * check if SSL is desired for HTTP servers and then * load SSL client and SSL server public certificates * and private keys */ ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file")); ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file")); if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) { /* we are fine here, the following call is now in conn_config_ssl(), * so there is no reason to do this twice. use_global_server_certkey_file(ssl_server_cert_file, ssl_server_key_file); */ } else if (ssl) { panic(0, "You MUST specify cert and key files within core group for SSL-enabled HTTP servers!"); } octstr_destroy(ssl_server_cert_file); octstr_destroy(ssl_server_key_file); #endif /* HAVE_LIBSSL */ http_open_port_if(ha_port, ssl, ha_interface); if (gwthread_create(httpadmin_run, NULL) == -1) panic(0, "Failed to start a new thread for HTTP admin"); httpadmin_running = 1; return 0; }
static void main_for_producer_and_consumer(void) { List *list; int i; Item *item; struct producer_info tab[NUM_PRODUCERS]; long p, n, index; int errors; list = gwlist_create(); init_received(); for (i = 0; i < NUM_PRODUCERS; ++i) { tab[i].list = list; tab[i].start_index = i * NUM_ITEMS_PER_PRODUCER; gwlist_add_producer(list); tab[i].id = gwthread_create(producer, tab + i); } for (i = 0; i < NUM_CONSUMERS; ++i) gwthread_create(consumer, list); gwthread_join_every(producer); gwthread_join_every(consumer); while (gwlist_len(list) > 0) { item = gwlist_get(list, 0); gwlist_delete(list, 0, 1); warning(0, "main: %ld %ld %ld", (long) item->producer, item->num, item->index); } errors = 0; for (p = 0; p < NUM_PRODUCERS; ++p) { for (n = 0; n < NUM_ITEMS_PER_PRODUCER; ++n) { index = p * NUM_ITEMS_PER_PRODUCER + n; if (!received[index]) { error(0, "Not received: producer=%ld " "item=%ld index=%ld", tab[p].id, n, index); errors = 1; } } } if (errors) panic(0, "Not all messages were received."); }
static void receive_smpp_thread(void *arg) { ESME *esme; Octstr *os; long len; long sender_id; SMPP_PDU *pdu; esme = arg; sender_id = -1; len = 0; while (!quitting && conn_wait(esme->conn, -1.0) != -1) { for (;;) { if (len == 0) { len = smpp_pdu_read_len(esme->conn); if (len == -1) { error(0, "Client sent garbage, closing connection."); goto error; } else if (len == 0) { if (conn_eof(esme->conn) || conn_error(esme->conn)) goto error; break; } } gw_assert(len > 0); os = smpp_pdu_read_data(esme->conn, len); if (os != NULL) { len = 0; pdu = smpp_pdu_unpack(NULL, os); if (pdu == NULL) { error(0, "PDU unpacking failed!"); octstr_dump(os, 0); } else { handle_pdu(esme, pdu); smpp_pdu_destroy(pdu); } octstr_destroy(os); } else if (conn_eof(esme->conn) || conn_error(esme->conn)) goto error; else break; } if (!quitting && esme->receiver && sender_id == -1) sender_id = gwthread_create(send_smpp_thread, esme); } error: if (sender_id != -1) { quit(); gwthread_join(sender_id); } esme_destroy(esme); quit(); debug("test.smpp", 0, "%s terminates.", __func__); }
static void run_wapbox(void *arg) { Boxc *newconn; List *newlist; long sender; gwlist_add_producer(flow_threads); newconn = arg; newconn->is_wap = 1; /* * create a new incoming list for just that box, * and add it to list of list pointers, so we can start * to route messages to it. */ debug("bb", 0, "setting up systems for new wapbox"); newlist = gwlist_create(); /* this is released by the sender/receiver if it exits */ gwlist_add_producer(newlist); newconn->incoming = newlist; newconn->retry = incoming_wdp; newconn->outgoing = outgoing_wdp; sender = gwthread_create(boxc_sender, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); goto cleanup; } gwlist_append(wapbox_list, newconn); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); /* cleanup after receiver has exited */ gwlist_remove_producer(newconn->outgoing); gwlist_lock(wapbox_list); gwlist_delete_equal(wapbox_list, newconn); gwlist_unlock(wapbox_list); while (gwlist_producer_count(newlist) > 0) gwlist_remove_producer(newlist); newconn->alive = 0; gwthread_join(sender); cleanup: gw_assert(gwlist_len(newlist) == 0); gwlist_destroy(newlist, NULL); boxc_destroy(newconn); gwlist_remove_producer(flow_threads); }
void timers_init(void) { if (initialized == 0) { timers = gw_malloc(sizeof(*timers)); timers->mutex = mutex_create(); timers->heap = heap_create(); timers->stopping = 0; timers->thread = gwthread_create(watch_timers, timers); } initialized++; }
int wapbox_start(Cfg *cfg) { CfgGroup *grp; if (wapbox_running) return -1; debug("bb", 0, "starting wapbox connection module"); grp = cfg_get_single_group(cfg, octstr_imm("core")); if (cfg_get_integer(&wapbox_port, grp, octstr_imm("wapbox-port")) == -1) { error(0, "Missing wapbox-port variable, cannot start WAP"); return -1; } #ifdef HAVE_LIBSSL cfg_get_bool(&wapbox_port_ssl, grp, octstr_imm("wapbox-port-ssl")); #endif /* HAVE_LIBSSL */ box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip")); if (box_allow_ip == NULL) box_allow_ip = octstr_create(""); box_deny_ip = cfg_get(grp, octstr_imm("box-deny-ip")); if (box_deny_ip == NULL) box_deny_ip = octstr_create(""); if (box_allow_ip != NULL && box_deny_ip == NULL) info(0, "Box connection allowed IPs defined without any denied..."); wapbox_list = gwlist_create(); /* have a list of connections */ gwlist_add_producer(outgoing_wdp); if (!boxid) boxid = counter_create(); if (gwthread_create(wdp_to_wapboxes, NULL) == -1) panic(0, "Failed to start a new thread for wapbox routing"); if (gwthread_create(wapboxc_run, &wapbox_port) == -1) panic(0, "Failed to start a new thread for wapbox connections"); wapbox_running = 1; return 0; }
Timerset *gw_timerset_create(void) { Timerset *set; set = gw_malloc(sizeof(Timerset)); set->mutex = mutex_create(); set->heap = heap_create(); set->stopping = 0; set->thread = gwthread_create(watch_timers, set); return set; }
static int add_service(int port, char *interface_name) { Udpc *udpc; if ((udpc = udpc_create(port, interface_name)) == NULL) goto error; gwlist_add_producer(udpc->outgoing_list); udpc->receiver = gwthread_create(udp_receiver, udpc); if (udpc->receiver == -1) goto error; if (gwthread_create(udp_sender, udpc) == -1) goto error; gwlist_append(udpc_list, udpc); return 0; error: error(0, "Failed to start UDP receiver/sender thread"); udpc_destroy(udpc); return -1; }
void wtls_init(wtls_dispatch_func_t *responder_dispatch) { /* Initialise our various lists and counters */ wtls_machines = gwlist_create(); wtls_machine_id_counter = counter_create(); wtls_queue = gwlist_create(); gwlist_add_producer(wtls_queue); dispatch_resp_to_bb = responder_dispatch; /* Idiot check - ensure that we are able to start running */ gw_assert(wtls_run_status == limbo); wtls_run_status = running; gwthread_create(main_thread, NULL); }
int main(void) { Counter *c; long threads[THREADS]; long i; gwlib_init(); log_set_output_level(GW_INFO); c = counter_create(); for (i = 0; i < THREADS; ++i) threads[i] = gwthread_create(check, c); for (i = 0; i < THREADS; ++i) gwthread_join(threads[i]); return 0; }
void wap_push_ota_init(wap_dispatch_func_t *wsp_dispatch, wap_dispatch_func_t *wsp_unit_dispatch) { ota_queue = list_create(); list_add_producer(ota_queue); dispatch_to_wsp = wsp_dispatch; dispatch_to_wsp_unit = wsp_unit_dispatch; bearerbox = bearerbox_address_create(); gw_assert(run_status == limbo); run_status = running; gwthread_create(main_thread, NULL); }
static int start_wap(Cfg *cfg) { static int started = 0; if (started) return 0; wapbox_start(cfg); debug("bb", 0, "starting WDP router"); if (gwthread_create(wdp_router, NULL) == -1) panic(0, "Failed to start a new thread for WDP routing"); started = 1; return 0; }
void wsp_push_client_init(wap_dispatch_func_t *dispatch_self, wap_dispatch_func_t *dispatch_wtp_resp) { push_client_machines = gwlist_create(); push_client_machine_id_counter = counter_create(); push_client_queue = gwlist_create(); gwlist_add_producer(push_client_queue); dispatch_to_self = dispatch_self; dispatch_to_wtp_resp = dispatch_wtp_resp; gw_assert(push_client_run_status == limbo); push_client_run_status = running; gwthread_create(main_thread, NULL); }
void wsp_session_init(wap_dispatch_func_t *responder_dispatch, wap_dispatch_func_t *initiator_dispatch, wap_dispatch_func_t *application_dispatch, wap_dispatch_func_t *push_ota_dispatch) { queue = gwlist_create(); gwlist_add_producer(queue); session_machines = gwlist_create(); session_id_counter = counter_create(); dispatch_to_wtp_resp = responder_dispatch; dispatch_to_wtp_init = initiator_dispatch; dispatch_to_appl = application_dispatch; dispatch_to_ota = push_ota_dispatch; wsp_strings_init(); run_status = running; gwthread_create(main_thread, NULL); }
void radius_acct_init(CfgGroup *grp) { long nas_ports = 0; /* get configured parameters */ if ((our_host = cfg_get(grp, octstr_imm("our-host"))) == NULL) { our_host = octstr_create("0.0.0.0"); } if ((remote_host = cfg_get(grp, octstr_imm("remote-host"))) != NULL) { cfg_get_integer(&remote_port, grp, octstr_imm("remote-port")); if ((secret_radius = cfg_get(grp, octstr_imm("secret-radius"))) == NULL) { panic(0, "RADIUS: No shared secret `secret-radius' for remote RADIUS in `radius-acct' provided."); } } cfg_get_integer(&our_port, grp, octstr_imm("our-port")); cfg_get_integer(&remote_timeout, grp, octstr_imm("remote-timeout")); if ((cfg_get_integer(&nas_ports, grp, octstr_imm("nas-ports"))) == -1) { nas_ports = RADIUS_NAS_PORTS; } if ((secret_nas = cfg_get(grp, octstr_imm("secret-nas"))) == NULL) { panic(0, "RADIUS: No shared secret `secret-nas' for NAS in `radius-acct' provided."); } unified_prefix = cfg_get(grp, octstr_imm("unified-prefix")); info(0, "RADIUS: local RADIUS accounting proxy at <%s:%ld>", octstr_get_cstr(our_host), our_port); if (remote_host == NULL) { info(0, "RADIUS: remote RADIUS accounting server is absent"); } else { info(0, "RADIUS: remote RADIUS accounting server at <%s:%ld>", octstr_get_cstr(remote_host), remote_port); } info(0, "RADIUS: initializing internal hash tables with %ld buckets.", nas_ports); radius_mutex = mutex_create(); /* init hash tables */ radius_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); session_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); client_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); gwthread_create(proxy_thread, NULL); }
void mbuni_mm1_queue_runner(int *rstop) { httpcaller = http_caller_create(); if (gwthread_create((gwthread_func_t *)receive_push_reply, httpcaller) < 0) { /* Listener thread. */ error(0, "Mobile sender: Failed to create push reply thread: %d: %s!", errno, strerror(errno)); return; } settings->qfs->mms_queue_run(octstr_get_cstr(settings->mm1_queuedir), sendNotify, settings->queue_interval, settings->maxthreads, rstop); sleep(2); /* Wait for it to die. */ http_caller_signal_shutdown(httpcaller); sleep(2); http_caller_destroy(httpcaller); return; }
void wtp_initiator_init(wap_dispatch_func_t *datagram_dispatch, wap_dispatch_func_t *session_dispatch, long timer_freq) { init_machines = gwlist_create(); init_machine_id_counter = counter_create(); queue = gwlist_create(); gwlist_add_producer(queue); dispatch_to_wdp = datagram_dispatch; dispatch_to_wsp = session_dispatch; timers_init(); init_timer_freq = timer_freq; gw_assert(initiator_run_status == limbo); initiator_run_status = running; gwthread_create(main_thread, NULL); }
static int start_http_thread(void) { unsigned short port; int *port_copy; int ssl = 0; /* indicate if SSL-enabled server should be used */ for (port = 40000; port < 41000; port += 13) { if (http_open_port(port, ssl) != -1) break; } if (port == 41000) panic(0, "No ports available for http server"); port_copy = gw_malloc(sizeof(*port_copy)); *port_copy = port; http_thread_id = gwthread_create(http_thread, port_copy); if (http_thread_id == -1) panic(0, "Cannot start http thread"); return port; }
static void wait_for_connections(int fd, void (*function) (void *arg), List *waited, int ssl) { int ret; int timeout = 10; /* 10 sec. */ gw_assert(function != NULL); while(bb_status != BB_DEAD) { /* if we are being shutdowned, as long as there is * messages in incoming list allow new connections, but when * list is empty, exit. * Note: We have timeout (defined above) for which we allow new connections. * Otherwise we wait here for ever! */ if (bb_status == BB_SHUTDOWN) { ret = gwlist_wait_until_nonempty(waited); if (ret == -1 || !timeout) break; else timeout--; } /* block here if suspended */ gwlist_consume(suspended); ret = gwthread_pollfd(fd, POLLIN, 1.0); if (ret > 0) { Boxc *newconn = accept_boxc(fd, ssl); if (newconn != NULL) { gwthread_create(function, newconn); gwthread_sleep(1.0); } else { error(0, "Failed to create new boxc connection."); } } else if (ret < 0 && errno != EINTR && errno != EAGAIN) error(errno, "bb_boxc::wait_for_connections failed"); } }
int main(int argc, char **argv) { int opt; unsigned long sended = 0; Octstr *cf, *rf; gwlib_init(); bb_host = octstr_create("localhost"); bb_port = 13001; bb_ssl = 0; while ((opt = getopt(argc, argv, "hv:b:p:si:n:a:f:D:u:d:r:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'b': octstr_destroy(bb_host); bb_host = octstr_create(optarg); break; case 'p': bb_port = atoi(optarg); break; case 's': bb_ssl = 1; break; case 'i': smsbox_id = octstr_create(optarg); break; case 'n': service = octstr_create(optarg); break; case 'a': account = octstr_create(optarg); break; case 'f': from = octstr_create(optarg); break; case 'D': dlr_mask = atoi(optarg); break; case 'u': dlr_url = octstr_create(optarg); break; case 'd': delay = atof(optarg); break; case 'r': smsc_id = octstr_create(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (optind == argc || argc-optind < 2) { help(); exit(1); } /* check some mandatory elements */ if (from == NULL) panic(0,"Sender address not specified. Use option -f to specify sender address."); if ((DLR_IS_ENABLED(dlr_mask) && dlr_url == NULL) || (!DLR_IS_ENABLED(dlr_mask) && dlr_url != NULL)) panic(0,"dlr-url address OR dlr-mask not specified. Use option -D or -u to specify dlr values"); rf = octstr_create(argv[argc-1]); cf = octstr_create(argv[argc-2]); report_versions("mtbatch"); write_pid_file(); init_batch(cf, rf); connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */); identify_to_bearerbox(); gwthread_create(read_messages_from_bearerbox, NULL); sended = run_batch(); /* avoid exiting before sending all msgs */ while(sended > counter_value(counter)) { gwthread_sleep(0.1); } program_status = shutting_down; gwthread_join_all(); octstr_destroy(bb_host); octstr_destroy(smsbox_id); octstr_destroy(content); octstr_destroy(service); octstr_destroy(account); octstr_destroy(dlr_url); octstr_destroy(smsc_id); counter_destroy(counter); gwlist_destroy(lines, octstr_destroy_item); gwlib_shutdown(); return 0; }
int smsc_wrapper_create(SMSCConn *conn, CfgGroup *cfg) { /* 1. Call smsc_open() * 2. create sender/receiver threads * 3. fill up the conn * * XXX open() SHOULD be done in distinct thread, not here! */ SmscWrapper *wrap; wrap = gw_malloc(sizeof(SmscWrapper)); wrap->smsc = NULL; conn->data = wrap; conn->send_msg = wrapper_add_msg; wrap->outgoing_queue = gwlist_create(); wrap->stopped = gwlist_create(); wrap->reconnect_mutex = mutex_create(); gwlist_add_producer(wrap->outgoing_queue); if ((wrap->smsc = smsc_open(cfg)) == NULL) goto error; conn->name = octstr_create(smsc_name(wrap->smsc)); conn->status = SMSCCONN_ACTIVE; conn->connect_time = time(NULL); if (conn->is_stopped) gwlist_add_producer(wrap->stopped); /* XXX here we could fail things... specially if the second one * fails.. so fix this ASAP * * moreover, open should be in sender/receiver, so that we can continue * while trying to open... maybe move this, or just wait for new * implementations of various SMSC protocols */ if ((wrap->receiver_thread = gwthread_create(wrapper_receiver, conn))==-1) goto error; if ((wrap->sender_thread = gwthread_create(wrapper_sender, conn))==-1) goto error; conn->shutdown = wrapper_shutdown; conn->queued = wrapper_queued; conn->stop_conn = wrapper_stop; conn->start_conn = wrapper_start; return 0; error: error(0, "Failed to create Smsc wrapper"); conn->data = NULL; smscwrapper_destroy(wrap); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; return -1; }
int smsc_http_create(SMSCConn *conn, CfgGroup *cfg) { ConnData *conndata = NULL; Octstr *type; int ssl = 0; /* indicate if SSL-enabled server should be used */ long max_ps; if ((type = cfg_get(cfg, octstr_imm("system-type"))) == NULL) { error(0, "HTTP[%s]: 'system-type' missing in smsc 'http' record.", octstr_get_cstr(conn->id)); octstr_destroy(type); return -1; } conndata = gw_malloc(sizeof(ConnData)); /* reset conndata */ memset(conndata, 0, sizeof(ConnData)); conn->data = conndata; conndata->http_ref = NULL; conndata->data = NULL; if (cfg_get_integer(&conndata->port, cfg, octstr_imm("port")) == -1) { warning(0, "HTTP[%s]: 'port' not set in smsc 'http' group.", octstr_get_cstr(conn->id)); conndata->port = -1; } conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip")); conndata->send_url = cfg_get(cfg, octstr_imm("send-url")); conndata->username = cfg_get(cfg, octstr_imm("smsc-username")); conndata->password = cfg_get(cfg, octstr_imm("smsc-password")); conndata->system_id = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender")); cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding")); cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep")); conndata->proxy = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&ssl, cfg, octstr_imm("use-ssl")); conndata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url")); conndata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset")); if (cfg_get_integer(&max_ps, cfg, octstr_imm("max-pending-submits")) == -1 || max_ps < 1) max_ps = 10; conndata->max_pending_sends = semaphore_create(max_ps); if (conndata->port <= 0 && conndata->send_url == NULL) { error(0, "Sender and receiver disabled. Dummy SMSC not allowed."); goto error; } if (conndata->send_url == NULL) panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.", octstr_get_cstr(conn->id)); if (octstr_case_compare(type, octstr_imm("kannel")) == 0) { if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->callbacks = &smsc_http_kannel_callback; } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) { conndata->callbacks = &smsc_http_brunet_callback; } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) { conndata->callbacks = &smsc_http_xidris_callback; } else if (octstr_case_compare(type, octstr_imm("generic")) == 0) { conndata->callbacks = &smsc_http_generic_callback; } else if (octstr_case_compare(type, octstr_imm("clickatell")) == 0) { conndata->callbacks = &smsc_http_clickatell_callback; } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) { conndata->callbacks = &smsc_http_wapme_callback; } /* * ADD NEW HTTP SMSC TYPES HERE */ else { error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } if (conndata->callbacks != NULL && conndata->callbacks->init != NULL && conndata->callbacks->init(conn, cfg)) { error(0, "HTTP[%s]: submodule '%s' init failed.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } conndata->open_sends = counter_create(); conndata->msg_to_send = gwlist_create(); gwlist_add_producer(conndata->msg_to_send); conndata->http_ref = http_caller_create(); conn->name = octstr_format("HTTP%s:%S:%d", (ssl?"S":""), type, conndata->port); if (conndata->send_url != NULL) { conn->status = SMSCCONN_ACTIVE; } else { conn->status = SMSCCONN_ACTIVE_RECV; } conn->connect_time = time(NULL); conn->shutdown = httpsmsc_shutdown; conn->queued = httpsmsc_queued; conn->send_msg = httpsmsc_send; conndata->shutdown = 0; /* start receiver thread */ if (conndata->port > 0) { if (http_open_port(conndata->port, ssl) == -1) goto error; if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1) goto error; } else conndata->receive_thread = -1; /* start sender threads */ if (conndata->send_url) { if ((conndata->send_cb_thread = gwthread_create(httpsmsc_send_cb, conn)) == -1) goto error; if ((conndata->sender_thread = gwthread_create(httpsmsc_sender, conn)) == -1) goto error; } else { conndata->send_cb_thread = conndata->sender_thread = -1; } info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id)); octstr_destroy(type); return 0; error: error(0, "HTTP[%s]: Failed to create HTTP SMSC connection", octstr_get_cstr(conn->id)); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; octstr_destroy(type); return -1; }
int main(int argc, char **argv) { struct sigaction act; int port; int opt; double run_time; char *log_file; char *config_file; gwlib_init(); act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); port = 2345; smsc_system_id = octstr_create("kannel_smpp"); smsc_source_addr = octstr_create("123456"); message_id_counter = counter_create(); bearerbox_host = octstr_create("127.0.0.1"); port_for_smsbox = 13001; max_to_esme = 1; num_to_esme = counter_create(); num_from_esme = counter_create(); num_to_bearerbox = counter_create(); num_from_bearerbox = counter_create(); log_file = config_file = NULL; while ((opt = getopt(argc, argv, "hv:p:m:l:c:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'h': help(); exit(0); case 'm': max_to_esme = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'l': log_file = optarg; break; case 'c': config_file = optarg; break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (log_file != NULL) log_open(log_file, GW_DEBUG, GW_NON_EXCL); if (config_file != NULL) { Cfg *cfg; Octstr *tmp = octstr_create(config_file); cfg = cfg_create(tmp); octstr_destroy(tmp); if (cfg_read(cfg) == -1) panic(0, "Errors in config file."); smpp_pdu_init(cfg); cfg_destroy(cfg); } info(0, "Starting drive_smpp test."); gwthread_create(accept_thread, &port); gwthread_join_all(); debug("test.smpp", 0, "Program exiting normally."); run_time = difftime(last_from_esme, first_to_esme); info(0, "Number of messages sent to ESME: %ld", counter_value(num_to_esme)); info(0, "Number of messages sent to smsbox: %ld", counter_value(num_from_bearerbox)); info(0, "Number of messages sent to bearerbox: %ld", counter_value(num_to_bearerbox)); info(0, "Number of messages sent to SMSC: %ld", counter_value(num_from_esme)); info(0, "Time: %.0f secs", run_time); info(0, "Time until all sent to ESME: %.0f secs", difftime(last_to_esme, start_time)); info(0, "Time from first from bb to last to bb: %.0f secs", difftime(last_to_bb, first_from_bb)); info(0, "Time until all sent to SMSC: %.0f secs", difftime(last_from_esme, start_time)); info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec", counter_value(num_to_esme) / run_time); info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec", counter_value(num_from_esme) / run_time); octstr_destroy(smsc_system_id); octstr_destroy(smsc_source_addr); octstr_destroy(bearerbox_host); counter_destroy(num_to_esme); counter_destroy(num_from_esme); counter_destroy(num_to_bearerbox); counter_destroy(num_from_bearerbox); counter_destroy(message_id_counter); gwlib_shutdown(); return 0; }