⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc_smasi.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Implementation of a SM/ASI SMSC module. * * Stipe Tolj <tolj@wapme-systems.de> * * This module connects to a CriticalPath InVoke SMS Center which * uses the SM/ASI protocoll.  * The module is heavily based on the SMPP module design. * * TODO: * 1. alt_dcs is not used. Instead, msg->sms.mclass is used as the SMASI *    Class. * 2. Numbers are not handled correctly, I guess. SMASI allows only(?) *    international numbers without leading double zero. How to ensure *    this? * 3. Handling of npi and ton correct? * 4. SubmitMulti PDUs not supported. * 5. Replace PDUs not supported. * 6. Status PDUs not supported. * 7. Cancel PDUs not supported. * 8. UserRes PDUs not supported. * 9. Smsc PDUs not supported. * 10. EnquireLink PDUs not supported. */#include "gwlib/gwlib.h"#include "msg.h"#include "smsc_p.h"#include "smasi_pdu.h"#include "smscconn_p.h"#include "bb_smscconn_cb.h"#include "sms.h"#include "dlr.h"#define DEBUG 1#ifndef DEBUGstatic void dump_pdu(const char *msg, Octstr *id, SMASI_PDU *pdu) { }#elsestatic void dump_pdu(const char *msg, Octstr *id, SMASI_PDU *pdu) {    debug("bb.sms.smasi", 0, "SMASI[%s]: %s", octstr_get_cstr(id), msg);    smasi_pdu_dump(pdu);}#endif/************************************************************************//* DEFAULT SETTINGS                                                     *//************************************************************************/#define SMASI_DEFAULT_PORT          21500#define SMASI_RECONNECT_DELAY       10.0#define SMASI_DEFAULT_PRIORITY      0#define MAX_PENDING_SUBMITS         10#define SMASI_THROTTLING_SLEEP_TIME 15#define SMASI_ENQUIRE_LINK_INTERVAL  30.0 /************************************************************************//* OVERRIDE SETTINGS                                                    *//************************************************************************//* Set these to -1 if no override desired. Values carried in message will * be used then. Or the defaults - if message has no values. *  * Otherwise these values will be forced! */#define SMASI_OVERRIDE_SOURCE_TON    1#define SMASI_OVERRIDE_SOURCE_NPI    -1#define SMASI_OVERRIDE_DEST_TON      -1#define SMASI_OVERRIDE_DEST_NPI      -1/************************************************************************//* SMASI STRUCTURE AND RELATED FUNCTIONS                                *//************************************************************************/typedef struct {    SMSCConn * conn;                 /* connection to the bearerbox */    int thread_handle;               /* handle for the SMASI thread */    List *msgs_to_send;    Dict *sent_msgs;                 /* hash table for send, but yet not confirmed */    List *received_msgs;             /* list of received, but yet not processed */    Counter *message_id_counter;     /* sequence number */    Octstr *host;                    /* host or IP of the SMASI server */    long port;                       /* port to connect to */    Octstr *username;         Octstr * password;    Octstr * my_number;    long source_addr_ton;    long source_addr_npi;    long dest_addr_ton;    long dest_addr_npi;    long reconnect_delay;    long priority;    time_t throttling_err_time;    int quitting;    long enquire_link_interval;    int logged_off;} SMASI;static SMASI *smasi_create(SMSCConn *conn) {    SMASI *smasi = gw_malloc(sizeof(SMASI));    smasi->conn = conn;    smasi->thread_handle = -1;    smasi->msgs_to_send = list_create();    smasi->sent_msgs = dict_create(16, NULL);    smasi->received_msgs = list_create();    smasi->message_id_counter = counter_create();    smasi->host = NULL;    smasi->username = NULL;    smasi->password = NULL;    smasi->source_addr_ton = -1;    smasi->source_addr_npi = -1;    smasi->dest_addr_ton = -1;    smasi->dest_addr_npi = -1;    smasi->my_number = NULL;    smasi->port = 21500;    smasi->reconnect_delay = 10;    smasi->quitting = 0;    smasi->logged_off = 0;    smasi->priority = 0;    smasi->throttling_err_time = 0;    smasi->enquire_link_interval = 30;    list_add_producer(smasi->msgs_to_send);    return smasi;} static void smasi_destroy(SMASI *smasi) {    if (smasi == NULL) return;    list_destroy(smasi->msgs_to_send, msg_destroy_item);    dict_destroy(smasi->sent_msgs);    list_destroy(smasi->received_msgs, msg_destroy_item);    counter_destroy(smasi->message_id_counter);    octstr_destroy(smasi->host);    octstr_destroy(smasi->username);    octstr_destroy(smasi->password);    gw_free(smasi);} /************************************************************************//* DATA ENCODING                                                        *//************************************************************************//* These values will be initialized on module startup. They contain the * ASCII representation of the chars that need to be escaped in the message * body before transmission. Example: "," (comma) will be represented by * the octet string ":2c". */static Octstr *colon = NULL;static Octstr *assign = NULL;static Octstr *comma = NULL;static Octstr *cr = NULL;static Octstr *lf = NULL;/* * Escapes outgoing message body data by replacing occurrences of "special" * chars inside the octet string. */static void escape_data(Octstr *data) {    long pos = 0;    /* This one uses a different approach than the encode and decode     * functions. Because it is assumed, that only a fraction of the     * contained chars have to be escaped.     */    while (pos < octstr_len(data)) {        Octstr * escaped = NULL;        int check = octstr_get_char(data, pos);        if (check == ':') escaped = colon;        else if (check == '=') escaped = assign;        else if (check == ',') escaped = comma;        else if (check == '\n') escaped = cr;        else if (check == '\r') escaped = lf;        if (escaped != NULL) {            /* If the current char has to be escaped, delete the char from             * the source string, replace it with the escape sequence, and             * advance position until after the inserted sequence.             */            octstr_delete(data, pos, 1);            octstr_insert(data, escaped, pos);            pos += octstr_len(escaped);        } else {            /* If not escaped, simply skip the current char. */            pos++;        }     } } /* * Unescapes incoming message body data by replacing occurrences of escaped * chars with their original character representation. */static void unescape_data(Octstr *data) {    long pos = 0;    /* Again, an inplace transformation is used. Because, again, it is     * assumed that only a fraction of chars has to be unescaped.     */    while (pos < octstr_len(data)) {        int check = octstr_get_char(data, pos);        if (check == ':') {            char byte = 0;            int msb = octstr_get_char(data, pos + 1);            int lsb = octstr_get_char(data, pos + 2);            if (msb == '0') msb = 0;            else if (msb >= '1' && msb <= '9') msb -= '1' + 1;            else msb -= 'a' + 10;            if (lsb == '0') lsb = 0;            else if (lsb >= '1' && lsb <= '9') lsb -= '1' + 1;            else lsb -= 'a' + 10;            byte = msb << 4 | lsb;            /* Do inplace unescaping. */            octstr_delete(data, pos, 3);            octstr_insert_data(data, pos, &byte, 1);        }         pos++;    } }/* * Will replace a binary data octet string (inplace) with a SMASI conform * ASCII representation of the data. */static void encode_binary_data(Octstr *data) {    Octstr *result = octstr_create("");    long pos = 0;    while (pos < octstr_len(data)) {        int encode = octstr_get_char(data, pos);        int msb = (encode & 0xf0) >> 4;        int lsb = (encode & 0x0f) >> 0;        if (msb == 0) msb = '0';        else if (msb < 10) msb = '1' + msb - 1;        else msb = 'a' + msb - 10;        if (lsb == 0) lsb = '0';        else if (lsb < 10) lsb = '1' + lsb - 1;        else lsb = 'a' + lsb - 10;        octstr_append_char(result, ':');        octstr_append_char(result, msb);        octstr_append_char(result, lsb);        pos++;    }     /* Replace binary data octet string with ASCII representation. */    octstr_delete(data, 0, octstr_len(data));    octstr_append(data, result);    octstr_destroy(result);}/* * Replaces a SMASI conform ASCII representation of binary data with the * original binary data octet string. Will abort data decoding if the ASCII * representation is invalid. */static void decode_binary_data(Octstr *data) {    long pos = 0;    Octstr * result = octstr_create("");    for (pos = 0; pos < octstr_len(data); pos += 3) {        int check = octstr_get_char(data, pos);        if (check != ':') {            warning(0, "Malformed binary encoded data.");            return;        } else {            int byte = 0;            int msb = octstr_get_char(data, pos + 1);            int lsb = octstr_get_char(data, pos + 2);            if (msb == '0') msb = 0;            else if (msb >= '1' && msb <= '9') msb = msb - 48;            else msb = msb - 'a' + 10;            if (lsb == '0') lsb = 0;            else if (lsb >= '1' && lsb <= '9') lsb = lsb - 48;            else lsb = lsb - 'a' + 10;            byte = msb << 4 | lsb;            octstr_append_char(result, byte);        }     }     /* Replace ASCII representation with binary data octet string. */    octstr_delete(data, 0, octstr_len(data));    octstr_append(data, result);    octstr_destroy(result);}/************************************************************************//* MESSAGE PROCESSING                                                   *//************************************************************************/static Octstr *get_ton_npi_value(int override, int message) {    if(override != -1) {        debug("bb.sms.smasi", 0, "SMASI: Manually forced source addr ton = %d",               override);        return(octstr_format("%ld", override));    } else {        return(octstr_format("%ld", message));    }}/* * Gets the value to be used as source_addr_ton. Will use override values * if configured. Will use values from message otherwise. Or fall back to * defaults if nothing given. */static Octstr *get_source_addr_ton(SMASI *smasi, Msg *msg) {    return get_ton_npi_value(smasi->source_addr_ton,                              GSM_ADDR_TON_INTERNATIONAL);}/* * Gets the value to be used as source_addr_npi. Will use override values * if configured. Will use values from message otherwise. Or fall back to * defaults if nothing given. */static Octstr *get_source_addr_npi(SMASI *smasi, Msg *msg) {    return get_ton_npi_value(smasi->source_addr_npi,                              GSM_ADDR_NPI_E164);}/* * Gets the value to be used as dest_addr_ton. Will use override values * if configured. Will use values from message otherwise. Or fall back to * defaults if nothing given.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -