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

📄 smsc_smasi.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
 */static Octstr *get_dest_addr_ton(SMASI *smasi, Msg *msg) {    return get_ton_npi_value(smasi->dest_addr_ton,                              GSM_ADDR_TON_INTERNATIONAL);}/* * Gets the value to be used as dest_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_dest_addr_npi(SMASI *smasi, Msg *msg) {    return get_ton_npi_value(smasi->dest_addr_npi,                              GSM_ADDR_NPI_E164);}/* * Determine the originator (sender number) type based on the number. Will * change the originator number if necessary. */static Octstr *get_originator_type(SMASI *smasi, Octstr *originator) {    /* International or alphanumeric sender? */    if (octstr_get_char(originator, 0) == '+') {        if (!octstr_check_range(originator, 1, 256, gw_isdigit)) {            return octstr_format("%ld", GSM_ADDR_TON_ALPHANUMERIC);        } else {           /* Numeric sender address with + in front: The + has to be            * removed from this international number.            */           octstr_delete(originator, 0, 1);           return octstr_format("%ld", GSM_ADDR_TON_INTERNATIONAL);        }    } else if (!octstr_check_range(originator, 0, 256, gw_isdigit)) {       return octstr_format("%ld", GSM_ADDR_TON_ALPHANUMERIC);    }    /* Return the default value. */    return octstr_format("%ld", GSM_ADDR_TON_INTERNATIONAL);}/* * Creates a SubmitReq PDU from an outgoing message. */static SMASI_PDU *msg_to_pdu(SMASI *smasi, Msg *msg) {    SMASI_PDU *pdu = smasi_pdu_create(SubmitReq);    pdu->u.SubmitReq.Destination = octstr_duplicate(msg->sms.receiver);    pdu->u.SubmitReq.Body = octstr_duplicate(msg->sms.msgdata);    pdu->u.SubmitReq.Originator = octstr_duplicate(msg->sms.sender);    pdu->u.SubmitReq.OriginatorType =         get_originator_type(smasi, pdu->u.SubmitReq.Originator);    pdu->u.SubmitReq.Sequence =         octstr_format("%ld", counter_increase(smasi->message_id_counter));    /* If its a international number starting with +, lets remove the +. */    if (octstr_get_char(pdu->u.SubmitReq.Destination, 0) == '+')        octstr_delete(pdu->u.SubmitReq.Destination, 0,1);    /* Do ton and npi override - if configured. Use values from message     * otherwise.     */    pdu->u.SubmitReq.OriginatorType = get_source_addr_ton(smasi, msg);    pdu->u.SubmitReq.OriginatorPlan = get_source_addr_npi(smasi, msg);    pdu->u.SubmitReq.DestinationType = get_dest_addr_ton(smasi, msg);    pdu->u.SubmitReq.DestinationPlan = get_dest_addr_npi(smasi, msg);           /* Set priority. */    if (smasi->priority >= 0 && smasi->priority <= 3) {        pdu->u.SubmitReq.MqPriority = octstr_format("%ld", smasi->priority);    } else {        pdu->u.SubmitReq.MqPriority = octstr_format("%ld", 0);    }    /* Set encoding. */    if (msg->sms.coding != 0) {        if (msg->sms.coding == 1)            pdu->u.SubmitReq.MsEncoding = octstr_create("7bit");        else if (msg->sms.coding == 2)            pdu->u.SubmitReq.MsEncoding = octstr_create("8bit");        else if (msg->sms.coding == 2)            pdu->u.SubmitReq.MsEncoding = octstr_create("16bit");        /* Everything else will default to 7bit. */    }    /* Set messaging class - if within defined parameter range. */    if (msg->sms.mclass >= 0 && msg->sms.mclass <= 4)        pdu->u.SubmitReq.Class = octstr_format("%ld", (msg->sms.mclass - 1));    /* Set Protocol ID. */    pdu->u.SubmitReq.ProtocolID = octstr_format("%ld", msg->sms.pid);    /* Check if SMS is binary. */    if (msg->sms.udhdata && octstr_len(msg->sms.udhdata) > 0) {                pdu->u.SubmitReq.UserDataHeader =          octstr_duplicate(msg->sms.udhdata);        pdu->u.SubmitReq.BodyEncoding =          octstr_create("Data");        if (pdu->u.SubmitReq.MsEncoding)          octstr_destroy(pdu->u.SubmitReq.MsEncoding);        pdu->u.SubmitReq.MsEncoding =          octstr_create("transparent");        /* Encode data. */        encode_binary_data(pdu->u.SubmitReq.UserDataHeader);        encode_binary_data(pdu->u.SubmitReq.Body);    } else {        /* Otherwise do data escaping. */        escape_data(pdu->u.SubmitReq.Body);    }     return pdu;} /* * Create a message structure from an incoming DeliverReq PDU. */static Msg *pdu_to_msg(SMASI_PDU *pdu) {    Msg *msg = NULL;    gw_assert(pdu->type == DeliverReq);    gw_assert(pdu->u.DeliverReq.Originator);    gw_assert(pdu->u.DeliverReq.Destination);    gw_assert(pdu->u.DeliverReq.Body);    msg = msg_create(sms);;    msg->sms.sender = octstr_duplicate(pdu->u.DeliverReq.Originator);    msg->sms.receiver = octstr_duplicate(pdu->u.DeliverReq.Destination);    msg->sms.msgdata = octstr_duplicate(pdu->u.DeliverReq.Body);     /* Unescape (non-binary) or decode (binary) data. */    if (pdu->u.DeliverReq.UserDataHeader &&        octstr_len(pdu->u.DeliverReq.UserDataHeader) > 0) {        msg->sms.udhdata = octstr_duplicate(pdu->u.DeliverReq.UserDataHeader);        decode_binary_data(msg->sms.msgdata);        decode_binary_data(msg->sms.udhdata);    } else {        unescape_data(msg->sms.msgdata);    }     /* Read priority. */    if (pdu->u.DeliverReq.ProtocolId)        if (octstr_parse_long(&msg->sms.pid,                               pdu->u.DeliverReq.ProtocolId, 0, 10) == -1)            msg->sms.pid = 0;    /* Read Coding. */    if (pdu->u.SubmitReq.MsEncoding) {        /* Use specified coding. */        if (octstr_str_compare(pdu->u.SubmitReq.MsEncoding, "7bit") == 0)            msg->sms.coding = 1;        else if (octstr_str_compare(pdu->u.SubmitReq.MsEncoding, "8bit") == 0)            msg->sms.coding = 2;        else if (octstr_str_compare(pdu->u.SubmitReq.MsEncoding, "UCS2") == 0)            msg->sms.coding = 3;        else if (octstr_str_compare(pdu->u.SubmitReq.MsEncoding, "transparent") == 0)            msg->sms.coding = 2;    } else {        /* Determine specified coding according to udhdata presence. */        if (pdu->u.SubmitReq.UserDataHeader)            msg->sms.coding = 2;        else            msg->sms.coding = 1;    }    /* Read message class. */    if (pdu->u.SubmitReq.Class) {        if (octstr_parse_long(&msg->sms.mclass,                               pdu->u.SubmitReq.Class, 0, 10) == -1)            msg->sms.mclass = 0;    /* Set to unspecified. */        else            msg->sms.mclass++;      /* Correct value mapping. */    }    /* Read protocol ID. */    if (pdu->u.SubmitReq.ProtocolID)        if (octstr_parse_long(&msg->sms.pid,                               pdu->u.SubmitReq.ProtocolID, 0, 10) == -1)            msg->sms.pid = 0;    return msg;} /************************************************************************//* PDU HANDLING                                                         *//************************************************************************/static void send_logoff(SMASI *smasi, Connection *conn) {    SMASI_PDU *pdu = NULL;    Octstr *os = NULL;    counter_increase(smasi->message_id_counter);    pdu = smasi_pdu_create(LogoffReq);    pdu->u.LogoffReq.Reason = octstr_create("Client shutting down");    dump_pdu("Sending !LogoffReq:", smasi->conn->id, pdu);     os = smasi_pdu_pack(pdu);    conn_write(conn, os);    octstr_destroy(os);    smasi_pdu_destroy(pdu);} static void send_enquire_link(SMASI *smasi, Connection *conn, long *last_sent) {     SMASI_PDU *pdu = NULL;     Octstr *os = NULL;      if (date_universal_now() - *last_sent < smasi->enquire_link_interval)        return;     *last_sent = date_universal_now();      pdu = smasi_pdu_create(EnquireLinkReq);    dump_pdu("Sending EnquireLinkReq:", smasi->conn->id, pdu);     os = smasi_pdu_pack(pdu);     if (os)	   conn_write(conn, os); /* Write errors checked by caller. */     octstr_destroy(os);     smasi_pdu_destroy(pdu); } static int send_pdu(Connection *conn, Octstr *id, SMASI_PDU *pdu){    Octstr * os = NULL;    int ret = 0;    dump_pdu("Sending PDU:", id, pdu);     os = smasi_pdu_pack(pdu);    if (os) ret = conn_write(conn, os);    else ret = -1;    octstr_destroy(os);    return ret;} /* * Try to read a SMASI PDU from a connection. Return -1 for error (caller * should close the connection), 0 for no PDU ready yet, or 1 for PDU read * and unpacked. Return a pointer to the PDU in `*pdu'. */static int read_pdu(SMASI *smasi, Connection *conn, SMASI_PDU **pdu) {    Octstr *os;        os = smasi_pdu_read(conn);    if (os == NULL) {        if (conn_eof(conn) || conn_read_error(conn))             return -1;        return 0;    }    *pdu = smasi_pdu_unpack(os);    if (*pdu == NULL) {        error(0, "SMASI[%s]: PDU unpacking failed.",              octstr_get_cstr(smasi->conn->id));        debug("bb.sms.smasi", 0, "SMASI[%s]: Failed PDU follows.",              octstr_get_cstr(smasi->conn->id));        octstr_dump(os, 0);        octstr_destroy(os);        return -1;    }    octstr_destroy(os);    return 1;}static void handle_pdu(SMASI *smasi, Connection *conn,                        SMASI_PDU *pdu, long *pending_submits) {    SMASI_PDU *resp = NULL;    Msg *msg = NULL;    long reason;    switch (pdu->type) {        case DeliverReq:            msg = pdu_to_msg(pdu);            if (smasi->my_number && octstr_len(smasi->my_number)) {                octstr_destroy(msg->sms.receiver);                msg->sms.receiver = octstr_duplicate(smasi->my_number);            }            time(&msg->sms.time);            msg->sms.smsc_id = octstr_duplicate(smasi->conn->id);            bb_smscconn_receive(smasi->conn, msg);            resp = smasi_pdu_create(DeliverConf);            if (pdu->u.DeliverReq.Sequence)                resp->u.DeliverConf.Sequence =                  octstr_duplicate(pdu->u.DeliverReq.Sequence);            if (pdu->u.DeliverReq.MsgReference)                resp->u.DeliverConf.MsgReference =                  octstr_duplicate(pdu->u.DeliverReq.MsgReference);            break;        case SubmitConf:            if (pdu->u.SubmitConf.Sequence) {                msg = dict_remove(smasi->sent_msgs,                                   pdu->u.SubmitConf.Sequence);            } else {                msg = NULL;            }            if (msg == NULL) {                warning(0, "SMASI[%s]: SMSC sent SubmitConf for unknown message.",                        octstr_get_cstr(smasi->conn->id));            } else {                debug("bb.sms.smasi",0,                      "SMSC[%s]: SMSC confirmed msg seq <%s> ref <%s>",                       octstr_get_cstr(smasi->conn->id),                       octstr_get_cstr(pdu->u.SubmitConf.Sequence),                       octstr_get_cstr(pdu->u.SubmitConf.MsgReference));                bb_smscconn_sent(smasi->conn, msg);                --(*pending_submits);            }            break;        case SubmitRej:            if (pdu->u.SubmitRej.Sequence) {                msg = dict_remove(smasi->sent_msgs,                                   pdu->u.SubmitRej.Sequence);            } else {                msg = NULL;            }            error(0, "SMASI[%s]: SMSC returned error code %s for "                  "message ref <%s>", octstr_get_cstr(smasi->conn->id),                  octstr_get_cstr(pdu->u.SubmitRej.RejectCode),                  octstr_get_cstr(pdu->u.SubmitRej.MsgReference));            if (msg == NULL) {               warning(0, "SMASI[%s]: SMSC sent SubmitRej for unknown message.",                       octstr_get_cstr(smasi->conn->id));            } else {                reason = SMSCCONN_FAILED_REJECTED;                bb_smscconn_send_failed(smasi->conn, msg, reason);                --(*pending_submits);

⌨️ 快捷键说明

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