#include "gwlib/gwlib.h"#include "msg.h"#include "smsc_p.h"#include "smpp_pdu.h"#include "smscconn_p.h"#include "bb_smscconn_cb.h"#include "sms.h"#include "dlr.h"#include "bearerbox.h"Include dependency graph for smsc_smpp.c:

Go to the source code of this file.
Data Structures | |
| struct | SMPP |
| struct | smpp_msg |
| struct | io_arg |
Defines | |
| #define | SMPP_DEFAULT_CHARSET "UTF-8" |
| #define | DEBUG 1 |
| #define | dump_pdu(msg, id, pdu) |
| #define | SMPP_ENQUIRE_LINK_INTERVAL 30.0 |
| #define | SMPP_MAX_PENDING_SUBMITS 10 |
| #define | SMPP_DEFAULT_VERSION 0x34 |
| #define | SMPP_DEFAULT_PRIORITY 0 |
| #define | SMPP_THROTTLING_SLEEP_TIME 15 |
| #define | SMPP_DEFAULT_CONNECTION_TIMEOUT 10 * SMPP_ENQUIRE_LINK_INTERVAL |
| #define | SMPP_DEFAULT_WAITACK 60 |
| #define | SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30 |
| #define | SMPP_WAITACK_RECONNECT 0x00 |
| #define | SMPP_WAITACK_REQUEUE 0x01 |
| #define | SMPP_WAITACK_NEVER_EXPIRE 0x02 |
Functions | |
| smpp_msg * | smpp_msg_create (Msg *msg) |
| void | smpp_msg_destroy (struct smpp_msg *msg, int destroy_msg) |
| SMPP * | smpp_create (SMSCConn *conn, Octstr *host, int transmit_port, int receive_port, Octstr *system_type, Octstr *username, Octstr *password, Octstr *address_range, int source_addr_ton, int source_addr_npi, int dest_addr_ton, int dest_addr_npi, int enquire_link_interval, int max_pending_submits, int version, int priority, int validity, Octstr *my_number, int smpp_msg_id_type, int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset, Octstr *service_type, long connection_timeout, long wait_ack, int wait_ack_action) |
| void | smpp_destroy (SMPP *smpp) |
| int | read_pdu (SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu) |
| long | convert_addr_from_pdu (Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset) |
| Msg * | pdu_to_msg (SMPP *smpp, SMPP_PDU *pdu, long *reason) |
| Msg * | data_sm_to_msg (SMPP *smpp, SMPP_PDU *pdu, long *reason) |
| long | smpp_status_to_smscconn_failure_reason (long status) |
| SMPP_PDU * | msg_to_pdu (SMPP *smpp, Msg *msg) |
| void | send_enquire_link (SMPP *smpp, Connection *conn, long *last_sent) |
| void | send_unbind (SMPP *smpp, Connection *conn) |
| int | send_pdu (Connection *conn, Octstr *id, SMPP_PDU *pdu) |
| void | send_messages (SMPP *smpp, Connection *conn, long *pending_submits) |
| Connection * | open_transmitter (SMPP *smpp) |
| Connection * | open_transceiver (SMPP *smpp) |
| Connection * | open_receiver (SMPP *smpp) |
| Msg * | handle_dlr (SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state) |
| long | smscconn_failure_reason_to_smpp_status (long reason) |
| void | handle_pdu (SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits) |
| io_arg * | io_arg_create (SMPP *smpp, int transmitter) |
| int | do_queue_cleanup (SMPP *smpp, long *pending_submits, int action) |
| void | io_thread (void *arg) |
| long | queued_cb (SMSCConn *conn) |
| int | send_msg_cb (SMSCConn *conn, Msg *msg) |
| int | shutdown_cb (SMSCConn *conn, int finish_sending) |
| int | smsc_smpp_create (SMSCConn *conn, CfgGroup *grp) |
|
|
Definition at line 90 of file smsc_smpp.c. |
|
|
Value: do { \ debug("bb.sms.smpp", 0, "SMPP[%s]: %s", \ octstr_get_cstr(id), msg); \ smpp_pdu_dump(pdu); \ } while(0) Definition at line 96 of file smsc_smpp.c. Referenced by io_thread(), send_enquire_link(), send_logoff(), send_pdu(), send_unbind(), and smasi_thread(). |
|
|
Definition at line 82 of file smsc_smpp.c. Referenced by convert_addr_from_pdu(), data_sm_to_msg(), msg_to_pdu(), and pdu_to_msg(). |
|
|
Definition at line 114 of file smsc_smpp.c. |
|
|
Definition at line 112 of file smsc_smpp.c. |
|
|
Definition at line 116 of file smsc_smpp.c. Referenced by io_thread(). |
|
|
Definition at line 111 of file smsc_smpp.c. |
|
|
Definition at line 115 of file smsc_smpp.c. |
|
|
Definition at line 109 of file smsc_smpp.c. |
|
|
Definition at line 110 of file smsc_smpp.c. |
|
|
Definition at line 113 of file smsc_smpp.c. |
|
|
Definition at line 124 of file smsc_smpp.c. |
|
|
Definition at line 122 of file smsc_smpp.c. Referenced by do_queue_cleanup(). |
|
|
Definition at line 123 of file smsc_smpp.c. Referenced by do_queue_cleanup(). |
|
||||||||||||||||||||||||
|
Definition at line 338 of file smsc_smpp.c. References charset_convert(), charset_gsm_to_utf8(), error(), GSM_ADDR_TON_ALPHANUMERIC, GSM_ADDR_TON_INTERNATIONAL, gw_isdigit(), octstr_check_range(), octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_insert_char(), octstr_len(), octstr_search(), octstr_str_case_compare(), reason, SMPP_DEFAULT_CHARSET, and warning(). Referenced by data_sm_to_msg(), and pdu_to_msg(). 00339 {
00340 long reason = SMPP_ESME_ROK;
00341
00342 if (addr == NULL)
00343 return reason;
00344
00345 switch(ton) {
00346 case GSM_ADDR_TON_INTERNATIONAL:
00347 /*
00348 * Checks to perform:
00349 * 1) assume international number has at least 7 chars
00350 * 2) the whole source addr consist of digits, exception '+' in front
00351 */
00352 if (octstr_len(addr) < 7) {
00353 /* We consider this as a "non-hard" condition, since there "may"
00354 * be international numbers routable that are < 7 digits. Think
00355 * of 2 digit country code + 3 digit emergency code. */
00356 warning(0, "SMPP[%s]: Mallformed addr `%s', generally expected at least 7 digits. ",
00357 octstr_get_cstr(id),
00358 octstr_get_cstr(addr));
00359 } else if (octstr_get_char(addr, 0) == '+' &&
00360 !octstr_check_range(addr, 1, 256, gw_isdigit)) {
00361 error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
00362 octstr_get_cstr(id),
00363 octstr_get_cstr(addr));
00364 reason = SMPP_ESME_RINVSRCADR;
00365 goto error;
00366 } else if (octstr_get_char(addr, 0) != '+' &&
00367 !octstr_check_range(addr, 0, 256, gw_isdigit)) {
00368 error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
00369 octstr_get_cstr(id),
00370 octstr_get_cstr(addr));
00371 reason = SMPP_ESME_RINVSRCADR;
00372 goto error;
00373 }
00374 /* check if we received leading '00', then remove it*/
00375 if (octstr_search(addr, octstr_imm("00"), 0) == 0)
00376 octstr_delete(addr, 0, 2);
00377
00378 /* international, insert '+' if not already here */
00379 if (octstr_get_char(addr, 0) != '+')
00380 octstr_insert_char(addr, 0, '+');
00381
00382 break;
00383 case GSM_ADDR_TON_ALPHANUMERIC:
00384 if (octstr_len(addr) > 11) {
00385 /* alphanum sender, max. allowed length is 11 (according to GSM specs) */
00386 error(0, "SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ",
00387 octstr_get_cstr(id),
00388 octstr_get_cstr(addr));
00389 reason = SMPP_ESME_RINVSRCADR;
00390 goto error;
00391 }
00392 if (alt_addr_charset) {
00393 if (octstr_str_case_compare(alt_addr_charset, "gsm") == 0)
00394 charset_gsm_to_utf8(addr);
00395 else if (charset_convert(addr, octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET) != 0)
00396 error(0, "Failed to convert address from charset <%s> to <%s>, leave as is.",
00397 octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET);
00398 }
00399 break;
00400 default: /* otherwise don't touch addr, user should handle it */
00401 break;
00402 }
00403
00404 error:
00405 return reason;
00406 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 576 of file smsc_smpp.c. References SMPP::alt_addr_charset, SMPP::alt_charset, charset_convert(), charset_gsm_to_utf8(), SMPP::conn, convert_addr_from_pdu(), data_sm, DC_7BIT, DC_UNDEF, dcs_to_fields(), debug(), error(), gw_assert, smscconn::id, msg_create, msg_destroy(), octstr_copy, octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_len(), pdu, reason, SMPP_DEFAULT_CHARSET, sms, SMPP_PDU::type, and SMPP_PDU::u. Referenced by handle_pdu(). 00577 {
00578 Msg *msg;
00579 int ton, npi;
00580
00581 gw_assert(pdu->type == data_sm);
00582
00583 msg = msg_create(sms);
00584 gw_assert(msg != NULL);
00585 *reason = SMPP_ESME_ROK;
00586
00587 /*
00588 * Reset source addr to have a prefixed '+' in case we have an
00589 * intl. TON to allow backend boxes (ie. smsbox) to distinguish
00590 * between national and international numbers.
00591 */
00592 ton = pdu->u.data_sm.source_addr_ton;
00593 npi = pdu->u.data_sm.source_addr_npi;
00594 /* check source addr */
00595 if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
00596 goto error;
00597 msg->sms.sender = pdu->u.data_sm.source_addr;
00598 pdu->u.data_sm.source_addr = NULL;
00599
00600 /*
00601 * Follows SMPP spec. v3.4. issue 1.2
00602 * it's not allowed to have destination_addr NULL
00603 */
00604 if (pdu->u.data_sm.destination_addr == NULL) {
00605 error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
00606 "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
00607 octstr_get_cstr(pdu->u.data_sm.destination_addr));
00608 *reason = SMPP_ESME_RINVDSTADR;
00609 goto error;
00610 }
00611
00612 /* Same reset of destination number as for source */
00613 ton = pdu->u.data_sm.dest_addr_ton;
00614 npi = pdu->u.data_sm.dest_addr_npi;
00615 /* check destination addr */
00616 if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
00617 goto error;
00618 msg->sms.receiver = pdu->u.data_sm.destination_addr;
00619 pdu->u.data_sm.destination_addr = NULL;
00620
00621 /* SMSCs use service_type for billing information */
00622 msg->sms.binfo = pdu->u.data_sm.service_type;
00623 pdu->u.data_sm.service_type = NULL;
00624
00625 if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
00626 msg->sms.rpi = 1;
00627
00628 msg->sms.msgdata = pdu->u.data_sm.message_payload;
00629 pdu->u.data_sm.message_payload = NULL;
00630
00631 /*
00632 * Encode udh if udhi set
00633 * for reference see GSM03.40, section 9.2.3.24
00634 */
00635 if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
00636 int udhl;
00637 udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
00638 debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
00639 octstr_get_cstr(smpp->conn->id), udhl);
00640 if (udhl > octstr_len(msg->sms.msgdata)) {
00641 error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
00642 "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
00643 udhl, octstr_len(msg->sms.msgdata));
00644 *reason = SMPP_ESME_RINVESMCLASS;
00645 goto error;
00646 }
00647 msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
00648 octstr_delete(msg->sms.msgdata, 0, udhl);
00649 }
00650
00651 dcs_to_fields(&msg, pdu->u.data_sm.data_coding);
00652
00653 /* handle default data coding */
00654 switch (pdu->u.data_sm.data_coding) {
00655 case 0x00: /* default SMSC alphabet */
00656 /*
00657 * try to convert from something interesting if specified so
00658 * unless it was specified binary, ie. UDH indicator was detected
00659 */
00660 if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {
00661 if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET) != 0)
00662 error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
00663 octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET);
00664 msg->sms.coding = DC_7BIT;
00665 } else { /* assume GSM 03.38 7-bit alphabet */
00666 charset_gsm_to_utf8(msg->sms.msgdata);
00667 msg->sms.coding = DC_7BIT;
00668 }
00669 break;
00670 case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
00671 case 0x03: /* ISO-8859-1 - do nothing */
00672 msg->sms.coding = DC_7BIT; break;
00673 case 0x02: /* 8 bit binary - do nothing */
00674 case 0x04: /* 8 bit binary - do nothing */
00675 msg->sms.coding = DC_8BIT; break;
00676 case 0x05: /* JIS - what do I do with that ? */
00677 break;
00678 case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
00679 if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UTF-8") != 0)
00680 error(0, "Failed to convert msgdata from cyrllic to UTF-8, will leave as is");
00681 msg->sms.coding = DC_7BIT; break;
00682 case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
00683 if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UTF-8") != 0)
00684 error(0, "Failed to convert msgdata from hebrew to UTF-8, will leave as is");
00685 msg->sms.coding = DC_7BIT; break;
00686 case 0x08: /* unicode UCS-2, yey */
00687 msg->sms.coding = DC_UCS2; break;
00688
00689 /*
00690 * don't much care about the others,
00691 * you implement them if you feel like it
00692 */
00693
00694 default:
00695 /*
00696 * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
00697 * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
00698 * if we have an UDH indicator, we assume DC_8BIT.
00699 */
00700 if (msg->sms.coding == DC_UNDEF && pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
00701 msg->sms.coding = DC_8BIT;
00702 else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
00703 msg->sms.coding = DC_7BIT;
00704 charset_gsm_to_utf8(msg->sms.msgdata);
00705 }
00706 }
00707
00708 return msg;
00709
00710 error:
00711 msg_destroy(msg);
00712 return NULL;
00713 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1665 of file smsc_smpp.c. References action, bb_smscconn_send_failed(), SMPP::conn, dict_get(), dict_keys(), dict_remove(), error(), gwlist_destroy(), gwlist_extract_first(), smscconn::id, smpp_msg::msg, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, SMPP::sent_msgs, smpp_msg::sent_time, smpp_msg_destroy(), SMPP_WAITACK_RECONNECT, SMPP_WAITACK_REQUEUE, SMSCCONN_FAILED_TEMPORARILY, SMPP::wait_ack, and warning(). Referenced by io_thread(). 01666 {
01667 List *keys;
01668 Octstr *key;
01669 struct smpp_msg *smpp_msg;
01670 time_t now = time(NULL);
01671
01672 if (*pending_submits <= 0)
01673 return 0;
01674
01675 /* check if action set to wait ack for ever */
01676 if (action == SMPP_WAITACK_NEVER_EXPIRE)
01677 return 0;
01678
01679 keys = dict_keys(smpp->sent_msgs);
01680 if (keys == NULL)
01681 return 0;
01682
01683 while ((key = gwlist_extract_first(keys)) != NULL) {
01684 smpp_msg = dict_get(smpp->sent_msgs, key);
01685 if (smpp_msg != NULL && difftime(now, smpp_msg->sent_time) > smpp->wait_ack) {
01686 switch(action) {
01687 case SMPP_WAITACK_RECONNECT: /* reconnect */
01688 /* found at least one not acked msg */
01689 warning(0, "SMPP[%s]: Not ACKED message found, reconnecting.",
01690 octstr_get_cstr(smpp->conn->id));
01691 octstr_destroy(key);
01692 gwlist_destroy(keys, octstr_destroy_item);
01693 return 1; /* io_thread will reconnect */
01694 case SMPP_WAITACK_REQUEUE: /* requeue */
01695 smpp_msg = dict_remove(smpp->sent_msgs, key);
01696 if (smpp_msg != NULL) {
01697 warning(0, "SMPP[%s]: Not ACKED message found, will retransmit."
01698 " SENT<%ld>sec. ago, SEQ<%s>, DST<%s>",
01699 octstr_get_cstr(smpp->conn->id),
01700 (long)difftime(now, smpp_msg->sent_time) ,
01701 octstr_get_cstr(key),
01702 octstr_get_cstr(smpp_msg->msg->sms.receiver));
01703 bb_smscconn_send_failed(smpp->conn, smpp_msg->msg, SMSCCONN_FAILED_TEMPORARILY,NULL);
01704 smpp_msg_destroy(smpp_msg, 0);
01705 (*pending_submits)--;
01706 }
01707 break;
01708 default:
01709 error(0, "SMPP[%s] Unknown clenup action defined %xd.",
01710 octstr_get_cstr(smpp->conn->id), action);
01711 octstr_destroy(key);
01712 gwlist_destroy(keys, octstr_destroy_item);
01713 return 0;
01714 }
01715 }
01716 octstr_destroy(key);
01717 }
01718 gwlist_destroy(keys, octstr_destroy_item);
01719
01720 return 0;
01721 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 1145 of file smsc_smpp.c. References SMPP::conn, debug(), dlr_find(), error(), gw_isdigit(), smscconn::id, octstr_check_range(), octstr_compare(), octstr_copy, octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_search(), octstr_search_char(), octstr_strip_blanks(), SMPP::smpp_msg_id_type, SMPP::version, and warning(). Referenced by handle_pdu(). 01146 {
01147 Msg *dlrmsg = NULL;
01148 Octstr *respstr = NULL, *msgid = NULL, *tmp;
01149 int dlrstat = -1;
01150
01151 /* first check for SMPP v3.4 and above */
01152 if (smpp->version > 0x33 && receipted_message_id) {
01153 msgid = octstr_duplicate(receipted_message_id);
01154 switch(message_state) {
01155 case 1: /* ENROUTE */
01156 case 6: /* ACCEPTED */
01157 dlrstat = DLR_BUFFERED;
01158 break;
01159 case 2: /* DELIVERED */
01160 dlrstat = DLR_SUCCESS;
01161 break;
01162 case 3: /* EXPIRED */
01163 case 4: /* DELETED */
01164 case 5: /* UNDELIVERABLE */
01165 case 7: /* UNKNOWN */
01166 case 8: /* REJECTED */
01167 dlrstat = DLR_FAIL;
01168 break;
01169 default:
01170 warning(0, "SMPP[%s]: Got DLR with unknown 'message_state' (%ld).",
01171 octstr_get_cstr(smpp->conn->id), message_state);
01172 dlrstat = DLR_FAIL;
01173 break;
01174 }
01175 }
01176
01177 /* check for SMPP v.3.4. and message_payload */
01178 if (smpp->version > 0x33 && octstr_len(short_message) == 0)
01179 respstr = message_payload;
01180 else
01181 respstr = short_message;
01182
01183 /* still no msgid ? */
01184 if (!msgid && respstr) {
01185 long curr = 0, vpos = 0;
01186 Octstr *stat = NULL;
01187 char id_cstr[65], stat_cstr[16], sub_d_cstr[13], done_d_cstr[13];
01188 int sub, dlrvrd, ret;
01189
01190 /* get server message id */
01191 /* first try sscanf way if thus failed then old way */
01192 ret = sscanf(octstr_get_cstr(respstr),
01193 "id:%64[^s] sub:%d dlvrd:%d submit date:%12[0-9] done date:%12[0-9] stat:%10[^t^e]",
01194 id_cstr, &sub, &dlrvrd, sub_d_cstr, done_d_cstr, stat_cstr);
01195 if (ret == 6) {
01196 msgid = octstr_create(id_cstr);
01197 octstr_strip_blanks(msgid);
01198 stat = octstr_create(stat_cstr);
01199 octstr_strip_blanks(stat);
01200 }
01201 else {
01202 debug("bb.sms.smpp", 0, "SMPP[%s]: Couldnot parse DLR string sscanf way,"
01203 "fallback to old way. Please report!", octstr_get_cstr(smpp->conn->id));
01204
01205 if ((curr = octstr_search(respstr, octstr_imm("id:"), 0)) != -1) {
01206 vpos = octstr_search_char(respstr, ' ', curr);
01207 if ((vpos-curr >0) && (vpos != -1))
01208 msgid = octstr_copy(respstr, curr+3, vpos-curr-3);
01209 } else {
01210 msgid = NULL;
01211 }
01212
01213 /* get err & status code */
01214 if ((curr = octstr_search(respstr, octstr_imm("stat:"), 0)) != -1) {
01215 vpos = octstr_search_char(respstr, ' ', curr);
01216 if ((vpos-curr >0) && (vpos != -1))
01217 stat = octstr_copy(respstr, curr+5, vpos-curr-5);
01218 } else {
01219 stat = NULL;
01220 }
01221 }
01222
01223 /*
01224 * we get the following status:
01225 * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD
01226 *
01227 * Note: some buggy SMSC's send us immediately delivery notifications although
01228 * we doesn't requested these.
01229 */
01230
01231 if (stat != NULL && octstr_compare(stat, octstr_imm("DELIVRD")) == 0)
01232 dlrstat = DLR_SUCCESS;
01233 else if (stat != NULL && (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0 ||
01234 octstr_compare(stat, octstr_imm("ACKED")) == 0 ||
01235 octstr_compare(stat, octstr_imm("BUFFRED")) == 0 ||
01236 octstr_compare(stat, octstr_imm("BUFFERD")) == 0 ||
01237 octstr_compare(stat, octstr_imm("ENROUTE")) == 0))
01238 dlrstat = DLR_BUFFERED;
01239 else
01240 dlrstat = DLR_FAIL;
01241
01242 if (stat != NULL)
01243 octstr_destroy(stat);
01244 }
01245
01246 if (msgid != NULL) {
01247
01248 /*
01249 * Obey which SMPP msg_id type this SMSC is using, where we
01250 * have the following semantics for the variable smpp_msg_id:
01251 *
01252 * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm
01253 *
01254 * if bit is set value is hex otherwise dec
01255 *
01256 * 0x00 deliver_sm dec, submit_sm_resp dec
01257 * 0x01 deliver_sm dec, submit_sm_resp hex
01258 * 0x02 deliver_sm hex, submit_sm_resp dec
01259 * 0x03 deliver_sm hex, submit_sm_resp hex
01260 *
01261 * Default behaviour is SMPP spec compliant, which means
01262 * msg_ids should be C strings and hence non modified.
01263 */
01264 if (smpp->smpp_msg_id_type == -1) {
01265 /* the default, C string */
01266 tmp = octstr_duplicate(msgid);
01267 } else {
01268 if ((smpp->smpp_msg_id_type & 0x02) ||
01269 (!octstr_check_range(msgid, 0, octstr_len(msgid), gw_isdigit))) {
01270 tmp = octstr_format("%lu", strtoll(octstr_get_cstr(msgid), NULL, 16));
01271 } else {
01272 tmp = octstr_format("%lu", strtoll(octstr_get_cstr(msgid), NULL, 10));
01273 }
01274 }
01275
01276 dlrmsg = dlr_find(smpp->conn->id,
01277 tmp, /* smsc message id */
01278 destination_addr, /* destination */
01279 dlrstat);
01280
01281 octstr_destroy(msgid);
01282 } else
01283 tmp = octstr_create("");
01284
01285 if (dlrmsg != NULL) {
01286 /*
01287 * we found the delivery report in our storage, so recode the
01288 * message structure.
01289 * The DLR trigger URL is indicated by msg->sms.dlr_url.
01290 */
01291 dlrmsg->sms.msgdata = octstr_duplicate(respstr);
01292 dlrmsg->sms.sms_type = report_mo;
01293 } else {
01294 error(0,"SMPP[%s]: got DLR but could not find message or was not interested "
01295 "in it id<%s> dst<%s>, type<%d>",
01296 octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp),
01297 octstr_get_cstr(destination_addr), dlrstat);
01298 }
01299 octstr_destroy(tmp);
01300
01301 return dlrmsg;
01302 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1320 of file smsc_smpp.c. References bb_alog_sms(), bb_smscconn_connected(), bb_smscconn_receive(), bb_smscconn_send_failed(), bb_smscconn_sent(), bind_receiver_resp, bind_transceiver_resp, bind_transmitter_resp, SMPP::conn, smscconn::connect_time, data_sm, data_sm_resp, data_sm_to_msg(), debug(), deliver_sm, deliver_sm_resp, dict_remove(), dlr_add(), DLR_IS_ENABLED_DEVICE, enquire_link, enquire_link_resp, error(), smscconn::flow_mutex, generic_nack, gw_isdigit(), handle_dlr(), smscconn::id, smscconn::is_stopped, smpp_msg::msg, msg_destroy(), mutex_lock, mutex_unlock, SMPP::my_number, octstr_check_range(), octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_len(), pdu, pdu_to_msg(), SMPP::quitting, reason, send_pdu(), SMPP::sent_msgs, smpp_error_to_string(), SMPP_ESME_RINVSYSID, smpp_msg_destroy(), SMPP::smpp_msg_id_type, smpp_pdu_create(), smpp_pdu_destroy(), smpp_status_to_smscconn_failure_reason(), smscconn_failure_reason_to_smpp_status(), smscconn::status, submit_sm_resp, SMPP::throttling_err_time, SMPP_PDU::type, SMPP_PDU::u, unbind, unbind_resp, and warning(). 01322 {
01323 SMPP_PDU *resp;
01324 Octstr *os;
01325 Msg *msg, *dlrmsg = NULL;
01326 long reason;
01327 long cmd_stat;
01328 struct smpp_msg *smpp_msg = NULL;
01329
01330 resp = NULL;
01331
01332 switch (pdu->type) {
01333 case data_sm:
01334 resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);
01335 /*
01336 * If SMSCConn stopped then send temp. error code
01337 */
01338 mutex_lock(smpp->conn->flow_mutex);
01339 if (smpp->conn->is_stopped) {
01340 mutex_unlock(smpp->conn->flow_mutex);
01341 resp->u.data_sm.command_status = SMPP_ESME_RX_T_APPN;
01342 break;
01343 }
01344 mutex_unlock(smpp->conn->flow_mutex);
01345 /* got a deliver ack (DLR)?
01346 * NOTE: following SMPP v3.4. spec. we are interested
01347 * only on bits 2-5 (some SMSC's send 0x44, and it's
01348 * spec. conforme)
01349 */
01350 if (pdu->u.data_sm.esm_class & (0x04|0x08)) {
01351 debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
01352 octstr_get_cstr(smpp->conn->id));
01353 dlrmsg = handle_dlr(smpp, pdu->u.data_sm.source_addr, NULL, pdu->u.data_sm.message_payload,
01354 pdu->u.data_sm.receipted_message_id, pdu->u.data_sm.message_state);
01355 if (dlrmsg != NULL) {
01356 /* passing DLR to upper layer */
01357 reason = bb_smscconn_receive(smpp->conn, dlrmsg);
01358 } else {
01359 /* no DLR will be passed, but we write an access-log entry */
01360 reason = SMSCCONN_SUCCESS;
01361 msg = data_sm_to_msg(smpp, pdu, &reason);
01362 bb_alog_sms(smpp->conn, msg, "FAILED DLR SMS");
01363 msg_destroy(msg);
01364 }
01365 resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
01366 } else { /* MO message */
01367 msg = data_sm_to_msg(smpp, pdu, &reason);
01368 if (msg == NULL || reason != SMPP_ESME_ROK) {
01369 resp->u.data_sm_resp.command_status = reason;
01370 break;
01371 }
01372 /* Replace MO destination number with my-number */
01373 if (octstr_len(smpp->my_number)) {
01374 octstr_destroy(msg->sms.receiver);
01375 msg->sms.receiver = octstr_duplicate(smpp->my_number);
01376 }
01377 time(&msg->sms.time);
01378 msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
01379 reason = bb_smscconn_receive(smpp->conn, msg);
01380 resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
01381 }
01382 break;
01383
01384 case deliver_sm:
01385 /*
01386 * If SMSCConn stopped then send temp. error code
01387 */
01388 mutex_lock(smpp->conn->flow_mutex);
01389 if (smpp->conn->is_stopped) {
01390 mutex_unlock(smpp->conn->flow_mutex);
01391 resp = smpp_pdu_create(deliver_sm_resp,
01392 pdu->u.deliver_sm.sequence_number);
01393 resp->u.deliver_sm.command_status = SMPP_ESME_RX_T_APPN;
01394 break;
01395 }
01396 mutex_unlock(smpp->conn->flow_mutex);
01397
01398 /* got a deliver ack (DLR)?
01399 * NOTE: following SMPP v3.4. spec. we are interested
01400 * only on bits 2-5 (some SMSC's send 0x44, and it's
01401 * spec. conforme)
01402 */
01403 if (pdu->u.deliver_sm.esm_class & (0x04|0x08)) {
01404
01405 debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
01406 octstr_get_cstr(smpp->conn->id));
01407
01408 dlrmsg = handle_dlr(smpp, pdu->u.deliver_sm.source_addr, pdu->u.deliver_sm.short_message, pdu->u.deliver_sm.message_payload,
01409 pdu->u.deliver_sm.receipted_message_id, pdu->u.deliver_sm.message_state);
01410 resp = smpp_pdu_create(deliver_sm_resp,
01411 pdu->u.deliver_sm.sequence_number);
01412 if (dlrmsg != NULL)
01413 reason = bb_smscconn_receive(smpp->conn, dlrmsg);
01414 else
01415 reason = SMSCCONN_SUCCESS;
01416 resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
01417 } else {/* MO-SMS */
01418 resp = smpp_pdu_create(deliver_sm_resp,
01419 pdu->u.deliver_sm.sequence_number);
01420 /* ensure the smsc-id is set */
01421 msg = pdu_to_msg(smpp, pdu, &reason);
01422 if (msg == NULL) {
01423 resp->u.deliver_sm_resp.command_status = reason;
01424 break;
01425 }
01426
01427 /* Replace MO destination number with my-number */
01428 if (octstr_len(smpp->my_number)) {
01429 octstr_destroy(msg->sms.receiver);
01430 msg->sms.receiver = octstr_duplicate(smpp->my_number);
01431 }
01432
01433 time(&msg->sms.time);
01434 msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
01435 reason = bb_smscconn_receive(smpp->conn, msg);
01436 resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
01437 }
01438 break;
01439
01440 case enquire_link:
01441 resp = smpp_pdu_create(enquire_link_resp,
01442 pdu->u.enquire_link.sequence_number);
01443 break;
01444
01445 case enquire_link_resp:
01446 break;
01447
01448 case submit_sm_resp:
01449 os = octstr_format("%ld", pdu->u.submit_sm_resp.sequence_number);
01450 smpp_msg = dict_remove(smpp->sent_msgs, os);
01451 octstr_destroy(os);
01452 if (smpp_msg == NULL) {
01453 warning(0, "SMPP[%s]: SMSC sent submit_sm_resp "
01454 "with wrong sequence number 0x%08lx",
01455 octstr_get_cstr(smpp->conn->id),
01456 pdu->u.submit_sm_resp.sequence_number);
01457 break;
01458 }
01459 msg = smpp_msg->msg;
01460 smpp_msg_destroy(smpp_msg, 0);
01461 if (pdu->u.submit_sm_resp.command_status != 0) {
01462 error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
01463 "in response to submit_sm.",
01464 octstr_get_cstr(smpp->conn->id),
01465 pdu->u.submit_sm_resp.command_status,
01466 smpp_error_to_string(pdu->u.submit_sm_resp.command_status));
01467 reason = smpp_status_to_smscconn_failure_reason(
01468 pdu->u.submit_sm_resp.command_status);
01469
01470 /*
01471 * check to see if we got a "throttling error", in which case we'll just
01472 * sleep for a while
01473 */
01474 if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
01475 time(&(smpp->throttling_err_time));
01476 else
01477 smpp->throttling_err_time = 0;
01478
01479 bb_smscconn_send_failed(smpp->conn, msg, reason,
01480 octstr_format("%ld/%s", pdu->u.submit_sm_resp.command_status,
01481 smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
01482 --(*pending_submits);
01483 } else {
01484 Octstr *tmp;
01485
01486 /* check if msg_id is C string, decimal or hex for this SMSC */
01487 if (smpp->smpp_msg_id_type == -1) {
01488 /* the default, C string */
01489 tmp = octstr_duplicate(pdu->u.submit_sm_resp.message_id);
01490 } else {
01491 if ((smpp->smpp_msg_id_type & 0x01) ||
01492 (!octstr_check_range(pdu->u.submit_sm_resp.message_id, 0,
01493 octstr_len(pdu->u.submit_sm_resp.message_id), gw_isdigit))) {
01494 tmp = octstr_format("%lu", strtoll( /* hex */
01495 octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 16));
01496 } else {
01497 tmp = octstr_format("%lu", strtoll( /* decimal */
01498 octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 10));
01499 }
01500 }
01501
01502 /* SMSC ACK.. now we have the message id. */
01503 if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask))
01504 dlr_add(smpp->conn->id, tmp, msg);
01505
01506 octstr_destroy(tmp);
01507 bb_smscconn_sent(smpp->conn, msg, NULL);
01508 --(*pending_submits);
01509 } /* end if for SMSC ACK */
01510 break;
01511
01512 case bind_transmitter_resp:
01513 if (pdu->u.bind_transmitter_resp.command_status != 0) {
01514 error(0, "SMPP[%s]: SMSC rejected login to transmit, "
01515 "code 0x%08lx (%s).",
01516 octstr_get_cstr(smpp->conn->id),
01517 pdu->u.bind_transmitter_resp.command_status,
01518 smpp_error_to_string(pdu->u.bind_transmitter_resp.command_status));
01519 if (pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSID ||
01520 pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVPASWD)
01521 smpp->quitting = 1;
01522 } else {
01523 *pending_submits = 0;
01524 mutex_lock(smpp->conn->flow_mutex);
01525 smpp->conn->status = SMSCCONN_ACTIVE;
01526 smpp->conn->connect_time = time(NULL);
01527 mutex_unlock(smpp->conn->flow_mutex);
01528 bb_smscconn_connected(smpp->conn);
01529 }
01530 break;
01531
01532 case bind_transceiver_resp:
01533 if (pdu->u.bind_transceiver_resp.command_status != 0) {
01534 error(0, "SMPP[%s]: SMSC rejected login to transmit, "
01535 "code 0x%08lx (%s).",
01536 octstr_get_cstr(smpp->conn->id),
01537 pdu->u.bind_transceiver_resp.command_status,
01538 smpp_error_to_string(pdu->u.bind_transceiver_resp.command_status));
01539 if (pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSID ||
01540 pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVPASWD)
01541 smpp->quitting = 1;
01542 } else {
01543 *pending_submits = 0;
01544 mutex_lock(smpp->conn->flow_mutex);
01545 smpp->conn->status = SMSCCONN_ACTIVE;
01546 smpp->conn->connect_time = time(NULL);
01547 mutex_unlock(smpp->conn->flow_mutex);
01548 bb_smscconn_connected(smpp->conn);
01549 }
01550 break;
01551
01552 case bind_receiver_resp:
01553 if (pdu->u.bind_receiver_resp.command_status != 0) {
01554 error(0, "SMPP[%s]: SMSC rejected login to receive, "
01555 "code 0x%08lx (%s).",
01556 octstr_get_cstr(smpp->conn->id),
01557 pdu->u.bind_receiver_resp.command_status,
01558 smpp_error_to_string(pdu->u.bind_receiver_resp.command_status));
01559 if (pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSID ||
01560 pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVPASWD)
01561 smpp->quitting = 1;
01562 } else {
01563 /* set only resceive status if no transmitt is bind */
01564 mutex_lock(smpp->conn->flow_mutex);
01565 if (smpp->conn->status != SMSCCONN_ACTIVE) {
01566 smpp->conn->status = SMSCCONN_ACTIVE_RECV;
01567 smpp->conn->connect_time = time(NULL);
01568 }
01569 mutex_unlock(smpp->conn->flow_mutex);
01570 }
01571 break;
01572
01573 case unbind:
01574 resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
01575 mutex_lock(smpp->conn->flow_mutex);
01576 smpp->conn->status = SMSCCONN_DISCONNECTED;
01577 mutex_unlock(smpp->conn->flow_mutex);
01578 break;
01579
01580 case unbind_resp:
01581 mutex_lock(smpp->conn->flow_mutex);
01582 smpp->conn->status = SMSCCONN_DISCONNECTED;
01583 mutex_unlock(smpp->conn->flow_mutex);
01584 break;
01585
01586 case generic_nack:
01587 cmd_stat = pdu->u.generic_nack.command_status;
01588
01589 os = octstr_format("%ld", pdu->u.generic_nack.sequence_number);
01590 smpp_msg = dict_remove(smpp->sent_msgs, os);
01591 octstr_destroy(os);
01592
01593 if (smpp_msg == NULL) {
01594 error(0, "SMPP[%s]: SMSC rejected last command"
01595 "code 0x%08lx (%s).",
01596 octstr_get_cstr(smpp->conn->id),
01597 cmd_stat,
01598 smpp_error_to_string(cmd_stat));
01599 } else {
01600 msg = smpp_msg->msg;
01601 smpp_msg_destroy(smpp_msg, 0);
01602
01603 error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
01604 "in response to submit_sm.",
01605 octstr_get_cstr(smpp->conn->id),
01606 cmd_stat,
01607 smpp_error_to_string(cmd_stat));
01608
01609 /*
01610 * check to see if we got a "throttling error", in which case we'll just
01611 * sleep for a while
01612 */
01613 if (cmd_stat == SMPP_ESME_RTHROTTLED)
01614 time(&(smpp->throttling_err_time));
01615 else
01616 smpp->throttling_err_time = 0;
01617
01618 reason = smpp_status_to_smscconn_failure_reason(cmd_stat);
01619 bb_smscconn_send_failed(smpp->conn, msg, reason,
01620 octstr_format("%ld/%s", cmd_stat, smpp_error_to_string(cmd_stat)));
01621 --(*pending_submits);
01622 }
01623 break;
01624 default:
01625 error(0, "SMPP[%s]: Unknown PDU type 0x%08lx, ignored.",
01626 octstr_get_cstr(smpp->conn->id), pdu->type);
01627 /*
01628 send gnack , see smpp3.4 spec., section 3.3
01629 because we doesn't know what kind of pdu received, we assume generick_nack_resp
01630 (header always the same)
01631 */
01632 resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number);
01633 resp->u.generic_nack.command_status = SMPP_ESME_RINVCMDID;
01634 break;
01635 }
01636
01637 if (resp != NULL) {
01638 send_pdu(conn, smpp->conn->id, resp);
01639 smpp_pdu_destroy(resp);
01640 }
01641 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1650 of file smsc_smpp.c. References io_arg::smpp, and SMPP::transmitter. Referenced by smsc_smpp_create(). 01651 {
01652 struct io_arg *io_arg;
01653
01654 io_arg = gw_malloc(sizeof(*io_arg));
01655 io_arg->smpp = smpp;
01656 io_arg->transmitter = transmitter;
01657 return io_arg;
01658 }
|
|
|
Definition at line 1730 of file smsc_smpp.c. References bb_smscconn_send_failed(), SMPP::conn, conn_destroy(), conn_wait(), SMPP::connection_timeout, date_universal_now(), debug(), dict_keys(), dict_remove(), do_queue_cleanup(), dump_pdu, SMPP::enquire_link_interval, error(), smscconn::flow_mutex, gwlist_destroy(), gwlist_extract_first(), gwthread_sleep(), handle_pdu(), smscconn::id, smscconn::log_idx, log_thread_to(), smpp_msg::msg, SMPP::msgs_to_send, mutex_lock, mutex_unlock, octstr_destroy(), octstr_get_cstr, open_receiver(), open_transceiver(), open_transmitter(), pdu, SMPP::quitting, read_pdu(), reason, smscconn::reconnect_delay, send_enquire_link(), send_messages(), send_unbind(), SMPP::sent_msgs, io_arg::smpp, SMPP_DEFAULT_SHUTDOWN_TIMEOUT, smpp_msg_destroy(), smpp_pdu_destroy(), SMSCCONN_ACTIVE, SMSCCONN_FAILED_SHUTDOWN, smscconn::status, SMPP::throttling_err_time, io_arg::transmitter, SMPP::wait_ack, and SMPP::wait_ack_action. Referenced by smsc_smpp_create(). 01731 {
01732 SMPP *smpp;
01733 struct io_arg *io_arg;
01734 int transmitter;
01735 Connection *conn;
01736 int ret;
01737 long last_enquire_sent;
01738 long pending_submits;
01739 long len;
01740 SMPP_PDU *pdu;
01741 double timeout;
01742 time_t last_response, last_cleanup;
01743
01744 io_arg = arg;
01745 smpp = io_arg->smpp;
01746 transmitter = io_arg->transmitter;
01747 gw_free(io_arg);
01748
01749 /* Make sure we log into our own log-file if defined */
01750 log_thread_to(smpp->conn->log_idx);
01751
01752 conn = NULL;
01753 while (!smpp->quitting) {
01754 if (transmitter == 1)
01755 conn = open_transmitter(smpp);
01756 else if (transmitter == 2)
01757 conn = open_transceiver(smpp);
01758 else
01759 conn = open_receiver(smpp);
01760
01761 last_enquire_sent = last_cleanup = last_response = date_universal_now();
01762 pending_submits = -1;
01763 len = 0;
01764 smpp->throttling_err_time = 0;
01765 for (;conn != NULL;) {
01766 timeout = last_enquire_sent + smpp->enquire_link_interval
01767 - date_universal_now();
01768
01769 if (conn_wait(conn, timeout) == -1)
01770 break;
01771
01772 /* unbind
01773 * Read so long as unbind_resp received or timeout passed. Otherwise we have
01774 * double delivered messages.
01775 */
01776 if (smpp->quitting) {
01777 send_unbind(smpp, conn);
01778 last_response = time(NULL);
01779 while(conn_wait(conn, 1.00) != -1 &&
01780 difftime(time(NULL), last_response) < SMPP_DEFAULT_SHUTDOWN_TIMEOUT &&
01781 smpp->conn->status != SMSCCONN_DISCONNECTED) {
01782 if (read_pdu(smpp, conn, &len, &pdu) == 1) {
01783 dump_pdu("Got PDU:", smpp->conn->id, pdu);
01784 handle_pdu(smpp, conn, pdu, &pending_submits);
01785 smpp_pdu_destroy(pdu);
01786 }
01787 }
01788 debug("bb.sms.smpp", 0, "SMPP[%s]: %s: break and shutting down",
01789 octstr_get_cstr(smpp->conn->id), __func__);
01790
01791 break;
01792 }
01793
01794 send_enquire_link(smpp, conn, &last_enquire_sent);
01795
01796 while ((ret = read_pdu(smpp, conn, &len, &pdu)) == 1) {
01797 last_response = time(NULL);
01798 /* Deal with the PDU we just got */
01799 dump_pdu("Got PDU:", smpp->conn->id, pdu);
01800 handle_pdu(smpp, conn, pdu, &pending_submits);
01801 smpp_pdu_destroy(pdu);
01802
01803 /*
01804 * check if we are still connected.
01805 * Note: smsc can send unbind request, so we must check it.
01806 */
01807 if (smpp->conn->status != SMSCCONN_ACTIVE && smpp->conn->status != SMSCCONN_ACTIVE_RECV) {
01808 /* we are disconnected */
01809 ret = -1;
01810 break;
01811 }
01812
01813 /* Make sure we send enquire_link even if we read a lot */
01814 send_enquire_link(smpp, conn, &last_enquire_sent);
01815
01816 /* Make sure we send even if we read a lot */
01817 if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
01818 smpp->throttling_err_time = 0;
01819 send_messages(smpp, conn, &pending_submits);
01820 }
01821 }
01822
01823 if (ret == -1) {
01824 error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
01825 octstr_get_cstr(smpp->conn->id));
01826 break;
01827 }
01828
01829 /* if no PDU was received and connection timeout was set and over the limit */
01830 if (ret == 0 && smpp->connection_timeout > 0 &&
01831 difftime(time(NULL), last_response) > smpp->connection_timeout) {
01832 error(0, "SMPP[%s]: No responses from SMSC within %ld sec. Reconnecting.",
01833 octstr_get_cstr(smpp->conn->id), smpp->connection_timeout);
01834 break;
01835 }
01836
01837
01838 /* cleanup sent queue */
01839 if (transmitter && difftime(time(NULL), last_cleanup) > smpp->wait_ack) {
01840 if (do_queue_cleanup(smpp, &pending_submits, smpp->wait_ack_action))
01841 break; /* reconnect */
01842 last_cleanup = time(NULL);
01843 }
01844
01845 if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
01846 smpp->throttling_err_time = 0;
01847 send_messages(smpp, conn, &pending_submits);
01848 }
01849 }
01850
01851 if (conn != NULL) {
01852 conn_destroy(conn);
01853 conn = NULL;
01854 }
01855 /* set reconnect status */
01856 mutex_lock(smpp->conn->flow_mutex);
01857 smpp->conn->status = SMSCCONN_RECONNECTING;
01858 mutex_unlock(smpp->conn->flow_mutex);
01859 /*
01860 * Put all queued messages back into global queue,so if
01861 * we have another link running then messages will be delivered
01862 * quickly.
01863 */
01864 if (transmitter) {
01865 Msg *msg;
01866 struct smpp_msg *smpp_msg;
01867 List *noresp;
01868 Octstr *key;
01869
01870 long reason = (smpp->quitting?SMSCCONN_FAILED_SHUTDOWN:SMSCCONN_FAILED_TEMPORARILY);
01871
01872 while((msg = gwlist_extract_first(smpp->msgs_to_send)) != NULL)
01873 bb_smscconn_send_failed(smpp->conn, msg, reason, NULL);
01874
01875 noresp = dict_keys(smpp->sent_msgs);
01876 while((key = gwlist_extract_first(noresp)) != NULL) {
01877 smpp_msg = dict_remove(smpp->sent_msgs, key);
01878 if (smpp_msg != NULL && smpp_msg->msg) {
01879 bb_smscconn_send_failed(smpp->conn, smpp_msg->msg, reason, NULL);
01880 smpp_msg_destroy(smpp_msg, 0);
01881 }
01882 octstr_destroy(key);
01883 }
01884 gwlist_destroy(noresp, NULL);
01885 }
01886 /*
01887 * Reconnect if that was a connection problem.
01888 */
01889 if (!smpp->quitting) {
01890 error(0, "SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
01891 octstr_get_cstr(smpp->conn->id), smpp->conn->reconnect_delay);
01892 gwthread_sleep(smpp->conn->reconnect_delay);
01893 }
01894 }
01895 mutex_lock(smpp->conn->flow_mutex);
01896 smpp->conn->status = SMSCCONN_DEAD;
01897 mutex_unlock(smpp->conn->flow_mutex);
01898 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 733 of file smsc_smpp.c. References SMPP::alt_addr_charset, SMPP::alt_charset, smscconn::alt_dcs, SMPP::autodetect_addr, charset_convert(), charset_utf8_to_gsm(), SMPP::conn, counter_increase(), DC_7BIT, DC_UNDEF, debug(), SMPP::dest_addr_npi, SMPP::dest_addr_ton, DLR_IS_FAIL, DLR_IS_SUCCESS, DLR_IS_SUCCESS_OR_FAIL, error(), fields_to_dcs(), gw_gmtime(), gw_isdigit(), smscconn::id, SMPP::message_id_counter, MWI_UNDEF, octstr_check_range(), octstr_delete(), octstr_duplicate, octstr_format(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_insert(), octstr_len(), octstr_replace(), octstr_str_case_compare(), pdu, SMPP::priority, SMPP::service_type, SMPP_DEFAULT_CHARSET, smpp_pdu_create(), smpp_pdu_destroy(), SMS_PARAM_UNDEFINED, SMPP::source_addr_npi, SMPP::source_addr_ton, submit_sm, SMPP_PDU::u, SMPP::validityperiod, and SMPP::version. Referenced by send_messages(). 00734 {
00735 SMPP_PDU *pdu;
00736 int validity;
00737
00738 pdu = smpp_pdu_create(submit_sm,
00739 counter_increase(smpp->message_id_counter));
00740
00741 pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);
00742 pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
00743
00744 /* Set the service type of the outgoing message. We'll use the config
00745 * directive as default and 'binfo' as specific parameter. */
00746 pdu->u.submit_sm.service_type = octstr_len(msg->sms.binfo) ?
00747 octstr_duplicate(msg->sms.binfo) : octstr_duplicate(smpp->service_type);
00748
00749 /* Check for manual override of source ton and npi values */
00750 if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
00751 pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;
00752 pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;
00753 debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
00754 octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,
00755 smpp->source_addr_npi);
00756 } else {
00757 /* setup default values */
00758 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
00759 pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
00760 }
00761
00762 if (smpp->autodetect_addr && pdu->u.submit_sm.source_addr) {
00763 /* lets see if its international or alphanumeric sender */
00764 if (octstr_get_char(pdu->u.submit_sm.source_addr, 0) == '+') {
00765 if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {
00766 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
00767 pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; /* short code */
00768 if (smpp->alt_addr_charset) {
00769 if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
00770 /* @ would break PDU if converted into GSM*/
00771 octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
00772 charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
00773 } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
00774 error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
00775 SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset));
00776 }
00777 } else {
00778 /* numeric sender address with + in front -> international (remove the +) */
00779 octstr_delete(pdu->u.submit_sm.source_addr, 0, 1);
00780 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
00781 }
00782 } else {
00783 if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {
00784 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
00785 pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
00786 if (smpp->alt_addr_charset) {
00787 if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
00788 /* @ would break PDU if converted into GSM */
00789 octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
00790 charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
00791 } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
00792 error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
00793 SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset));
00794 }
00795 }
00796 }
00797 }
00798
00799 /* Check for manual override of destination ton and npi values */
00800 if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
00801 pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;
00802 pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;
00803 debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
00804 octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,
00805 smpp->dest_addr_npi);
00806 } else {
00807 pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
00808 pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
00809 }
00810
00811 /*
00812 * if its a international number starting with +, lets remove the
00813 * '+' and set number type to international instead
00814 */
00815 if (octstr_get_char(pdu->u.submit_sm.destination_addr,0) == '+') {
00816 octstr_delete(pdu->u.submit_sm.destination_addr, 0,1);
00817 pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
00818 }
00819
00820 /* check length of src/dst address */
00821 if (octstr_len(pdu->u.submit_sm.destination_addr) > 20 ||
00822 octstr_len(pdu->u.submit_sm.source_addr) > 20) {
00823 smpp_pdu_destroy(pdu);
00824 return NULL;
00825 }
00826
00827 /*
00828 * set the data coding scheme (DCS) field
00829 * check if we have a forced value for this from the smsc-group.
00830 * Note: if message class is set, then we _must_ force alt_dcs otherwise
00831 * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
00832 * first here, because MWI and MCLASS can not be set at the same time and
00833 * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
00834 * if MWI is set.
00835 */
00836 if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
00837 pdu->u.submit_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
00838 else
00839 pdu->u.submit_sm.data_coding = fields_to_dcs(msg,
00840 (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
00841 msg->sms.alt_dcs : smpp->conn->alt_dcs));
00842
00843 /* set protocol id */
00844 if(msg->sms.pid != SMS_PARAM_UNDEFINED)
00845 pdu->u.submit_sm.protocol_id = msg->sms.pid;
00846
00847 /*
00848 * set the esm_class field
00849 * default is store and forward, plus udh and rpi if requested
00850 */
00851 pdu->u.submit_sm.esm_class = ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE;
00852 if (octstr_len(msg->sms.udhdata))
00853 pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |
00854 ESM_CLASS_SUBMIT_UDH_INDICATOR;
00855 if (msg->sms.rpi > 0)
00856 pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |
00857 ESM_CLASS_SUBMIT_RPI;
00858
00859 /*
00860 * set data segments and length
00861 */
00862
00863 pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);
00864
00865 /*
00866 * only re-encoding if using default smsc charset that is defined via
00867 * alt-charset in smsc group and if MT is not binary
00868 */
00869 if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata) == 0)) {
00870 /*
00871 * consider 3 cases:
00872 * a) data_coding 0xFX: encoding should always be GSM 03.38 charset
00873 * b) data_coding 0x00: encoding may be converted according to alt-charset
00874 * c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
00875 */
00876 if ((pdu->u.submit_sm.data_coding & 0xF0) ||
00877 (pdu->u.submit_sm.data_coding == 0 && !smpp->alt_charset)) {
00878 charset_utf8_to_gsm(pdu->u.submit_sm.short_message);
00879 } else if (pdu->u.submit_sm.data_coding == 0 && smpp->alt_charset) {
00880 /*
00881 * convert to the given alternative charset
00882 */
00883 if (charset_convert(pdu->u.submit_sm.short_message, SMPP_DEFAULT_CHARSET,
00884 octstr_get_cstr(smpp->alt_charset)) != 0)
00885 error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
00886 SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_charset));
00887 }
00888 }
00889
00890 /* prepend udh if present */
00891 if (octstr_len(msg->sms.udhdata)) {
00892 octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);
00893 }
00894
00895 pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message);
00896
00897 /*
00898 * check for validity and defered settings
00899 * were message value has higher priiority then smsc config group value
00900 */
00901 validity = msg->sms.validity >= 0 ? msg->sms.validity : smpp->validityperiod;
00902 if (validity >= 0) {
00903 struct tm tm = gw_gmtime(time(NULL) + validity * 60);
00904 pdu->u.submit_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",
00905 tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
00906 tm.tm_hour, tm.tm_min, tm.tm_sec);
00907 }
00908
00909 if (msg->sms.deferred >= 0) {
00910 struct tm tm = gw_gmtime(time(NULL) + msg->sms.deferred * 60);
00911 pdu->u.submit_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",
00912 tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
00913 tm.tm_hour, tm.tm_min, tm.tm_sec);
00914 }
00915
00916 /* ask for the delivery reports if needed */
00917 if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
00918 pdu->u.submit_sm.registered_delivery = 1;
00919 else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
00920 pdu->u.submit_sm.registered_delivery = 2;
00921
00922 /* set priority */
00923 if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
00924 pdu->u.submit_sm.priority_flag = msg->sms.priority;
00925 else
00926 pdu->u.submit_sm.priority_flag = smpp->priority;
00927
00928 /* set more messages to send */
00929 if (smpp->version > 0x33 && msg->sms.msg_left > 0)
00930 pdu->u.submit_sm.more_messages_to_send = 1;
00931
00932 return pdu;
00933 }
|
Here is the call graph for this function:

|
|
Definition at line 1112 of file smsc_smpp.c. References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, bind_receiver, SMPP::conn, conn_open_tcp(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::password, SMPP::receive_port, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::system_type, SMPP_PDU::u, SMPP::username, and SMPP::version. Referenced by io_thread(). 01113 {
01114 SMPP_PDU *bind;
01115 Connection *conn;
01116
01117 conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host );
01118 if (conn == NULL) {
01119 error(0, "SMPP[%s]: Couldn't connect to server.",
01120 octstr_get_cstr(smpp->conn->id));
01121 return NULL;
01122 }
01123
01124 bind = smpp_pdu_create(bind_receiver,
01125 counter_increase(smpp->message_id_counter));
01126 bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username);
01127 bind->u.bind_receiver.password = octstr_duplicate(smpp->password);
01128 if (smpp->system_type == NULL)
01129 bind->u.bind_receiver.system_type = octstr_create("VMA");
01130 else
01131 bind->u.bind_receiver.system_type =
01132 octstr_duplicate(smpp->system_type);
01133 bind->u.bind_receiver.interface_version = smpp->version;
01134 bind->u.bind_receiver.address_range =
01135 octstr_duplicate(smpp->address_range);
01136 bind->u.bind_receiver.addr_ton = smpp->bind_addr_ton;
01137 bind->u.bind_receiver.addr_npi = smpp->bind_addr_npi;
01138 send_pdu(conn, smpp->conn->id, bind);
01139 smpp_pdu_destroy(bind);
01140
01141 return conn;
01142 }
|
Here is the call graph for this function:

|
|
Definition at line 1076 of file smsc_smpp.c. References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, bind_transceiver, SMPP::conn, conn_open_tcp(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::password, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::system_type, SMPP::transmit_port, SMPP_PDU::u, SMPP::username, and SMPP::version. Referenced by io_thread(). 01077 {
01078 SMPP_PDU *bind;
01079 Connection *conn;
01080
01081 conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host );
01082 if (conn == NULL) {
01083 error(0, "SMPP[%s]: Couldn't connect to server.",
01084 octstr_get_cstr(smpp->conn->id));
01085 return NULL;
01086 }
01087
01088 bind = smpp_pdu_create(bind_transceiver,
01089 counter_increase(smpp->message_id_counter));
01090 bind->u.bind_transceiver.system_id = octstr_duplicate(smpp->username);
01091 bind->u.bind_transceiver.password = octstr_duplicate(smpp->password);
01092 if (smpp->system_type == NULL)
01093 bind->u.bind_transceiver.system_type = octstr_create("VMA");
01094 else
01095 bind->u.bind_transceiver.system_type = octstr_duplicate(smpp->system_type);
01096 bind->u.bind_transceiver.interface_version = smpp->version;
01097 bind->u.bind_transceiver.address_range = octstr_duplicate(smpp->address_range);
01098 bind->u.bind_transceiver.addr_ton = smpp->bind_addr_ton;
01099 bind->u.bind_transceiver.addr_npi = smpp->bind_addr_npi;
01100 send_pdu(conn, smpp->conn->id, bind);
01101 smpp_pdu_destroy(bind);
01102
01103 return conn;
01104 }
|
Here is the call graph for this function:

|
|
Definition at line 1038 of file smsc_smpp.c. References SMPP::address_range, SMPP::bind_addr_npi, SMPP::bind_addr_ton, bind_transmitter, SMPP::conn, conn_open_tcp(), counter_increase(), error(), SMPP::host, smscconn::id, SMPP::message_id_counter, octstr_create, octstr_duplicate, octstr_get_cstr, smscconn::our_host, SMPP::password, send_pdu(), smpp_pdu_create(), smpp_pdu_destroy(), SMPP::system_type, SMPP::transmit_port, SMPP_PDU::u, SMPP::username, and SMPP::version. Referenced by io_thread(). 01039 {
01040 SMPP_PDU *bind;
01041 Connection *conn;
01042
01043 conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host );
01044 if (conn == NULL) {
01045 error(0, "SMPP[%s]: Couldn't connect to server.",
01046 octstr_get_cstr(smpp->conn->id));
01047 return NULL;
01048 }
01049
01050 bind = smpp_pdu_create(bind_transmitter,
01051 counter_increase(smpp->message_id_counter));
01052 bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username);
01053 bind->u.bind_transmitter.password = octstr_duplicate(smpp->password);
01054 if (smpp->system_type == NULL)
01055 bind->u.bind_transmitter.system_type = octstr_create("VMA");
01056 else
01057 bind->u.bind_transmitter.system_type =
01058 octstr_duplicate(smpp->system_type);
01059 bind->u.bind_transmitter.interface_version = smpp->version;
01060 bind->u.bind_transmitter.address_range =
01061 octstr_duplicate(smpp->address_range);
01062 bind->u.bind_transmitter.addr_ton = smpp->bind_addr_ton;
01063 bind->u.bind_transmitter.addr_npi = smpp->bind_addr_npi;
01064 send_pdu(conn, smpp->conn->id, bind);
01065 smpp_pdu_destroy(bind);
01066
01067 return conn;
01068 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 416 of file smsc_smpp.c. References SMPP::alt_addr_charset, SMPP::alt_charset, charset_convert(), charset_gsm_to_utf8(), SMPP::conn, convert_addr_from_pdu(), DC_7BIT, DC_UNDEF, dcs_to_fields(), debug(), deliver_sm, error(), gw_assert, smscconn::id, msg_create, msg_destroy(), octstr_copy, octstr_delete(), octstr_get_char(), octstr_get_cstr, octstr_len(), pdu, reason, SMPP_DEFAULT_CHARSET, sms, SMPP_PDU::type, SMPP_PDU::u, and SMPP::version. Referenced by handle_pdu(). 00417 {
00418 Msg *msg;
00419 int ton, npi;
00420
00421 gw_assert(pdu->type == deliver_sm);
00422
00423 msg = msg_create(sms);
00424 gw_assert(msg != NULL);
00425 *reason = SMPP_ESME_ROK;
00426
00427 /*
00428 * Reset source addr to have a prefixed '+' in case we have an
00429 * intl. TON to allow backend boxes (ie. smsbox) to distinguish
00430 * between national and international numbers.
00431 */
00432 ton = pdu->u.deliver_sm.source_addr_ton;
00433 npi = pdu->u.deliver_sm.source_addr_npi;
00434 /* check source addr */
00435 if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
00436 goto error;
00437 msg->sms.sender = pdu->u.deliver_sm.source_addr;
00438 pdu->u.deliver_sm.source_addr = NULL;
00439
00440 /*
00441 * Follows SMPP spec. v3.4. issue 1.2
00442 * it's not allowed to have destination_addr NULL
00443 */
00444 if (pdu->u.deliver_sm.destination_addr == NULL) {
00445 error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
00446 "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
00447 octstr_get_cstr(pdu->u.deliver_sm.destination_addr));
00448 *reason = SMPP_ESME_RINVDSTADR;
00449 goto error;
00450 }
00451
00452 /* Same reset of destination number as for source */
00453 ton = pdu->u.deliver_sm.dest_addr_ton;
00454 npi = pdu->u.deliver_sm.dest_addr_npi;
00455 /* check destination addr */
00456 if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
00457 goto error;
00458 msg->sms.receiver = pdu->u.deliver_sm.destination_addr;
00459 pdu->u.deliver_sm.destination_addr = NULL;
00460
00461 /* SMSCs use service_type for billing information */
00462 msg->sms.binfo = pdu->u.deliver_sm.service_type;
00463 pdu->u.deliver_sm.service_type = NULL;
00464
00465 if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
00466 msg->sms.rpi = 1;
00467
00468 /*
00469 * Check for message_payload if version > 0x33 and sm_length == 0
00470 * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!
00471 */
00472 if (smpp->version > 0x33 && pdu->u.deliver_sm.sm_length == 0 && pdu->u.deliver_sm.message_payload) {
00473 msg->sms.msgdata = pdu->u.deliver_sm.message_payload;
00474 pdu->u.deliver_sm.message_payload = NULL;
00475 }
00476 else {
00477 msg->sms.msgdata = pdu->u.deliver_sm.short_message;
00478 pdu->u.deliver_sm.short_message = NULL;
00479 }
00480
00481 /*
00482 * Encode udh if udhi set
00483 * for reference see GSM03.40, section 9.2.3.24
00484 */
00485 if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
00486 int udhl;
00487 udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
00488 debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
00489 octstr_get_cstr(smpp->conn->id), udhl);
00490 if (udhl > octstr_len(msg->sms.msgdata)) {
00491 error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
00492 "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
00493 udhl, octstr_len(msg->sms.msgdata));
00494 *reason = SMPP_ESME_RINVESMCLASS;
00495 goto error;
00496 }
00497 msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
00498 octstr_delete(msg->sms.msgdata, 0, udhl);
00499 }
00500
00501 dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
00502
00503 /* handle default data coding */
00504 switch (pdu->u.deliver_sm.data_coding) {
00505 case 0x00: /* default SMSC alphabet */
00506 /*
00507 * try to convert from something interesting if specified so
00508 * unless it was specified binary, ie. UDH indicator was detected
00509 */
00510 if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {
00511 if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET) != 0)
00512 error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
00513 octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET);
00514 msg->sms.coding = DC_7BIT;
00515 } else { /* assume GSM 03.38 7-bit alphabet */
00516 charset_gsm_to_utf8(msg->sms.msgdata);
00517 msg->sms.coding = DC_7BIT;
00518 }
00519 break;
00520 case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
00521 case 0x03: /* ISO-8859-1 - do nothing */
00522 msg->sms.coding = DC_7BIT; break;
00523 case 0x02: /* 8 bit binary - do nothing */
00524 case 0x04: /* 8 bit binary - do nothing */
00525 msg->sms.coding = DC_8BIT; break;
00526 case 0x05: /* JIS - what do I do with that ? */
00527 break;
00528 case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
00529 if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UTF-8") != 0)
00530 error(0, "Failed to convert msgdata from cyrllic to UTF-8, will leave as is");
00531 msg->sms.coding = DC_7BIT; break;
00532 case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
00533 if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UTF-8") != 0)
00534 error(0, "Failed to convert msgdata from hebrew to UTF-8, will leave as is");
00535 msg->sms.coding = DC_7BIT; break;
00536 case 0x08: /* unicode UCS-2, yey */
00537 msg->sms.coding = DC_UCS2; break;
00538
00539 /*
00540 * don't much care about the others,
00541 * you implement them if you feel like it
00542 */
00543
00544 default:
00545 /*
00546 * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
00547 * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
00548 * if we have an UDH indicator, we assume DC_8BIT.
00549 */
00550 if (msg->sms.coding == DC_UNDEF && pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
00551 msg->sms.coding = DC_8BIT;
00552 else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
00553 msg->sms.coding = DC_7BIT;
00554 charset_gsm_to_utf8(msg->sms.msgdata);
00555 }
00556 }
00557 msg->sms.pid = pdu->u.deliver_sm.protocol_id;
00558
00559 /* set priority flag */
00560 msg->sms.priority = pdu->u.deliver_sm.priority_flag;
00561
00562 return msg;
00563
00564 error:
00565 msg_destroy(msg);
00566 return NULL;
00567 }
|
Here is the call graph for this function:

|
|
Definition at line 1906 of file smsc_smpp.c. References smscconn::data, gwlist_len(), smscconn::load, SMPP::msgs_to_send, SMSCConn, SMSCCONN_DEAD, and smscconn::status. 01907 {
01908 SMPP *smpp;
01909
01910 smpp = conn->data;
01911 conn->load = (smpp ? (conn->status != SMSCCONN_DEAD ?
01912 gwlist_len(smpp->msgs_to_send) : 0) : 0);
01913 return conn->load;
01914 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 297 of file smsc_smpp.c. References SMPP::conn, conn_eof(), conn_error(), debug(), error(), smscconn::id, octstr_destroy(), octstr_dump, octstr_get_cstr, pdu, smpp_pdu_read_data(), smpp_pdu_read_len(), and smpp_pdu_unpack(). Referenced by io_thread(), and smasi_thread(). 00298 {
00299 Octstr *os;
00300
00301 if (*len == 0) {
00302 *len = smpp_pdu_read_len(conn);
00303 if (*len == -1) {
00304 error(0, "SMPP[%s]: Server sent garbage, ignored.",
00305 octstr_get_cstr(smpp->conn->id));
00306 return -1;
00307 } else if (*len == 0) {
00308 if (conn_eof(conn) || conn_error(conn))
00309 return -1;
00310 return 0;
00311 }
00312 }
00313
00314 os = smpp_pdu_read_data(conn, *len);
00315 if (os == NULL) {
00316 if (conn_eof(conn) || conn_error(conn))
00317 return -1;
00318 return 0;
00319 }
00320 *len = 0;
00321
00322 *pdu = smpp_pdu_unpack(os);
00323 if (*pdu == NULL) {
00324 error(0, "SMPP[%s]: PDU unpacking failed.",
00325 octstr_get_cstr(smpp->conn->id));
00326 debug("bb.sms.smpp", 0, "SMPP[%s]: Failed PDU follows.",
00327 octstr_get_cstr(smpp->conn->id));
00328 octstr_dump(os, 0);
00329 octstr_destroy(os);
00330 return -1;
00331 }
00332
00333 octstr_destroy(os);
00334 return 1;
00335 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 936 of file smsc_smpp.c. References SMPP::conn, conn_write(), counter_increase(), date_universal_now(), dump_pdu, enquire_link, SMPP::enquire_link_interval, smscconn::id, SMPP::message_id_counter, octstr_destroy(), pdu, smpp_pdu_create(), smpp_pdu_destroy(), and smpp_pdu_pack(). Referenced by io_thread(), and smasi_thread(). 00937 {
00938 SMPP_PDU *pdu;
00939 Octstr *os;
00940
00941 if (date_universal_now() - *last_sent < smpp->enquire_link_interval)
00942 return;
00943 *last_sent = date_universal_now();
00944
00945 pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));
00946 dump_pdu("Sending enquire link:", smpp->conn->id, pdu);
00947 os = smpp_pdu_pack(pdu);
00948 if (os)
00949 conn_write(conn, os); /* Write errors checked by caller. */
00950 octstr_destroy(os);
00951 smpp_pdu_destroy(pdu);
00952 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 984 of file smsc_smpp.c. References bb_smscconn_send_failed(), SMPP::conn, dict_put(), gwlist_extract_first(), gwthread_sleep(), smscconn::id, SMPP::max_pending_submits, msg_to_pdu(), SMPP::msgs_to_send, octstr_create, octstr_destroy(), octstr_format(), pdu, send_pdu(), SMPP::sent_msgs, smpp_msg_create(), smpp_pdu_destroy(), SMSCCONN_FAILED_MALFORMED, SMSCCONN_FAILED_TEMPORARILY, smscconn::throughput, and SMPP_PDU::u. Referenced by io_thread(), and smasi_thread(). 00985 {
00986 Msg *msg;
00987 SMPP_PDU *pdu;
00988 Octstr *os;
00989 double delay = 0;
00990
00991 if (*pending_submits == -1)
00992 return;
00993
00994 if (smpp->conn->throughput > 0) {
00995 delay = 1.0 / smpp->conn->throughput;
00996 }
00997
00998 while (*pending_submits < smpp->max_pending_submits) {
00999 /* Get next message, quit if none to be sent */
01000 msg = gwlist_extract_first(smpp->msgs_to_send);
01001 if (msg == NULL)
01002 break;
01003
01004 /* Send PDU, record it as waiting for ack from SMS center */
01005 pdu = msg_to_pdu(smpp, msg);
01006 if (pdu == NULL) {
01007 bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED SMS"));
01008 continue;
01009 }
01010 /* check for write errors */
01011 if (send_pdu(conn, smpp->conn->id, pdu) == 0) {
01012 struct smpp_msg *smpp_msg = smpp_msg_create(msg);
01013 os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
01014 dict_put(smpp->sent_msgs, os, smpp_msg);
01015 smpp_pdu_destroy(pdu);
01016 octstr_destroy(os);
01017 ++(*pending_submits);
01018 /*
01019 * obey throughput speed limit, if any.
01020 */
01021 if (smpp->conn->throughput > 0)
01022 gwthread_sleep(delay);
01023 }
01024 else { /* write error occurs */
01025 smpp_pdu_destroy(pdu);
01026 bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
01027 break;
01028 }
01029 }
01030 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1917 of file smsc_smpp.c. References smscconn::data, gwlist_produce(), gwthread_wakeup(), msg_duplicate(), SMPP::msgs_to_send, SMSCConn, and SMPP::transmitter. 01918 {
01919 SMPP *smpp;
01920
01921 smpp = conn->data;
01922 gwlist_produce(smpp->msgs_to_send, msg_duplicate(msg));
01923 gwthread_wakeup(smpp->transmitter);
01924 return 0;
01925 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 968 of file smsc_smpp.c. References conn_write(), dump_pdu, octstr_destroy(), pdu, and smpp_pdu_pack(). 00969 {
00970 Octstr *os;
00971 int ret;
00972
00973 dump_pdu("Sending PDU:", id, pdu);
00974 os = smpp_pdu_pack(pdu);
00975 if (os)
00976 ret = conn_write(conn, os); /* Caller checks for write errors later */
00977 else
00978 ret = -1;
00979 octstr_destroy(os);
00980 return ret;
00981 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 955 of file smsc_smpp.c. References SMPP::conn, conn_write(), counter_increase(), dump_pdu, smscconn::id, SMPP::message_id_counter, octstr_destroy(), pdu, smpp_pdu_create(), smpp_pdu_destroy(), smpp_pdu_pack(), and unbind. Referenced by io_thread(). 00956 {
00957 SMPP_PDU *pdu;
00958 Octstr *os;
00959 pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));
00960 dump_pdu("Sending unbind:", smpp->conn->id, pdu);
00961 os = smpp_pdu_pack(pdu);
00962 conn_write(conn, os);
00963 octstr_destroy(os);
00964 smpp_pdu_destroy(pdu);
00965 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1928 of file smsc_smpp.c. References bb_smscconn_killed(), smscconn::data, debug(), gwthread_join(), gwthread_wakeup(), smscconn::name, octstr_get_cstr, SMPP::quitting, SMPP::receiver, smpp_destroy(), SMSCConn, smscconn::status, SMPP::transmitter, and smscconn::why_killed. 01929 {
01930 SMPP *smpp;
01931
01932 debug("bb.smpp", 0, "Shutting down SMSCConn %s (%s)",
01933 octstr_get_cstr(conn->name),
01934 finish_sending ? "slow" : "instant");
01935
01936 conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
01937
01938 /* XXX implement finish_sending */
01939
01940 smpp = conn->data;
01941 smpp->quitting = 1;
01942 if (smpp->transmitter != -1) {
01943 gwthread_wakeup(smpp->transmitter);
01944 gwthread_join(smpp->transmitter);
01945 }
01946 if (smpp->receiver != -1) {
01947 gwthread_wakeup(smpp->receiver);
01948 gwthread_join(smpp->receiver);
01949 }
01950 smpp_destroy(smpp);
01951
01952 debug("bb.smpp", 0, "SMSCConn %s shut down.",
01953 octstr_get_cstr(conn->name));
01954 conn->status = SMSCCONN_DEAD;
01955 bb_smscconn_killed();
01956 return 0;
01957 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 209 of file smsc_smpp.c. References counter_create(), counter_increase(), dict_create(), gwlist_add_producer(), gwlist_create, SMPP::msgs_to_send, octstr_duplicate, password, SMPP::receiver, SMSCConn, SMPP::transmitter, and username. Referenced by smsc_smpp_create(). 00221 {
00222 SMPP *smpp;
00223
00224 smpp = gw_malloc(sizeof(*smpp));
00225 smpp->transmitter = -1;
00226 smpp->receiver = -1;
00227 smpp->msgs_to_send = gwlist_create();
00228 smpp->sent_msgs = dict_create(max_pending_submits, NULL);
00229 gwlist_add_producer(smpp->msgs_to_send);
00230 smpp->received_msgs = gwlist_create();
00231 smpp->message_id_counter = counter_create();
00232 counter_increase(smpp->message_id_counter);
00233 smpp->host = octstr_duplicate(host);
00234 smpp->system_type = octstr_duplicate(system_type);
00235 smpp->username = octstr_duplicate(username);
00236 smpp->password = octstr_duplicate(password);
00237 smpp->address_range = octstr_duplicate(address_range);
00238 smpp->source_addr_ton = source_addr_ton;
00239 smpp->source_addr_npi = source_addr_npi;
00240 smpp->dest_addr_ton = dest_addr_ton;
00241 smpp->dest_addr_npi = dest_addr_npi;
00242 smpp->my_number = octstr_duplicate(my_number);
00243 smpp->service_type = octstr_duplicate(service_type);
00244 smpp->transmit_port = transmit_port;
00245 smpp->receive_port = receive_port;
00246 smpp->enquire_link_interval = enquire_link_interval;
00247 smpp->max_pending_submits = max_pending_submits;
00248 smpp->quitting = 0;
00249 smpp->version = version;
00250 smpp->priority = priority;
00251 smpp->validityperiod = validity;
00252 smpp->conn = conn;
00253 smpp->throttling_err_time = 0;
00254 smpp->smpp_msg_id_type = smpp_msg_id_type;
00255 smpp->autodetect_addr = autodetect_addr;
00256 smpp->alt_charset = octstr_duplicate(alt_charset);
00257 smpp->alt_addr_charset = octstr_duplicate(alt_addr_charset);
00258 smpp->connection_timeout = connection_timeout;
00259 smpp->wait_ack = wait_ack;
00260 smpp->wait_ack_action = wait_ack_action;
00261 smpp->bind_addr_ton = 0;
00262 smpp->bind_addr_npi = 0;
00263
00264 return smpp;
00265 }
|
Here is the call graph for this function:

|
Here is the call graph for this function:

|
|
Definition at line 181 of file smsc_smpp.c. References gw_assert, smpp_msg::msg, result, and smpp_msg::sent_time. Referenced by send_messages(). 00182 {
00183 struct smpp_msg *result = gw_malloc(sizeof(struct smpp_msg));
00184
00185 gw_assert(result != NULL);
00186 result->sent_time = time(NULL);
00187 result->msg = msg;
00188
00189 return result;
00190 }
|
|
||||||||||||
|
Definition at line 196 of file smsc_smpp.c. References smpp_msg::msg, and msg_destroy(). Referenced by do_queue_cleanup(), handle_pdu(), and io_thread(). 00197 {
00198 /* sanity check */
00199 if (msg == NULL)
00200 return;
00201
00202 if (destroy_msg && msg->msg != NULL)
00203 msg_destroy(msg->msg);
00204
00205 gw_free(msg);
00206 }
|
Here is the call graph for this function:

|
|
Definition at line 717 of file smsc_smpp.c. References SMPP_ESME_RMSGQFUL, SMPP_ESME_RSYSERR, SMPP_ESME_RTHROTTLED, and SMPP_ESME_RX_T_APPN. Referenced by handle_pdu(). 00718 {
00719 switch(status) {
00720 case SMPP_ESME_RMSGQFUL:
00721 case SMPP_ESME_RTHROTTLED:
00722 case SMPP_ESME_RX_T_APPN:
00723 case SMPP_ESME_RSYSERR:
00724 return SMSCCONN_FAILED_TEMPORARILY;
00725 break;
00726
00727 default:
00728 return SMSCCONN_FAILED_REJECTED;
00729 }
00730 }
|
|
||||||||||||
|
Definition at line 1966 of file smsc_smpp.c. References SMPP::bind_addr_npi, SMPP::bind_addr_ton, cfg_get, cfg_get_bool(), cfg_get_integer(), SMPP::conn, smscconn::data, error(), gwthread_create, gwthread_join(), gwthread_wakeup(), smscconn::id, io_arg_create(), io_thread(), smscconn::name, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), ok, panic, password, port, smscconn::queued, SMPP::quitting, SMPP::receiver, smscconn::send_msg, smscconn::shutdown, smpp_create(), smpp_destroy(), SMSCConn, smscconn::status, SMPP::transmitter, username, and warning(). Referenced by smscconn_create(). 01967 {
01968 Octstr *host;
01969 long port;
01970 long receive_port;
01971 Octstr *username;
01972 Octstr *password;
01973 Octstr *system_id;
01974 Octstr *system_type;
01975 Octstr *address_range;
01976 long source_addr_ton;
01977 long source_addr_npi;
01978 long dest_addr_ton;
01979 long dest_addr_npi;
01980 Octstr *my_number;
01981 Octstr *service_type;
01982 SMPP *smpp;
01983 int ok;
01984 int transceiver_mode;
01985 Octstr *smsc_id;
01986 long enquire_link_interval;
01987 long max_pending_submits;
01988 long version;
01989 long priority;
01990 long validity;
01991 long smpp_msg_id_type;
01992 int autodetect_addr;
01993 Octstr *alt_charset;
01994 Octstr *alt_addr_charset;
01995 long connection_timeout, wait_ack, wait_ack_action;
01996
01997 my_number = alt_addr_charset = alt_charset = NULL;
01998 transceiver_mode = 0;
01999 autodetect_addr = 1;
02000
02001 host = cfg_get(grp, octstr_imm("host"));
02002 if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1)
02003 port = 0;
02004 if (cfg_get_integer(&receive_port, grp, octstr_imm("receive-port")) == -1)
02005 receive_port = 0;
02006 cfg_get_bool(&transceiver_mode, grp, octstr_imm("transceiver-mode"));
02007 username = cfg_get(grp, octstr_imm("smsc-username"));
02008 password = cfg_get(grp, octstr_imm("smsc-password"));
02009 system_type = cfg_get(grp, octstr_imm("system-type"));
02010 address_range = cfg_get(grp, octstr_imm("address-range"));
02011 my_number = cfg_get(grp, octstr_imm("my-number"));
02012 service_type = cfg_get(grp, octstr_imm("service-type"));
02013
02014 system_id = cfg_get(grp, octstr_imm("system-id"));
02015 if (system_id != NULL) {
02016 warning(0, "SMPP: obsolete system-id variable is set, "
02017 "use smsc-username instead.");
02018 if (username == NULL) {
02019 warning(0, "SMPP: smsc-username not set, using system-id instead");
02020 username = system_id;
02021 } else
02022 octstr_destroy(system_id);
02023 }
02024
02025 /*
02026 * check if timing values have been configured, otherwise
02027 * use the predefined default values.
02028 */
02029 if (cfg_get_integer(&enquire_link_interval, grp,
02030 octstr_imm("enquire-link-interval")) == -1)
02031 enquire_link_interval = SMPP_ENQUIRE_LINK_INTERVAL;
02032 if (cfg_get_integer(&max_pending_submits, grp,
02033 octstr_imm("max-pending-submits")) == -1)
02034 max_pending_submits = SMPP_MAX_PENDING_SUBMITS;
02035
02036 /* Check that config is OK */
02037 ok = 1;
02038 if (host == NULL) {
02039 error(0,"SMPP: Configuration file doesn't specify host");
02040 ok = 0;
02041 }
02042 if (username == NULL) {
02043 error(0, "SMPP: Configuration file doesn't specify username.");
02044 ok = 0;
02045 }
02046 if (password == NULL) {
02047 error(0, "SMPP: Configuration file doesn't specify password.");
02048 ok = 0;
02049 }
02050 if (system_type == NULL) {
02051 error(0, "SMPP: Configuration file doesn't specify system-type.");
02052 ok = 0;
02053 }
02054 if (octstr_len(service_type) > 6) {
02055 error(0, "SMPP: Service type must be 6 characters or less.");
02056 ok = 0;
02057 }
02058
02059 if (!ok)
02060 return -1;
02061
02062 /* if the ton and npi values are forced, set them, else set them to -1 */
02063 if (cfg_get_integer(&source_addr_ton, grp,
02064 octstr_imm("source-addr-ton")) == -1)
02065 source_addr_ton = -1;
02066 if (cfg_get_integer(&source_addr_npi, grp,
02067 octstr_imm("source-addr-npi")) == -1)
02068 source_addr_npi = -1;
02069 if (cfg_get_integer(&dest_addr_ton, grp,
02070 octstr_imm("dest-addr-ton")) == -1)
02071 dest_addr_ton = -1;
02072 if (cfg_get_integer(&dest_addr_npi, grp,
02073 octstr_imm("dest-addr-npi")) == -1)
02074 dest_addr_npi = -1;
02075
02076 /* if source addr autodetection should be used set this to 1 */
02077 if (cfg_get_bool(&autodetect_addr, grp, octstr_imm("source-addr-autodetect")) == -1)
02078 autodetect_addr = 1; /* default is autodetect if no option defined */
02079
02080 /* check for any specified interface version */
02081 if (cfg_get_integer(&version, grp, octstr_imm("interface-version")) == -1)
02082 version = SMPP_DEFAULT_VERSION;
02083 else
02084 /* convert decimal to BCD */
02085 version = ((version / 10) << 4) + (version % 10);
02086
02087 /* check for any specified priority value in range [0-5] */
02088 if (cfg_get_integer(&priority, grp, octstr_imm("priority")) == -1)
02089 priority = SMPP_DEFAULT_PRIORITY;
02090 else if (priority < 0 || priority > 3)
02091 panic(0, "SMPP: Invalid value for priority directive in configuraton (allowed range 0-3).");
02092
02093 /* check for message validity period */
02094 if (cfg_get_integer(&validity, grp, octstr_imm("validityperiod")) == -1)
02095 validity = -1;
02096 else if (validity < 0)
02097 panic(0, "SMPP: Invalid value for validity period (allowed value >= 0).");
02098
02099 /* set the msg_id type variable for this SMSC */
02100 if (cfg_get_integer(&smpp_msg_id_type, grp, octstr_imm("msg-id-type")) == -1) {
02101 /*
02102 * defaults to C string "as-is" style
02103 */
02104 smpp_msg_id_type = -1;
02105 } else {
02106 if (smpp_msg_id_type < 0 || smpp_msg_id_type > 3)
02107 panic(0,"SMPP: Invalid value for msg-id-type directive in configuraton");
02108 }
02109
02110 /* check for an alternative charset */
02111 alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
02112 alt_addr_charset = cfg_get(grp, octstr_imm("alt-addr-charset"));
02113
02114 /* check for connection timeout */
02115 if (cfg_get_integer(&connection_timeout, grp, octstr_imm("connection-timeout")) == -1)
02116 connection_timeout = SMPP_DEFAULT_CONNECTION_TIMEOUT;
02117
02118 /* check if wait-ack timeout set */
02119 if (cfg_get_integer(&wait_ack, grp, octstr_imm("wait-ack")) == -1)
02120 wait_ack = SMPP_DEFAULT_WAITACK;
02121
02122 if (cfg_get_integer(&wait_ack_action, grp, octstr_imm("wait-ack-expire")) == -1)
02123 wait_ack_action = SMPP_WAITACK_REQUEUE;
02124
02125 if (wait_ack_action > 0x03 || wait_ack_action < 0)
02126 panic(0, "SMPP: Invalid wait-ack-expire directive in configuration.");
02127
02128 smpp = smpp_create(conn, host, port, receive_port, system_type,
02129 username, password, address_range,
02130 source_addr_ton, source_addr_npi, dest_addr_ton,
02131 dest_addr_npi, enquire_link_interval,
02132 max_pending_submits, version, priority, validity, my_number,
02133 smpp_msg_id_type, autodetect_addr, alt_charset, alt_addr_charset,
02134 service_type, connection_timeout, wait_ack, wait_ack_action);
02135
02136 cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton"));
02137 cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
02138
02139 conn->data = smpp;
02140 conn->name = octstr_format("SMPP:%S:%d/%d:%S:%S",
02141 host, port,
02142 (receive_port ? receive_port : port),
02143 username, system_type);
02144
02145 smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
02146 if (smsc_id == NULL) {
02147 conn->id = octstr_duplicate(conn->name);
02148 }
02149
02150 octstr_destroy(host);
02151 octstr_destroy(username);
02152 octstr_destroy(password);
02153 octstr_destroy(system_type);
02154 octstr_destroy(address_range);
02155 octstr_destroy(my_number);
02156 octstr_destroy(smsc_id);
02157 octstr_destroy(alt_charset);
02158 octstr_destroy(alt_addr_charset);
02159 octstr_destroy(service_type);
02160
02161 conn->status = SMSCCONN_CONNECTING;
02162
02163 /*
02164 * I/O threads are only started if the corresponding ports
02165 * have been configured with positive numbers. Use 0 to
02166 * disable the creation of the corresponding thread.
02167 */
02168 if (port != 0)
02169 smpp->transmitter = gwthread_create(io_thread, io_arg_create(smpp,
02170 (transceiver_mode ? 2 : 1)));
02171 if (receive_port != 0)
02172 smpp->receiver = gwthread_create(io_thread, io_arg_create(smpp, 0));
02173
02174 if ((port != 0 && smpp->transmitter == -1) ||
02175 (receive_port != 0 && smpp->receiver == -1)) {
02176 error(0, "SMPP[%s]: Couldn't start I/O threads.",
02177 octstr_get_cstr(smpp->conn->id));
02178 smpp->quitting = 1;
02179 if (smpp->transmitter != -1) {
02180 gwthread_wakeup(smpp->transmitter);
02181 gwthread_join(smpp->transmitter);
02182 }
02183 if (smpp->receiver != -1) {
02184 gwthread_wakeup(smpp->receiver);
02185 gwthread_join(smpp->receiver);
02186 }
02187 smpp_destroy(conn->data);
02188 return -1;
02189 }
02190
02191 conn->shutdown = shutdown_cb;
02192 conn->queued = queued_cb;
02193 conn->send_msg = send_msg_cb;
02194
02195 return 0;
02196 }
|
Here is the call graph for this function:

|
|
Definition at line 1305 of file smsc_smpp.c. References SMSCCONN_FAILED_QFULL, SMSCCONN_FAILED_REJECTED, SMSCCONN_FAILED_TEMPORARILY, and SMSCCONN_SUCCESS. Referenced by handle_pdu(). 01306 {
01307 switch (reason) {
01308 case SMSCCONN_FAILED_REJECTED:
01309 return SMPP_ESME_RX_R_APPN;
01310 case SMSCCONN_SUCCESS:
01311 return SMPP_ESME_ROK;
01312 case SMSCCONN_FAILED_QFULL:
01313 case SMSCCONN_FAILED_TEMPORARILY:
01314 return SMPP_ESME_RX_T_APPN;
01315 }
01316 return SMPP_ESME_RX_T_APPN;
01317 }
|