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

📄 smsc_smpp.c

📁 主要包括sms网关和wap网关实现说明和源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            octstr_destroy(os);            ++(*pending_submits);            /*             * obey throughput speed limit, if any.             */            if (smpp->conn->throughput > 0)                gwthread_sleep(delay);        }        else { /* write error occurs */            smpp_pdu_destroy(pdu);            bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);            break;        }    }}/* * Open transmission connection to SMS center. Return NULL for error, * open Connection for OK. Caller must set smpp->conn->status correctly * before calling this. */static Connection *open_transmitter(SMPP *smpp){     SMPP_PDU *bind;     Connection *conn;      conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host );     if (conn == NULL) {        error(0, "SMPP[%s]: Couldn't connect to server.",              octstr_get_cstr(smpp->conn->id));        return NULL;     }          bind = smpp_pdu_create(bind_transmitter,                 counter_increase(smpp->message_id_counter));     bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username);     bind->u.bind_transmitter.password = octstr_duplicate(smpp->password);     if (smpp->system_type == NULL)         bind->u.bind_transmitter.system_type = octstr_create("VMA");     else         bind->u.bind_transmitter.system_type =  	       octstr_duplicate(smpp->system_type);     bind->u.bind_transmitter.interface_version = smpp->version;    bind->u.bind_transmitter.address_range =      	octstr_duplicate(smpp->address_range);     bind->u.bind_transmitter.addr_ton = smpp->bind_addr_ton;    bind->u.bind_transmitter.addr_npi = smpp->bind_addr_npi;    send_pdu(conn, smpp->conn->id, bind);     smpp_pdu_destroy(bind);      return conn; }   /*  * Open transceiver connection to SMS center. Return NULL for error,  * open Connection for OK. Caller must set smpp->conn->status correctly  * before calling this.  */ static Connection *open_transceiver(SMPP *smpp) {     SMPP_PDU *bind;    Connection *conn;          conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host );     if (conn == NULL) {         error(0, "SMPP[%s]: Couldn't connect to server.",             octstr_get_cstr(smpp->conn->id));       return NULL;     }      bind = smpp_pdu_create(bind_transceiver,                            counter_increase(smpp->message_id_counter));     bind->u.bind_transceiver.system_id = octstr_duplicate(smpp->username);     bind->u.bind_transceiver.password = octstr_duplicate(smpp->password);     if (smpp->system_type == NULL)         bind->u.bind_transceiver.system_type = octstr_create("VMA");     else            bind->u.bind_transceiver.system_type = octstr_duplicate(smpp->system_type);     bind->u.bind_transceiver.interface_version = smpp->version;    bind->u.bind_transceiver.address_range = octstr_duplicate(smpp->address_range);     bind->u.bind_transceiver.addr_ton = smpp->bind_addr_ton;    bind->u.bind_transceiver.addr_npi = smpp->bind_addr_npi;    send_pdu(conn, smpp->conn->id, bind);     smpp_pdu_destroy(bind);      return conn; }   /*  * Open reception connection to SMS center. Return NULL for error,   * open Connection for OK. Caller must set smpp->conn->status correctly   * before calling this.  */ static Connection *open_receiver(SMPP *smpp){    SMPP_PDU *bind;    Connection *conn;    conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host );    if (conn == NULL) {        error(0, "SMPP[%s]: Couldn't connect to server.",              octstr_get_cstr(smpp->conn->id));        return NULL;    }    bind = smpp_pdu_create(bind_receiver,                counter_increase(smpp->message_id_counter));    bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username);    bind->u.bind_receiver.password = octstr_duplicate(smpp->password);    if (smpp->system_type == NULL)        bind->u.bind_receiver.system_type = octstr_create("VMA");    else        bind->u.bind_receiver.system_type =            octstr_duplicate(smpp->system_type);    bind->u.bind_receiver.interface_version = smpp->version;    bind->u.bind_receiver.address_range =        octstr_duplicate(smpp->address_range);    bind->u.bind_receiver.addr_ton = smpp->bind_addr_ton;    bind->u.bind_receiver.addr_npi = smpp->bind_addr_npi;    send_pdu(conn, smpp->conn->id, bind);    smpp_pdu_destroy(bind);    return conn;}static Msg *handle_dlr(SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state){    Msg *dlrmsg = NULL;    Octstr *respstr = NULL, *msgid = NULL, *tmp;    int dlrstat = -1;        /* first check for SMPP v3.4 and above */    if (smpp->version > 0x33 && receipted_message_id) {        msgid = octstr_duplicate(receipted_message_id);        switch(message_state) {        case 1: /* ENROUTE */        case 6: /* ACCEPTED */            dlrstat = DLR_BUFFERED;            break;        case 2: /* DELIVERED */            dlrstat = DLR_SUCCESS;            break;        case 3: /* EXPIRED */        case 4: /* DELETED */        case 5: /* UNDELIVERABLE */        case 7: /* UNKNOWN */        case 8: /* REJECTED */            dlrstat = DLR_FAIL;            break;        default:            warning(0, "SMPP[%s]: Got DLR with unknown 'message_state' (%ld).",                octstr_get_cstr(smpp->conn->id), message_state);            dlrstat = DLR_FAIL;            break;        }    }    /* check for SMPP v.3.4. and message_payload */    if (smpp->version > 0x33 && octstr_len(short_message) == 0)        respstr = message_payload;    else        respstr = short_message;            /* still no msgid ? */    if (!msgid && respstr) {        long curr = 0, vpos = 0;        Octstr *stat = NULL;        char id_cstr[65], stat_cstr[16], sub_d_cstr[13], done_d_cstr[13];        int sub, dlrvrd, ret;            /* get server message id */        /* first try sscanf way if thus failed then old way */        ret = sscanf(octstr_get_cstr(respstr),                    "id:%64[^s] sub:%d dlvrd:%d submit date:%12[0-9] done date:%12[0-9] stat:%10[^t^e]",                    id_cstr, &sub, &dlrvrd, sub_d_cstr, done_d_cstr, stat_cstr);        if (ret == 6) {            msgid = octstr_create(id_cstr);            octstr_strip_blanks(msgid);            stat = octstr_create(stat_cstr);            octstr_strip_blanks(stat);        }        else {            debug("bb.sms.smpp", 0, "SMPP[%s]: Couldnot parse DLR string sscanf way,"                "fallback to old way. Please report!", octstr_get_cstr(smpp->conn->id));                    if ((curr = octstr_search(respstr, octstr_imm("id:"), 0)) != -1) {                vpos = octstr_search_char(respstr, ' ', curr);                if ((vpos-curr >0) && (vpos != -1))                    msgid = octstr_copy(respstr, curr+3, vpos-curr-3);            } else {                msgid = NULL;            }            /* get err & status code */            if ((curr = octstr_search(respstr, octstr_imm("stat:"), 0)) != -1) {                vpos = octstr_search_char(respstr, ' ', curr);                if ((vpos-curr >0) && (vpos != -1))                    stat = octstr_copy(respstr, curr+5, vpos-curr-5);            } else {                stat = NULL;            }        }                /*         * we get the following status:         * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD         *         * Note: some buggy SMSC's send us immediately delivery notifications although         *          we doesn't requested these.         */                if (stat != NULL && octstr_compare(stat, octstr_imm("DELIVRD")) == 0)            dlrstat = DLR_SUCCESS;        else if (stat != NULL && (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0 ||                        octstr_compare(stat, octstr_imm("ACKED")) == 0 ||                        octstr_compare(stat, octstr_imm("BUFFRED")) == 0 ||                        octstr_compare(stat, octstr_imm("BUFFERD")) == 0 ||                                                octstr_compare(stat, octstr_imm("ENROUTE")) == 0))            dlrstat = DLR_BUFFERED;        else            dlrstat = DLR_FAIL;                        if (stat != NULL)            octstr_destroy(stat);    }    if (msgid != NULL) {        /*         * Obey which SMPP msg_id type this SMSC is using, where we         * have the following semantics for the variable smpp_msg_id:         *         * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm         *         * if bit is set value is hex otherwise dec         *         * 0x00 deliver_sm dec, submit_sm_resp dec         * 0x01 deliver_sm dec, submit_sm_resp hex         * 0x02 deliver_sm hex, submit_sm_resp dec         * 0x03 deliver_sm hex, submit_sm_resp hex         *         * Default behaviour is SMPP spec compliant, which means         * msg_ids should be C strings and hence non modified.         */        if (smpp->smpp_msg_id_type == -1) {            /* the default, C string */            tmp = octstr_duplicate(msgid);        } else {            if ((smpp->smpp_msg_id_type & 0x02) ||                 (!octstr_check_range(msgid, 0, octstr_len(msgid), gw_isdigit))) {                tmp = octstr_format("%lu", strtoll(octstr_get_cstr(msgid), NULL, 16));            } else {                tmp = octstr_format("%lu", strtoll(octstr_get_cstr(msgid), NULL, 10));            }        }        dlrmsg = dlr_find(smpp->conn->id,            tmp, /* smsc message id */            destination_addr, /* destination */            dlrstat);        octstr_destroy(msgid);    } else        tmp = octstr_create("");        if (dlrmsg != NULL) {        /*         * we found the delivery report in our storage, so recode the         * message structure.         * The DLR trigger URL is indicated by msg->sms.dlr_url.         */        dlrmsg->sms.msgdata = octstr_duplicate(respstr);        dlrmsg->sms.sms_type = report_mo;    } else {        error(0,"SMPP[%s]: got DLR but could not find message or was not interested "                "in it id<%s> dst<%s>, type<%d>",                octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp),                octstr_get_cstr(destination_addr), dlrstat);    }    octstr_destroy(tmp);                    return dlrmsg;}static long smscconn_failure_reason_to_smpp_status(long reason){    switch (reason) {    case SMSCCONN_FAILED_REJECTED:        return SMPP_ESME_RX_R_APPN;    case SMSCCONN_SUCCESS:        return SMPP_ESME_ROK;    case SMSCCONN_FAILED_QFULL:    case SMSCCONN_FAILED_TEMPORARILY:        return SMPP_ESME_RX_T_APPN;    }    return SMPP_ESME_RX_T_APPN;}static void handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu,    	    	       long *pending_submits){    SMPP_PDU *resp;    Octstr *os;    Msg *msg, *dlrmsg = NULL;    long reason;    long cmd_stat;    struct smpp_msg *smpp_msg = NULL;    resp = NULL;    switch (pdu->type) {        case data_sm:           resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);           /*            * If SMSCConn stopped then send temp. error code            */           mutex_lock(smpp->conn->flow_mutex);           if (smpp->conn->is_stopped) {                 mutex_unlock(smpp->conn->flow_mutex);                 resp->u.data_sm.command_status = SMPP_ESME_RX_T_APPN;                 break;           }           mutex_unlock(smpp->conn->flow_mutex);           /* got a deliver ack (DLR)?             * NOTE: following SMPP v3.4. spec. we are interested             *       only on bits 2-5 (some SMSC's send 0x44, and it's             *       spec. conforme)             */           if (pdu->u.data_sm.esm_class & (0x04|0x08)) {                debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",                      octstr_get_cstr(smpp->conn->id));                dlrmsg = handle_dlr(smpp, pdu->u.data_sm.source_addr, NULL, pdu->u.data_sm.message_payload,

⌨️ 快捷键说明

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