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

📄 smsc_smpp.c

📁 主要包括sms网关和wap网关实现说明和源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            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.data_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);            }    }    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;    int validity;        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 */                if (smpp->alt_addr_charset) {                    if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {                        /* @ would break PDU if converted into GSM*/                        octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));                        charset_latin1_to_gsm(pdu->u.submit_sm.source_addr);                    } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)                        error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",                                SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset));                }            } 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;                if (smpp->alt_addr_charset) {                    if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {                        /* @ would break PDU if converted into GSM */                        octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));                         charset_latin1_to_gsm(pdu->u.submit_sm.source_addr);                    } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)                        error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",                                SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset));                }            }        }    }    /* 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.submit_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 protocol 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, SMPP_DEFAULT_CHARSET,                                octstr_get_cstr(smpp->alt_charset)) != 0)                error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",                             SMPP_DEFAULT_CHARSET, 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     * were message value has higher priiority then smsc config group value     */    validity = msg->sms.validity >= 0 ? msg->sms.validity : smpp->validityperiod;    if (validity >= 0) {        struct tm tm = gw_gmtime(time(NULL) + validity * 60);        pdu->u.submit_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,                tm.tm_hour, tm.tm_min, tm.tm_sec);    }    if (msg->sms.deferred >= 0) {        struct tm tm = gw_gmtime(time(NULL) + msg->sms.deferred * 60);        pdu->u.submit_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",                tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,                tm.tm_hour, tm.tm_min, tm.tm_sec);    }    /* ask for the delivery reports if needed */    if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))        pdu->u.submit_sm.registered_delivery = 1;    else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))        pdu->u.submit_sm.registered_delivery = 2;    /* set priority */    if (msg->sms.priority >= 0 && msg->sms.priority <= 3)        pdu->u.submit_sm.priority_flag = msg->sms.priority;    else        pdu->u.submit_sm.priority_flag = smpp->priority;    /* set more messages to send */    if (smpp->version > 0x33 && msg->sms.msg_left > 0)        pdu->u.submit_sm.more_messages_to_send = 1;    return pdu;}static void send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent){    SMPP_PDU *pdu;    Octstr *os;    if (date_universal_now() - *last_sent < smpp->enquire_link_interval)        return;    *last_sent = date_universal_now();    pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));    dump_pdu("Sending enquire link:", smpp->conn->id, pdu);    os = smpp_pdu_pack(pdu);    if (os)	conn_write(conn, os); /* Write errors checked by caller. */    octstr_destroy(os);    smpp_pdu_destroy(pdu);}static void send_unbind(SMPP *smpp, Connection *conn){    SMPP_PDU *pdu;    Octstr *os;    pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));    dump_pdu("Sending unbind:", smpp->conn->id, pdu);    os = smpp_pdu_pack(pdu);    conn_write(conn, os);    octstr_destroy(os);    smpp_pdu_destroy(pdu);}static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu){    Octstr *os;    int ret;    dump_pdu("Sending PDU:", id, pdu);    os = smpp_pdu_pack(pdu);    if (os)        ret = conn_write(conn, os);   /* Caller checks for write errors later */    else	ret = -1;    octstr_destroy(os);    return ret;}static void send_messages(SMPP *smpp, Connection *conn, long *pending_submits){    Msg *msg;    SMPP_PDU *pdu;    Octstr *os;    double delay = 0;    if (*pending_submits == -1)        return;    if (smpp->conn->throughput > 0) {        delay = 1.0 / smpp->conn->throughput;    }    while (*pending_submits < smpp->max_pending_submits) {    	/* Get next message, quit if none to be sent */    	msg = gwlist_extract_first(smpp->msgs_to_send);        if (msg == NULL)            break;        /* Send PDU, record it as waiting for ack from SMS center */        pdu = msg_to_pdu(smpp, msg);        if (pdu == NULL) {            bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED SMS"));            continue;        }        /* check for write errors */        if (send_pdu(conn, smpp->conn->id, pdu) == 0) {            struct smpp_msg *smpp_msg = smpp_msg_create(msg);            os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);            dict_put(smpp->sent_msgs, os, smpp_msg);            smpp_pdu_destroy(pdu);

⌨️ 快捷键说明

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