86 #include "../sb-config.h" 88 #ifdef HAVE_PAM_SECURITY 89 #include <security/pam_appl.h> 90 #elif defined HAVE_PAM_PAM 91 #include <pam/pam_appl.h> 100 #define SMPP_SHUTDOWN 1 101 #define SMPP_RUNNING 2 137 #define TIMEOUT_SECONDS 300 197 typedef const struct pam_message pam_message_type;
199 static const char *PAM_username;
200 static const char *PAM_password;
202 static int PAM_conv (
int num_msg, pam_message_type **
msg,
203 struct pam_response **resp,
206 int count = 0, replies = 0;
207 struct pam_response *repl = NULL;
208 int size =
sizeof(
struct pam_response);
211 repl = gw_realloc(repl, size); \ 212 size += sizeof(struct pam_response) 213 #define COPY_STRING(s) (s) ? gw_strdup(s) : NULL 215 for (count = 0; count < num_msg; count++) {
216 switch (
msg[count]->msg_style) {
217 case PAM_PROMPT_ECHO_ON:
219 repl[replies].resp_retcode = PAM_SUCCESS;
220 repl[replies++].resp = COPY_STRING(PAM_username);
224 case PAM_PROMPT_ECHO_OFF:
226 repl[replies].resp_retcode = PAM_SUCCESS;
227 repl[replies++].resp = COPY_STRING(PAM_password);
232 warning(0,
"unexpected message from PAM: %s",
msg[count]->
msg);
238 error(0,
"unexpected error from PAM: %s",
msg[count]->
msg);
248 static struct pam_conv PAM_conversation = {
254 static int authenticate(
const char *acl,
const char *login,
const char *passwd)
259 PAM_username = login;
260 PAM_password = passwd;
262 pam_error = pam_start(acl, login, &PAM_conversation, &pamh);
263 info(0,
"Starting PAM for user: %s", login);
264 if (pam_error != PAM_SUCCESS ||
265 (pam_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
266 warning(0,
"PAM auth failed for user: %s", login);
267 pam_end(pamh, pam_error);
270 pam_end(pamh, PAM_SUCCESS);
271 info(0,
"opensmppbox login by <%s>", login);
283 char systemid[255], passw[255], systemtype[255], allowed_ips[1024];
291 fscanf(fp,
"%s %s %s %s\n", systemid, passw, systemtype, allowed_ips);
299 if (strcmp(allowed_ips,
"") != 0) {
323 debug(
"bb.sms.smpp", 0,
"opensmppbox[%s]: Multiple login: disconnect.",
326 #ifdef HAVE_SHUTDOWN_CONNECTION 344 #define dump_pdu(msg, id, pdu) do{}while(0) 347 #define dump_pdu(msg, id, pdu) \ 349 debug("opensmppbox", 0, "SMPP[%s]: %s", \ 350 octstr_get_cstr(id), msg); \ 351 smpp_pdu_dump(id, pdu); \ 366 int rc, diff, dummy, localdiff;
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);
390 if (utc == ((time_t)-1))
393 if (relation ==
'+' || relation ==
'-') {
399 if (valutc == ((time_t)-1))
405 local.tm_isdst = tm.tm_isdst = -1;
409 debug(
"sms.smpp",0,
"diff between utc and localtime (%d)", localdiff);
419 }
else if (relation ==
'R') {
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;
428 if (valutc == ((time_t)-1))
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);
437 debug(
"sms.smpp", 0,
"requested timestamp in min. (%ld)", (valutc - utc)/60);
439 return ceil ( difftime (valutc, utc) / 60 );
505 while (boxconn->
alive) {
526 int current = 1, partno = 1, thismsg, max = 0;
532 ret->sms.udhdata = NULL;
534 while (max < total) {
538 if (thismsg == partno) {
541 if (++partno > total) {
546 if (current >= total) {
553 debug(
"opensmppbox", 0,
"re-assembling message failed.");
573 error(0,
"SMPP[%s]: Mallformed addr `%s', expected at least 7 digits. ",
580 error(0,
"SMPP[%s]: Mallformed addr `%s', expected all digits. ",
587 error(0,
"SMPP[%s]: Mallformed addr `%s', expected all digits. ",
605 error(0,
"SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ",
665 error(0,
"opensmppbox[%s]: Server sent garbage, ignored.",
668 }
else if (*len == 0) {
685 error(0,
"opensmppbox[%s]: PDU unpacking failed.",
687 debug(
"bb.sms.smpp", 0,
"opensmppbox[%s]: Failed PDU omitted.",
702 int dlrtype, catenate;
705 char *
text, *tmps, err[4] = {
'0',
'0',
'0',
'\0' };
706 char submit_date_c_str[11] = {
'\0' }, done_date_c_str[11] = {
'\0' };
708 Octstr *msgid, *msgid2, *dlr_status, *dlvrd;
710 unsigned long msg_sequence, msg_count;
711 unsigned long submit_date;
713 Octstr *header, *footer, *suffix, *split_chars;
731 debug(
"bb.sms.smpp", 0,
"SMPP[%s]: Manually forced source addr ton = %ld, source add npi = %ld",
763 debug(
"bb.sms.smpp", 0,
"SMPP[%s]: Manually forced dest addr ton = %ld, dest add npi = %ld",
781 if (
octstr_len(pdu->
u.deliver_sm.destination_addr) > 20 ||
806 pdu->
u.deliver_sm.protocol_id =
msg->sms.pid;
812 pdu->
u.deliver_sm.esm_class = 0;
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 |
823 dlrtype =
msg->sms.dlr_mask;
868 tmps = strstr(
text,
"err:");
872 snprintf(err,
sizeof(err),
"%3.3s", tmps + (4 *
sizeof(
char)));
873 tmps = strstr(tmps,
" ");
874 text = tmps ? tmps + (1 *
sizeof(char)) :
"";
877 tmps = strstr(
text,
"text:");
879 text = tmps + (5 *
sizeof(char));
887 if (!submit_date || submit_date > dlr->sms.time) {
888 submit_date =
msg->sms.time;
892 gw_strftime(submit_date_c_str,
sizeof(submit_date_c_str),
"%y%m%d%H%M", &tm_tmp);
895 gw_strftime(done_date_c_str,
sizeof(done_date_c_str),
"%y%m%d%H%M", &tm_tmp);
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;
913 pdu2->
u.deliver_sm.destination_addr =
octstr_duplicate(pdu->
u.deliver_sm.destination_addr);
917 pdu2->
u.deliver_sm.message_state = dlr_state;
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);
930 pdu->
u.deliver_sm.message_state = dlr_state;
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);
945 pdu->
u.deliver_sm.registered_delivery = 1;
947 pdu->
u.deliver_sm.registered_delivery = 2;
968 if ((pdu->
u.deliver_sm.data_coding & 0xF0) ||
969 (!box->
alt_charset && pdu->
u.deliver_sm.data_coding == 0)) {
972 else if (pdu->
u.deliver_sm.data_coding == 0 && box->
alt_charset) {
977 error(0,
"Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
979 pdu->
u.deliver_sm.sm_length =
octstr_len(pdu->
u.deliver_sm.short_message);
988 pdu->
u.deliver_sm.sm_length =
octstr_len(pdu->
u.deliver_sm.short_message);
991 if (
msg->sms.priority >= 0 &&
msg->sms.priority <= 3)
992 pdu->
u.deliver_sm.priority_flag =
msg->sms.priority;
994 pdu->
u.deliver_sm.priority_flag = box->
priority;
1014 parts =
sms_split(
msg, header, footer, suffix, split_chars, catenate,
1018 if ((msg_count > 1) && (box->
version > 0x33)) {
1019 Octstr *use_message_payload_meta;
1020 long use_message_payload;
1023 use_message_payload = strtol(
octstr_get_cstr(use_message_payload_meta), 0, 0);
1025 if (use_message_payload) {
1027 pdu->
u.deliver_sm.message_payload =
octstr_duplicate(pdu->
u.deliver_sm.short_message);
1029 pdu->
u.deliver_sm.short_message = NULL;
1030 pdu->
u.deliver_sm.sm_length = 0;
1039 if (msg_count == 1) {
1045 debug(
"SMPP", 0,
"message length %ld, sending %ld message%s",
1046 octstr_len(
msg->sms.msgdata), msg_count, msg_count == 1 ?
"" :
"s");
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;
1058 pdu2->
u.deliver_sm.destination_addr =
octstr_duplicate(pdu->
u.deliver_sm.destination_addr);
1065 pdu2->
u.deliver_sm.short_message =
octstr_cat(msg2->sms.udhdata, msg2->sms.msgdata);
1117 ton = pdu->
u.submit_sm.source_addr_ton;
1118 npi = pdu->
u.submit_sm.source_addr_npi;
1122 msg->sms.sender = pdu->
u.submit_sm.source_addr;
1123 pdu->
u.submit_sm.source_addr = NULL;
1130 if (pdu->
u.submit_sm.destination_addr == NULL) {
1131 error(0,
"SMPP[%s]: Mallformed destination_addr `%s', may not be empty. " 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;
1144 ton = pdu->
u.submit_sm.dest_addr_ton;
1145 npi = pdu->
u.submit_sm.dest_addr_npi;
1149 msg->sms.receiver = pdu->
u.submit_sm.destination_addr;
1150 pdu->
u.submit_sm.destination_addr = NULL;
1153 msg->sms.binfo = pdu->
u.submit_sm.service_type;
1154 pdu->
u.submit_sm.service_type = NULL;
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;
1168 msg->sms.msgdata = pdu->
u.submit_sm.short_message;
1169 pdu->
u.submit_sm.short_message = NULL;
1179 debug(
"bb.sms.smpp",0,
"SMPP[%s]: UDH length read as %d",
1182 error(0,
"SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length " 1195 switch (pdu->
u.submit_sm.data_coding) {
1203 error(0,
"Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1221 error(0,
"Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1225 error(0,
"Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1248 msg->sms.pid = pdu->
u.submit_sm.protocol_id;
1251 msg->sms.priority = pdu->
u.submit_sm.priority_flag;
1254 switch (pdu->
u.submit_sm.registered_delivery & 0x03) {
1262 msg->sms.dlr_mask = 0;
1265 if (pdu->
u.submit_sm.esm_class & (0x04|0x08)) {
1270 if (
msg->sms.meta_data == NULL)
1275 msg->sms.time = time(NULL);
1278 if (pdu->
u.submit_sm.validity_period) {
1284 if (pdu->
u.submit_sm.schedule_delivery_time) {
1319 ton = pdu->
u.data_sm.source_addr_ton;
1320 npi = pdu->
u.data_sm.source_addr_npi;
1324 msg->sms.sender = pdu->
u.data_sm.source_addr;
1325 pdu->
u.data_sm.source_addr = NULL;
1331 if (pdu->
u.data_sm.destination_addr == NULL) {
1332 error(0,
"SMPP[%s]: Mallformed destination_addr `%s', may not be empty. " 1340 ton = pdu->
u.data_sm.dest_addr_ton;
1341 npi = pdu->
u.data_sm.dest_addr_npi;
1345 msg->sms.receiver = pdu->
u.data_sm.destination_addr;
1346 pdu->
u.data_sm.destination_addr = NULL;
1349 msg->sms.binfo = pdu->
u.data_sm.service_type;
1350 pdu->
u.data_sm.service_type = NULL;
1355 msg->sms.msgdata = pdu->
u.data_sm.message_payload;
1356 pdu->
u.data_sm.message_payload = NULL;
1365 debug(
"bb.sms.smpp",0,
"SMPP[%s]: UDH length read as %d",
1368 error(0,
"SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length " 1381 switch (pdu->
u.data_sm.data_coding) {
1389 error(0,
"Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1407 error(0,
"Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1411 error(0,
"Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1436 if (
msg->sms.meta_data == NULL)
1441 msg->sms.time = time(NULL);
1466 int reference, total;
1473 debug(
"opensmppbox", 0,
"assemble multi-part message.");
1478 if (NULL == (*parts_list)) {
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.");
1490 if (NULL == (*msg2)) {
1492 debug(
"opensmppbox", 0,
"Invalid multi-part message.");
1499 debug(
"opensmppbox", 0,
"multi-part message, length: %ld.",
octstr_len((*msg2)->sms.msgdata));
1514 Octstr *msgid = NULL, *hold_service, *system_type;
1515 int msg_to_send = 1;
1516 List *parts_list = NULL;
1520 switch (pdu->
type) {
1521 case bind_transmitter:
1523 case bind_transceiver:
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(
"");
1538 box->
version = pdu->
u.bind_transmitter.interface_version;
1543 resp =
smpp_pdu_create(bind_transmitter_resp, pdu->
u.bind_transmitter.sequence_number);
1547 resp =
smpp_pdu_create(bind_transmitter_resp, pdu->
u.bind_transmitter_resp.sequence_number);
1548 resp->
u.bind_transmitter.command_status = 0x0d;
1552 system_type = pdu->
u.bind_receiver.system_type ? pdu->
u.bind_receiver.system_type :
octstr_imm(
"");
1555 box->
version = pdu->
u.bind_receiver.interface_version;
1560 resp =
smpp_pdu_create(bind_receiver_resp, pdu->
u.bind_receiver.sequence_number);
1564 resp =
smpp_pdu_create(bind_receiver_resp, pdu->
u.bind_receiver.sequence_number);
1565 resp->
u.bind_receiver_resp.command_status = 0x0d;
1568 case bind_transceiver:
1569 system_type = pdu->
u.bind_transceiver.system_type ? pdu->
u.bind_transceiver.system_type :
octstr_imm(
"");
1572 box->
version = pdu->
u.bind_transceiver.interface_version;
1577 resp =
smpp_pdu_create(bind_transceiver_resp, pdu->
u.bind_transceiver.sequence_number);
1581 resp =
smpp_pdu_create(bind_transceiver_resp, pdu->
u.bind_transceiver.sequence_number);
1582 resp->
u.bind_transceiver_resp.command_status = 0x0d;
1592 pdu->
u.enquire_link.sequence_number);
1610 resp->
u.data_sm_resp.message_id = msgid;
1613 hold_service = msg2->sms.service;
1622 msg2->sms.service = hold_service;
1633 else if (
msg != msg2) {
1655 resp->
u.submit_sm_resp.message_id = msgid;
1658 hold_service = msg2->sms.service;
1667 msg2->sms.service = hold_service;
1679 else if (
msg != msg2) {
1685 case deliver_sm_resp:
1686 msgid =
octstr_format(
"%ld", pdu->
u.deliver_sm_resp.sequence_number);
1691 if (pdu->
u.deliver_sm_resp.command_status != 0) {
1703 error(0,
"SMPP[%s]: Unknown PDU type 0x%08lx, ignored.",
1733 boxc = gw_malloc(
sizeof(
Boxc));
1804 if (
msg->sms.smsc_id != NULL)
1805 return msg->sms.smsc_id;
1829 debug(
"opensmppbox", 0,
"routed msg '%s' to smsc '%s'",
1847 struct sockaddr_in client_addr;
1850 client_addr_len =
sizeof(client_addr);
1852 newfd = accept(fd, (
struct sockaddr *)&client_addr, &client_addr_len);
1887 switch (
read_pdu(box, conn, &len, &pdu)) {
1889 error(0,
"Invalid SMPP PDU received.");
1905 #ifdef HAVE_SHUTDOWN_CONNECTION 1934 int dreport, errcode;
1952 info(0,
"Bearerbox told us to die");
1955 info(0,
"Bearerbox told us to restart");
1962 debug(
"opensmppbox", 0,
"bearerbox_to_smpp: catch an heartbeat - we are alive");
1972 switch (
msg->ack.nack) {
1981 switch (pdu->
type) {
1982 case submit_sm_resp:
1984 pdu->
u.submit_sm_resp.message_id = NULL;
1985 pdu->
u.submit_sm_resp.command_status = errcode;
1989 pdu->
u.data_sm_resp.message_id = NULL;
1990 pdu->
u.data_sm_resp.command_status = errcode;
1993 debug(
"opensmppbox", 0,
"Getting failure ack on unexpected pdu: %s.", pdu->
type_name);
1998 debug(
"opensmppbox", 0,
"Unknown ack.nack type: %ld.",
msg->ack.nack);
2005 debug(
"opensmppbox", 0,
"Ack to unknown message: %s.",
id);
2014 info(0,
"We received an SMS message.");
2031 info(0,
"MO message converted from UCS-2 to UTF-8");
2048 info(0,
"MO message converted from UCS-2 to UTF-8");
2065 error(0,
"smppbox_req_thread: no sender/receiver, dump follows:");
2072 mack->ack.time =
msg->sms.time;
2082 mack->ack.time =
msg->sms.time;
2088 if (pdulist != NULL) {
2090 if (NULL == msgid) {
2104 warning(0,
"msg_to_pdu failed, sending negative ack");
2121 if (newconn == NULL) {
2122 panic(0,
"Socket accept failed");
2129 error(0,
"opensmppbox: Failed to connect to bearerbox." );
2136 #ifdef DO_HEARTBEATS 2140 info(0,
"OpenSMPPBox: Could not start heartbeat.");
2146 error(0,
"Failed to start a new thread, disconnecting client <%s>",
2169 if (ret == -1 || !timeout)
2178 }
else if (ret < 0) {
2179 if(errno==EINTR)
continue;
2180 if(errno==EAGAIN)
continue;
2181 error(errno,
"wait_for_connections failed");
2197 panic(0,
"Could not open opensmppbox port %d",
port);
2206 info(0,
"Waiting for SMPP connections on port %d.",
port);
2208 info(0,
"No more waiting for SMPP connections.");
2233 error(0,
"SIGINT received, aborting program...");
2239 warning(0,
"SIGHUP received, catching and re-opening logs");
2249 warning(0,
"SIGQUIT received, reporting memory usage.");
2257 struct sigaction act;
2260 sigemptyset(&act.sa_mask);
2262 sigaction(SIGINT, &act, NULL);
2263 sigaction(SIGQUIT, &act, NULL);
2264 sigaction(SIGHUP, &act, NULL);
2265 sigaction(SIGPIPE, &act, NULL);
2282 Octstr *
smsc_id, *boxc_ids, *shortcodes, *receiver_shortcodes;
2290 smsc_id = boxc_ids = shortcodes = receiver_shortcodes = NULL;
2291 list = items = NULL;
2299 panic(0,
"'smsc-id-route' group without valid 'smsc-id' directive!");
2316 if (receiver_shortcodes) {
2323 debug(
"opensmppbox",0,
"Adding smsc routing to id <%s> for receiver no <%s>",
2327 panic(0,
"Routing for receiver no <%s> already exists!",
2335 if (boxc_ids && !shortcodes) {
2342 debug(
"opensmppbox",0,
"Adding smsc routing to id <%s> for box id <%s>",
2346 panic(0,
"Routing for box-id <%s> already exists!",
2352 else if (!boxc_ids && shortcodes) {
2359 debug(
"opensmppbox",0,
"Adding smsc routing to id <%s> for sender no <%s>",
2363 panic(0,
"Routing for sender no <%s> already exists!",
2369 else if (boxc_ids && shortcodes) {
2381 debug(
"opensmppbox",0,
"Adding smsc routing to id <%s> " 2382 "for sender no <%s> and smsbox id <%s>",
2390 panic(0,
"Routing for sender:smsbox-id <%s> already exists!",
2426 long store_dump_freq = -1;
2445 warning(0,
"'store-file' option deprecated, please use 'store-location' and 'store-type' instead.");
2453 panic(0,
"Could not start with store init failed.");
2462 panic(0,
"Connot start with PDU init failed.");
2471 panic(0,
"No 'opensmppbox' group in configuration");
2490 panic(0,
"our-system-id is not set.");
2505 panic(0,
"No user file specified.");
2508 if (logfile != NULL) {
2509 info(0,
"Starting to log to file %s level %ld",
2535 panic(0,
"enable-pam requires systemid-is-boxcid=true.");
2539 panic(0,
"enable-pam is set but we are compiled without pam support.");
2543 info(0,
"Using PAM authentication.");
2561 if (strcmp(argv[i],
"-H")==0 || strcmp(argv[i],
"--tryhttp")==0) {
2581 #define OCTSTR(name) \ 2582 if (octstr_compare(octstr_imm(#name), variable) == 0) \ 2584 #define SINGLE_GROUP(name, fields) \ 2585 if (octstr_compare(octstr_imm(#name), group) == 0) { \ 2586 if (octstr_compare(groupstr, variable) == 0) \ 2591 #define MULTI_GROUP(name, fields) \ 2592 if (octstr_compare(octstr_imm(#name), group) == 0) { \ 2593 if (octstr_compare(groupstr, variable) == 0) \ 2609 #define OCTSTR(name) 2610 #define SINGLE_GROUP(name, fields) \ 2611 if (octstr_compare(octstr_imm(#name), query) == 0) \ 2613 #define MULTI_GROUP(name, fields) \ 2614 if (octstr_compare(octstr_imm(#name), query) == 0) \ 2632 if (argv[cf_index] == NULL)
2648 version =
octstr_format(
"opensmppbox version %s gwlib", GW_VERSION);
2672 execvp(argv[0], argv);
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
void smpp_pdu_destroy(SMPP_PDU *pdu)
void msg_dump(Msg *msg, int level)
void error(int err, const char *fmt,...)
static Octstr * route_to_smsc
static volatile sig_atomic_t smppbox_status
void info(int err, const char *fmt,...)
Msg * msg_duplicate(Msg *msg)
static volatile sig_atomic_t restart_smppbox
static Octstr * boxc_route_msg_to_smsc(Boxc *box, Msg *msg)
static Octstr * smppbox_id
Connection * connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
static Counter * catenated_sms_counter
static int timestamp_to_minutes(Octstr *timestamp)
static long smpp_dest_addr_npi
gw_assert(wtls_machine->packet_to_send !=NULL)
void dict_put(Dict *dict, Octstr *key, void *value)
void counter_destroy(Counter *counter)
void smpp_pdu_destroy_item(void *pdu)
void gwlist_append(List *list, void *item)
static void init_smppbox(Cfg *cfg)
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
#define DLR_IS_SUCCESS(dlr)
struct tm gw_gmtime(time_t t)
void gwthread_join(long thread)
static void destroy_smsc_routes(void)
long gwlist_len(List *list)
static long smpp_source_addr_ton
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
void * gwlist_get(List *list, long pos)
static void identify_to_bearerbox(Boxc *conn)
static Octstr * generate_smppid(Msg *msg, int version)
static List * msg_to_pdu(Boxc *box, Msg *msg)
#define GSM_ADDR_TON_NATIONAL
void check_multipart(Boxc *box, Msg *msg, int *msg_to_send, Msg **msg2, List **parts_list)
Msg * msg_unpack_wrapper(Octstr *os)
void charset_utf8_to_gsm(Octstr *ostr)
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
#define cfg_get(grp, varname)
void uuid_unparse(const uuid_t uu, char *out)
static void setup_signal_handlers(void)
void uuid_generate(uuid_t out)
long smpp_pdu_read_len(Connection *conn)
static void init_smsc_routes(Cfg *cfg)
static void signal_handler(int signum)
int gwthread_shouldhandlesignal(int signal)
static long outstanding_requests(void)
int conn_eof(Connection *conn)
void octstr_strip_blanks(Octstr *text)
size_t gw_strftime(char *s, size_t max, const char *format, const struct tm *tm)
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)
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)
unsigned long counter_increase(Counter *counter)
#define GSM_ADDR_TON_INTERNATIONAL
static void run_smppbox(void *arg)
static Boxc * find_receiver_box(Boxc *box)
static int bearerbox_port_ssl
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Cfg * cfg_create(Octstr *filename)
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
Connection * bearerbox_connection
void heartbeat_stop(long hb_thread)
volatile sig_atomic_t alive
static int disable_multipart_catenation
#define dump_pdu(msg, id, pdu)
Counter * smpp_pdu_counter
void msg_destroy_item(void *msg)
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited)
static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
Octstr * octstr_imm(const char *cstr)
void cfg_add_hooks(void *allowed, void *single)
int conn_write(Connection *conn, Octstr *data)
static int smppbox_is_allowed_in_group(Octstr *group, Octstr *variable)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Counter * counter_create(void)
Octstr * concat_msgids(Octstr *msgid, List *list)
void * gwlist_extract_first(List *list)
time_t gw_mktime(struct tm *tm)
static long smpp_dest_addr_ton
static void handle_pdu(Connection *conn, Boxc *box, SMPP_PDU *pdu)
void grp_dump(CfgGroup *grp)
void conn_config_ssl(CfgGroup *grp)
#define ESM_CLASS_DELIVER_UDH_INDICATOR
void * dict_get(Dict *dict, Octstr *key)
void octstr_delete(Octstr *ostr1, long pos, long len)
static long smpp_source_addr_npi
static int systemidisboxcid
static Msg * pdu_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
void conn_destroy(Connection *conn)
void octstr_insert_char(Octstr *ostr, long pos, const char c)
int store_init(Cfg *cfg, const Octstr *type, const Octstr *fname, long dump_freq, void *pack_func, void *unpack_func)
static void gw_smpp_enter(Cfg *cfg)
#define octstr_duplicate(ostr)
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
static Octstr * our_system_id
static void smppboxc_run(void *arg)
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
static Boxc * accept_smpp(int fd, int ssl)
static Dict * smsc_by_smsbox_id
long gwlist_delete_equal(List *list, void *item)
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
void uuid_copy(uuid_t dst, const uuid_t src)
void msg_destroy(Msg *msg)
int make_server_socket(int port, const char *interface_name)
void warning(int err, const char *fmt,...)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
int main(int argc, char **argv)
char filename[FILENAME_MAX+1]
#define gwthread_create(func, arg)
#define octstr_create(cstr)
static void smpp_to_bearerbox(void *arg)
void octstr_destroy_item(void *os)
int fields_to_dcs(Msg *msg, int mode)
void gwthread_sleep(double seconds)
#define SMS_PARAM_UNDEFINED
static void gw_smpp_leave()
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
int gwthread_pollfd(int fd, int events, double timeout)
Connection * smpp_connection
static Octstr * smpp_logins
Octstr * smpp_pdu_read_data(Connection *conn, long len)
static long bearerbox_port
void report_versions(const char *boxname)
int log_open(char *filename, int level, enum excl_state excl)
long octstr_len(const Octstr *ostr)
#define GSM_ADDR_NPI_UNKNOWN
void dict_destroy(Dict *dict)
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
#define DEFAULT_HEARTBEAT
static int smppbox_is_single_group(Octstr *query)
static Msg * read_from_box(Connection *conn, Boxc *boxconn)
long heartbeat_start(hb_send_func_t *send_func, double freq, hb_load_func_t *load_func)
void write_to_bearerbox_real(Connection *conn, Msg *pmsg)
#define GSM_ADDR_NPI_E164
#define ESM_CLASS_SUBMIT_RPI
Octstr * host_ip(struct sockaddr_in addr)
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
struct tm gw_localtime(time_t t)
static time_t smpp_timeout
static int smppbox_port_ssl
int check_login(Boxc *boxc, Octstr *system_id, Octstr *password, Octstr *system_type, smpp_login login_type)
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
Msg * catenate_msg(List *list, int total)
void gwlib_shutdown(void)
Octstr * msg_pack(Msg *msg)
static Msg * data_sm_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
int smpp_pdu_init(Cfg *cfg)
static Dict * smsc_by_receiver
int dict_put_once(Dict *dict, Octstr *key, void *value)
int dcs_to_fields(Msg **msg, int dcs)
int conn_error(Connection *conn)
#define GSM_ADDR_TON_ALPHANUMERIC
static Dict * smsc_by_sender
static void bearerbox_to_smpp(void *arg)
static int check_args(int i, int argc, char **argv)
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
#define BB_DEFAULT_SMSBOX_PORT
int octstr_get_char(const Octstr *ostr, long pos)
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
#define DLR_IS_ENABLED(dlr)
static int read_pdu(Boxc *box, Connection *conn, long *len, SMPP_PDU **pdu)
#define octstr_create_from_data(data, len)
List * octstr_split(const Octstr *os, const Octstr *sep)
static Octstr * alt_charset
static long sms_max_length
#define DLR_IS_SUCCESS_OR_FAIL(dlr)
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
static XMLRPCDocument * msg
static void boxc_destroy(Boxc *boxc)
static int smpp_autodetect_addr
Connection * conn_wrap_fd(int fd, int ssl)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
#define ESM_CLASS_DELIVER_SMSC_DELIVER_ACK
static Octstr * bearerbox_host
static Dict * smsc_by_sender_smsbox_id
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void charset_gsm_to_utf8(Octstr *ostr)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)