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

📄 smsc_smpp.c

📁 WAP gateway, Linux source
💻 C
📖 第 1 页 / 共 5 页
字号:
{    long reason = SMPP_ESME_ROK;        if (addr == NULL)        return reason;    switch(ton) {    case GSM_ADDR_TON_INTERNATIONAL:        /*         * Checks to perform:         *   1) assume international number has at least 7 chars         *   2) the whole source addr consist of digits, exception '+' in front         */        if (octstr_len(addr) < 7) {            /* We consider this as a "non-hard" condition, since there "may"             * be international numbers routable that are < 7 digits. Think             * of 2 digit country code + 3 digit emergency code. */            warning(0, "SMPP[%s]: Mallformed addr `%s', generally expected at least 7 digits. ",                     octstr_get_cstr(id),                     octstr_get_cstr(addr));        } else if (octstr_get_char(addr, 0) == '+' &&                   !octstr_check_range(addr, 1, 256, gw_isdigit)) {            error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",                     octstr_get_cstr(id),                     octstr_get_cstr(addr));            reason = SMPP_ESME_RINVSRCADR;            goto error;        } else if (octstr_get_char(addr, 0) != '+' &&                   !octstr_check_range(addr, 0, 256, gw_isdigit)) {            error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",                     octstr_get_cstr(id),                     octstr_get_cstr(addr));            reason = SMPP_ESME_RINVSRCADR;            goto error;        }        /* check if we received leading '00', then remove it*/        if (octstr_search(addr, octstr_imm("00"), 0) == 0)            octstr_delete(addr, 0, 2);        /* international, insert '+' if not already here */        if (octstr_get_char(addr, 0) != '+')            octstr_insert_char(addr, 0, '+');        break;    case GSM_ADDR_TON_ALPHANUMERIC:        if (octstr_len(addr) > 11) {            /* alphanum sender, max. allowed length is 11 (according to GSM specs) */            error(0, "SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ",                     octstr_get_cstr(id),                     octstr_get_cstr(addr));            reason = SMPP_ESME_RINVSRCADR;            goto error;        }        if (alt_addr_charset) {            if (octstr_str_case_compare(alt_addr_charset, "gsm") == 0)		charset_gsm_to_utf8(addr);            else if (charset_convert(addr, octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET) != 0)                error(0, "Failed to convert address from charset <%s> to <%s>, leave as is.",                    octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET);        }        break;    default: /* otherwise don't touch addr, user should handle it */        break;    }    error:    return reason;}/* * Convert SMPP PDU to internal Msgs structure. * Return the Msg if all was fine and NULL otherwise, while getting  * the failing reason delivered back in *reason. * XXX semantical check on the incoming values can be extended here. */static Msg *pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason){    Msg *msg;    int ton, npi;    gw_assert(pdu->type == deliver_sm);    msg = msg_create(sms);    gw_assert(msg != NULL);    *reason = SMPP_ESME_ROK;    /*      * Reset source addr to have a prefixed '+' in case we have an      * intl. TON to allow backend boxes (ie. smsbox) to distinguish     * between national and international numbers.     */    ton = pdu->u.deliver_sm.source_addr_ton;    npi = pdu->u.deliver_sm.source_addr_npi;    /* check source addr */    if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)        goto error;    msg->sms.sender = pdu->u.deliver_sm.source_addr;    pdu->u.deliver_sm.source_addr = NULL;    /*      * Follows SMPP spec. v3.4. issue 1.2      * it's not allowed to have destination_addr NULL      */    if (pdu->u.deliver_sm.destination_addr == NULL) {        error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "                 "Discarding MO message.", octstr_get_cstr(smpp->conn->id),                     octstr_get_cstr(pdu->u.deliver_sm.destination_addr));        *reason = SMPP_ESME_RINVDSTADR;        goto error;    }    /* Same reset of destination number as for source */    ton = pdu->u.deliver_sm.dest_addr_ton;    npi = pdu->u.deliver_sm.dest_addr_npi;    /* check destination addr */    if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)        goto error;    msg->sms.receiver = pdu->u.deliver_sm.destination_addr;    pdu->u.deliver_sm.destination_addr = NULL;    /* SMSCs use service_type for billing information */    msg->sms.binfo = pdu->u.deliver_sm.service_type;    pdu->u.deliver_sm.service_type = NULL;    if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_RPI)        msg->sms.rpi = 1;    /*     * Check for message_payload if version > 0x33 and sm_length == 0     * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!     */    if (smpp->version > 0x33 && pdu->u.deliver_sm.sm_length == 0 && pdu->u.deliver_sm.message_payload) {        msg->sms.msgdata = pdu->u.deliver_sm.message_payload;        pdu->u.deliver_sm.message_payload = NULL;    }    else {        msg->sms.msgdata = pdu->u.deliver_sm.short_message;        pdu->u.deliver_sm.short_message = NULL;    }    /*     * Encode udh if udhi set     * for reference see GSM03.40, section 9.2.3.24     */    if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {        int udhl;        udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;        debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",               octstr_get_cstr(smpp->conn->id), udhl);        if (udhl > octstr_len(msg->sms.msgdata)) {            error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "                     "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),                     udhl, octstr_len(msg->sms.msgdata));            *reason = SMPP_ESME_RINVESMCLASS;            goto error;        }        msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);        octstr_delete(msg->sms.msgdata, 0, udhl);    }    dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);    /* handle default data coding */    switch (pdu->u.deliver_sm.data_coding) {        case 0x00: /* default SMSC alphabet */            /*             * try to convert from something interesting if specified so             * unless it was specified binary, ie. UDH indicator was detected             */            if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET) != 0)                    error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",                             octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET);                msg->sms.coding = DC_7BIT;            } else { /* assume GSM 03.38 7-bit alphabet */                charset_gsm_to_utf8(msg->sms.msgdata);                msg->sms.coding = DC_7BIT;            }            break;        case 0x01: /* ASCII or IA5 - not sure if I need to do anything */        case 0x03: /* ISO-8859-1 - do nothing */            msg->sms.coding = DC_7BIT; break;        case 0x02: /* 8 bit binary - do nothing */        case 0x04: /* 8 bit binary - do nothing */            msg->sms.coding = DC_8BIT; break;        case 0x05: /* JIS - what do I do with that ? */            break;        case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */            if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UTF-8") != 0)                error(0, "Failed to convert msgdata from cyrllic to UTF-8, will leave as is");            msg->sms.coding = DC_7BIT; break;        case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */            if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UTF-8") != 0)                error(0, "Failed to convert msgdata from hebrew to UTF-8, will leave as is");            msg->sms.coding = DC_7BIT; break;        case 0x08: /* unicode UCS-2, yey */            msg->sms.coding = DC_UCS2; break;            /*             * don't much care about the others,             * you implement them if you feel like it             */        default:            /*             * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.             * So we just look decoded values from dcs_to_fields and if none there make our assumptions.             * if we have an UDH indicator, we assume DC_8BIT.             */            if (msg->sms.coding == DC_UNDEF && pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)                msg->sms.coding = DC_8BIT;            else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */                msg->sms.coding = DC_7BIT;                charset_gsm_to_utf8(msg->sms.msgdata);            }    }    msg->sms.pid = pdu->u.deliver_sm.protocol_id;    /* set priority flag */    msg->sms.priority = pdu->u.deliver_sm.priority_flag;    return msg;error:    msg_destroy(msg);    return NULL;}/* * Convert SMPP PDU to internal Msgs structure. * Return the Msg if all was fine and NULL otherwise, while getting  * the failing reason delivered back in *reason. * XXX semantical check on the incoming values can be extended here. */static Msg *data_sm_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason){    Msg *msg;    int ton, npi;    gw_assert(pdu->type == data_sm);    msg = msg_create(sms);    gw_assert(msg != NULL);    *reason = SMPP_ESME_ROK;    /*      * Reset source addr to have a prefixed '+' in case we have an      * intl. TON to allow backend boxes (ie. smsbox) to distinguish     * between national and international numbers.     */    ton = pdu->u.data_sm.source_addr_ton;    npi = pdu->u.data_sm.source_addr_npi;    /* check source addr */    if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)        goto error;    msg->sms.sender = pdu->u.data_sm.source_addr;    pdu->u.data_sm.source_addr = NULL;    /*      * Follows SMPP spec. v3.4. issue 1.2      * it's not allowed to have destination_addr NULL      */    if (pdu->u.data_sm.destination_addr == NULL) {        error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "                 "Discarding MO message.", octstr_get_cstr(smpp->conn->id),                     octstr_get_cstr(pdu->u.data_sm.destination_addr));        *reason = SMPP_ESME_RINVDSTADR;        goto error;    }    /* Same reset of destination number as for source */    ton = pdu->u.data_sm.dest_addr_ton;    npi = pdu->u.data_sm.dest_addr_npi;    /* check destination addr */    if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)        goto error;    msg->sms.receiver = pdu->u.data_sm.destination_addr;    pdu->u.data_sm.destination_addr = NULL;    /* SMSCs use service_type for billing information */    msg->sms.binfo = pdu->u.data_sm.service_type;    pdu->u.data_sm.service_type = NULL;    if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)        msg->sms.rpi = 1;    msg->sms.msgdata = pdu->u.data_sm.message_payload;    pdu->u.data_sm.message_payload = NULL;    /*     * Encode udh if udhi set     * for reference see GSM03.40, section 9.2.3.24     */    if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {        int udhl;        udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;        debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",               octstr_get_cstr(smpp->conn->id), udhl);        if (udhl > octstr_len(msg->sms.msgdata)) {            error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "                     "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),                     udhl, octstr_len(msg->sms.msgdata));            *reason = SMPP_ESME_RINVESMCLASS;            goto error;        }        msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);        octstr_delete(msg->sms.msgdata, 0, udhl);    }    dcs_to_fields(&msg, pdu->u.data_sm.data_coding);    /* handle default data coding */    switch (pdu->u.data_sm.data_coding) {        case 0x00: /* default SMSC alphabet */            /*             * try to convert from something interesting if specified so             * unless it was specified binary, ie. UDH indicator was detected             */            if (smpp->alt_charset && msg->sms.coding != DC_8BIT) {                if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET) != 0)                    error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",                             octstr_get_cstr(smpp->alt_charset), SMPP_DEFAULT_CHARSET);                msg->sms.coding = DC_7BIT;            } else { /* assume GSM 03.38 7-bit alphabet */                charset_gsm_to_utf8(msg->sms.msgdata);                msg->sms.coding = DC_7BIT;            }            break;        case 0x01: /* ASCII or IA5 - not sure if I need to do anything */        case 0x03: /* ISO-8859-1 - do nothing */            msg->sms.coding = DC_7BIT; break;        case 0x02: /* 8 bit binary - do nothing */        case 0x04: /* 8 bit binary - do nothing */            msg->sms.coding = DC_8BIT; break;        case 0x05: /* JIS - what do I do with that ? */

⌨️ 快捷键说明

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