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

📄 smsc_smpp.c

📁 gateway-1.3.2.tar.gz WAP gw code
💻 C
📖 第 1 页 / 共 5 页
字号:
        ((octstr_get_char(pdu->u.deliver_sm.source_addr, 0) == '+' &&         octstr_check_range(pdu->u.deliver_sm.source_addr, 1, 256, gw_isdigit)) ||        octstr_check_range(pdu->u.deliver_sm.source_addr, 0, 256, gw_isdigit))) {        /* check if we received leading '00', then remove it*/        if (octstr_search(pdu->u.deliver_sm.source_addr, octstr_imm("00"), 0) == 0)            octstr_delete(pdu->u.deliver_sm.source_addr, 0, 2);        /* international, insert '+' if not already here */        if (octstr_get_char(pdu->u.deliver_sm.source_addr, 0) != '+')            octstr_insert_char(pdu->u.deliver_sm.source_addr, 0, '+');    }    else if ((ton == GSM_ADDR_TON_ALPHANUMERIC ||             !octstr_check_range(pdu->u.deliver_sm.source_addr, 0, 256, gw_isdigit)) &&	         octstr_len(pdu->u.deliver_sm.source_addr) > 11) {        /* alphanum sender, max. allowed length is 11 (according to GSM specs) */        *reason = SMPP_ESME_RINVSRCADR;        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) {        *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 ton and destination addr */    if (ton == GSM_ADDR_TON_INTERNATIONAL &&        octstr_get_char(pdu->u.deliver_sm.destination_addr, 0) != '+') {        /* check for leading '00' and delete them */        if (octstr_search(pdu->u.deliver_sm.destination_addr, octstr_imm("00"), 0) == 0)            octstr_delete(pdu->u.deliver_sm.destination_addr, 0, 2);        /* add leading '+'*/        octstr_insert_char(pdu->u.deliver_sm.destination_addr, 0, '+');    }    /* now check dest addr range */    if (!octstr_check_range(pdu->u.deliver_sm.destination_addr, 1, 256, gw_isdigit)) {        *reason = SMPP_ESME_RINVDSTADR;        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), "ISO-8859-1") != 0)                    error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",                             octstr_get_cstr(smpp->alt_charset), "ISO-8859-1");                msg->sms.coding = DC_7BIT;            } else { /* assume GSM 03.38 7-bit alphabet */                charset_gsm_to_latin1(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", "UCS-2BE") != 0)                error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");            msg->sms.coding = DC_UCS2; break;        case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */            if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)                error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");            msg->sms.coding = DC_UCS2; 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_latin1(msg->sms.msgdata);            }    }    msg->sms.pid = pdu->u.deliver_sm.protocol_id;    return msg;error:    msg_destroy(msg);    return NULL;}static long smpp_status_to_smscconn_failure_reason(long status){    switch(status) {        case SMPP_ESME_RMSGQFUL:        case SMPP_ESME_RTHROTTLED:        case SMPP_ESME_RX_T_APPN:        case SMPP_ESME_RSYSERR:            return SMSCCONN_FAILED_TEMPORARILY;            break;        default:            return SMSCCONN_FAILED_REJECTED;    }}static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg){    SMPP_PDU *pdu;    Octstr *buffer;    Octstr *relation_UTC_time = NULL;    struct tm gmtime, localtime, tm;    int gwqdiff;    pdu = smpp_pdu_create(submit_sm,    	    	    	  counter_increase(smpp->message_id_counter));    pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);    pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);    /* Set the service type of the outgoing message. We'll use the config      * directive as default and 'binfo' as specific parameter. */    pdu->u.submit_sm.service_type = octstr_len(msg->sms.binfo) ?         octstr_duplicate(msg->sms.binfo) : octstr_duplicate(smpp->service_type);    /* Check for manual override of source ton and npi values */    if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {        pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;        pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",              octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,              smpp->source_addr_npi);    } else {        /* setup default values */        pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */        pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */    }    if (smpp->autodetect_addr) {        /* lets see if its international or alphanumeric sender */        if (octstr_get_char(pdu->u.submit_sm.source_addr, 0) == '+') {            if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {                pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */                pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;    /* short code */            } else {               /* numeric sender address with + in front -> international (remove the +) */               octstr_delete(pdu->u.submit_sm.source_addr, 0, 1);               pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;    	    }        } else {            if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {                pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;                pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;            }        }    }    /* Check for manual override of destination ton and npi values */    if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {        pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;        pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",              octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,              smpp->dest_addr_npi);    } else {        pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */        pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */    }    /*     * if its a international number starting with +, lets remove the     * '+' and set number type to international instead     */    if (octstr_get_char(pdu->u.submit_sm.destination_addr,0) == '+') {        octstr_delete(pdu->u.submit_sm.destination_addr, 0,1);        pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;    }    /* check length of src/dst address */    if (octstr_len(pdu->u.submit_sm.destination_addr) > 20 ||        octstr_len(pdu->u.submit_sm.source_addr) > 20) {        smpp_pdu_destroy(pdu);        return NULL;    }    /*     * set the data coding scheme (DCS) field     * check if we have a forced value for this from the smsc-group.     * Note: if message class is set, then we _must_ force alt_dcs otherwise     * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag     * first here, because MWI and MCLASS can not be set at the same time and     * function fields_to_dcs check MWI first, so we have no need to force alt_dcs     * if MWI is set.     */    if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)        pdu->u.deliver_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */    else        pdu->u.submit_sm.data_coding = fields_to_dcs(msg,            (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?             msg->sms.alt_dcs : smpp->conn->alt_dcs));    /* set protocoll id */    if(msg->sms.pid != SMS_PARAM_UNDEFINED)        pdu->u.submit_sm.protocol_id = msg->sms.pid;    /*     * set the esm_class field     * default is store and forward, plus udh and rpi if requested     */    pdu->u.submit_sm.esm_class = ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE;    if (octstr_len(msg->sms.udhdata))        pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |            ESM_CLASS_SUBMIT_UDH_INDICATOR;    if (msg->sms.rpi > 0)        pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |            ESM_CLASS_SUBMIT_RPI;    /*     * set data segments and length     */    pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);    /*     * only re-encoding if using default smsc charset that is defined via     * alt-charset in smsc group and if MT is not binary     */    if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata))) {        /*          * consider 3 cases:          *  a) data_coding 0xFX: encoding should always be GSM 03.38 charset          *  b) data_coding 0x00: encoding may be converted according to alt-charset          *  c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined         */        if ((pdu->u.submit_sm.data_coding & 0xF0) ||            (!smpp->alt_charset && pdu->u.submit_sm.data_coding == 0)) {            charset_latin1_to_gsm(pdu->u.submit_sm.short_message);        }        else if (pdu->u.submit_sm.data_coding == 0 && smpp->alt_charset) {            /*             * convert to the given alternative charset             */            if (charset_convert(pdu->u.submit_sm.short_message, "ISO-8859-1",                                octstr_get_cstr(smpp->alt_charset)) != 0)                error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",                             "ISO-8859-1", octstr_get_cstr(smpp->alt_charset));        }    }    /* prepend udh if present */    if (octstr_len(msg->sms.udhdata)) {        octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);    }    pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message);    /*     * check for validity and defered settings     */    if (msg->sms.validity >= 0 || msg->sms.deferred >= 0) {        /* work out 1/4 hour difference between local time and UTC/GMT */        gmtime = gw_gmtime(time(NULL));        localtime = gw_localtime(time(NULL));        gwqdiff = ((localtime.tm_hour - gmtime.tm_hour) * 4)                  + ((localtime.tm_min - gmtime.tm_min) / 15);        if (gwqdiff >= 0) {            relation_UTC_time = octstr_create("+");        } else {            relation_UTC_time = octstr_create("-");            gwqdiff *= -1;  /* make absolute */        }        if (msg->sms.validity >= 0) {            tm = gw_localtime(time(NULL) + msg->sms.validity * 60);            buffer = octstr_format("%02d%02d%02d%02d%02d%02d0%02d%1s",                    tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,                    tm.tm_hour, tm.tm_min, tm.tm_sec,                    gwqdiff, octstr_get_cstr(relation_UTC_time));            pdu->u.submit_sm.validity_period = octstr_copy(buffer,0,16);            octstr_destroy(buffer);        }        if (msg->sms.deferred >= 0) {            tm = gw_localtime(time(NULL) + msg->sms.deferred * 60);

⌨️ 快捷键说明

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