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

📄 smsc_oisd.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
        octstr_append_char(raw8, oisd_expand_gsm7_from_bits(bits, i));    }    gw_free(bits);    return raw8;}static void oisd_shrink_gsm7(Octstr *str){    Octstr *result;    int len, i;    int numbits, value;    result = octstr_create("");    len = octstr_len(str);    value = 0;    numbits = 0;    for (i = 0; i < len; i++) {        value += octstr_get_char(str, i) << numbits;        numbits += 7;        if (numbits >= 8) {            octstr_append_char(result, value & 0xff);            value >>= 8;            numbits -= 8;        }    }    if (numbits > 0)        octstr_append_char(result, value);    octstr_delete(str, 0, LONG_MAX);    octstr_append(str, result);    octstr_destroy(result);}/**************************************************************************** * Packet encoding functions.  They do not allow the creation of invalid * OISD packets. ***************************************************************************//* Build a new packet struct with this operation code and sequence number. */static struct packet *packet_create(int operation, unsigned long opref){    struct packet *packet;    unsigned char header[10];    packet = gw_malloc(sizeof(*packet));    packet->operation = operation;    packet->opref = opref;    /* Opref */    header[0] = opref & 0xff;    header[1] = (opref >> 8) & 0xff;    header[2] = (opref >> 16) & 0xff;    header[3] = (opref >> 24) & 0xff;    /* Message Type & Operation */    if (operation > RESPONSE) {        header[4] = RESULT;        header[5] = operation - RESPONSE;    } else {        header[4] = INVOKE;        header[5] = operation;    }    /* Unused */    header[6] = 0;    header[7] = 0;    /* Data Size */    header[8] = 0;    header[9] = 0;    packet->data = octstr_create_from_data(header, 10);    return packet;}static void packet_set_data_size(struct packet *packet){    int len;    gw_assert(packet != NULL);    len = octstr_len(packet->data) - 10;    octstr_set_char(packet->data, 8, len & 0xff); /* Data Size */    octstr_set_char(packet->data, 9, (len >> 8) & 0xff);}static void packet_set_sequence(struct packet *packet, unsigned long opref){    gw_assert(packet != NULL);    octstr_set_char(packet->data, 0, opref & 0xff);    octstr_set_char(packet->data, 1, (opref >> 8) & 0xff);    octstr_set_char(packet->data, 2, (opref >> 16) & 0xff);    octstr_set_char(packet->data, 3, (opref >> 24) & 0xff);    packet->opref = opref;}static struct packet *packet_encode_message(Msg *msg, SMSCConn *conn){    struct packet *packet;    PrivData *pdata = conn->data;    int DCS;    int setvalidity = 0;    int so = 0;    int udhlen7, udhlen8;    int msglen7, msglen8;    Octstr *udhdata = NULL;    Octstr *msgdata = NULL;    gw_assert(msg != NULL);    gw_assert(msg->type == sms);    gw_assert(msg->sms.receiver != NULL);    DCS = fields_to_dcs(msg, 0);    if (msg->sms.sender == NULL)        msg->sms.sender = octstr_create("");    if (!parm_valid_address(msg->sms.receiver)) {        warning(0, "OISD[%s]: non-digits in destination phone number '%s', discarded",                octstr_get_cstr(conn->id),                octstr_get_cstr(msg->sms.receiver));        return NULL;    }    if (!parm_valid_address(msg->sms.sender)) {        warning(0, "OISD[%s]: non-digits in originating phone number '%s', discarded",                octstr_get_cstr(conn->id),                octstr_get_cstr(msg->sms.sender));        return NULL;    }    packet = packet_create(SUBMIT_SM, BOGUS_SEQUENCE);    gw_assert(octstr_check_range(msg->sms.receiver, 0,                                 octstr_len(msg->sms.receiver), isphonedigit));    /* MSISDN length */    octstr_append_char(packet->data,                       (unsigned char) octstr_len(msg->sms.receiver));    /* MSISDN */    octstr_append(packet->data, msg->sms.receiver);    /* Duplicate msg. behaviour */    /* 1=reject duplicates, 2=allow duplicates */    octstr_append_char(packet->data, 2);    /* SME ref. no. unused in this protocol implementation, but set */    octstr_append_char(packet->data, 0);    octstr_append_char(packet->data, 0);    octstr_append_char(packet->data, 0);    octstr_append_char(packet->data, 0);    /* Priority 0=high, 1=normal */    octstr_append_char(packet->data, 1);    gw_assert(octstr_check_range(msg->sms.sender, 0,                                 octstr_len(msg->sms.sender), isphonedigit));    /* Originating address length */    octstr_append_char(packet->data,                       (unsigned char) (octstr_len(msg->sms.sender) + 2));    /* XXX: GSM operator dependent ? */    /* TON */    octstr_append_char(packet->data, 0x42);    /* NPI */    octstr_append_char(packet->data, 0x44);    /* Originating address */    octstr_append(packet->data, msg->sms.sender);    /* Validity period type 0=none, 1=absolute, 2=relative */    /*     * Validity-Period (TP-VP)     * see GSM 03.40 section 9.2.3.12     */    if ((setvalidity = msg->sms.validity) != SMS_PARAM_UNDEFINED ||        (setvalidity = pdata->validityperiod) != SMS_PARAM_UNDEFINED) {        /* Validity period type 0=none, 1=absolute, 2=relative */        octstr_append_char(packet->data, 2);        if (setvalidity > 635040)            setvalidity = 255;        else if (setvalidity >= 50400 && setvalidity <= 635040)            setvalidity = (setvalidity - 1) / 7 / 24 / 60 + 192 + 1;        else if (setvalidity > 43200 && setvalidity < 50400)            setvalidity = 197;        else if (setvalidity >= 2880 && setvalidity <= 43200)            setvalidity = (setvalidity - 1) / 24 / 60 + 166 + 1;        else if (setvalidity > 1440 && setvalidity < 2880)            setvalidity = 168;        else if (setvalidity >= 750 && setvalidity <= 1440)            setvalidity = (setvalidity - 720 - 1) / 30 + 143 + 1;        else if (setvalidity > 720 && setvalidity < 750)            setvalidity = 144;        else if (setvalidity >= 5 && setvalidity <= 720)            setvalidity = (setvalidity - 1) / 5 - 1 + 1;        else if (setvalidity < 5)            setvalidity = 0;        octstr_append_char(packet->data, setvalidity);    } else {        /* Validity period type 0=none, 1=absolute, 2=relative */        octstr_append_char(packet->data, 0);        setvalidity = 0; /* reset */    }    if (setvalidity >= 0 && setvalidity <= 143)        debug("bb.smsc.oisd", 0, "OISD[%s]: Validity-Period: %d minutes",              octstr_get_cstr(conn->id), (setvalidity + 1)*5);    else if (setvalidity >= 144 && setvalidity <= 167)        debug("bb.smsc.oisd", 0, "OISD[%s]: Validity-Period: %3.1f hours",              octstr_get_cstr(conn->id), ((float)(setvalidity - 143) / 2) + 12);    else if (setvalidity >= 168 && setvalidity <= 196)        debug("bb.smsc.oisd", 0, "OISD[%s]: Validity-Period: %d days",              octstr_get_cstr(conn->id), (setvalidity - 166));    else        debug("bb.smsc.oisd", 0, "OISD[%s]: Validity-Period: %d weeks",              octstr_get_cstr(conn->id), (setvalidity - 192));    /* Data coding scheme */    octstr_append_char(packet->data, DCS);    /* Explicitly ask not to get status reports.     * If we do not do this, the server's default might be to     * send status reports in some cases, and we don't do anything     * with those reports anyway. */    /* ask for the delivery reports if needed*/    if (!pdata->no_dlr)        if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))            octstr_append_char(packet->data, 7);        else            octstr_append_char(packet->data, 0);    else if (pdata->no_dlr && DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))        warning(0, "OISD[%s]: dlr request make no sense while no-dlr set to true",             octstr_get_cstr(conn->id));    /* Protocol id 0=default */    octstr_append_char(packet->data, 0);    if (octstr_len(msg->sms.udhdata))        so |= 0x02;    if (msg->sms.coding == DC_8BIT)        so |= 0x10;    /* Submission options */    octstr_append_char(packet->data, so);    udhlen8 = octstr_len(msg->sms.udhdata);    msglen8 = octstr_len(msg->sms.msgdata);    udhdata = octstr_duplicate(msg->sms.udhdata);    msgdata = octstr_duplicate(msg->sms.msgdata);    if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) {        debug("bb.sms.oisd", 0, "OISD[%s]: sending latin1=%s",              octstr_get_cstr(conn->id),              octstr_get_cstr(msg->sms.msgdata));        charset_latin1_to_gsm(msgdata);        oisd_shrink_gsm7(msgdata);    }    /* calculate lengths */    udhlen7 = octstr_len(udhdata);    msglen7 = octstr_len(msgdata);    octstr_append_char(packet->data, (unsigned char) (udhlen8 + msglen8));    octstr_append_char(packet->data, (unsigned char) (udhlen7 + msglen7));    /*     * debug("bb.sms.oisd", 0, "OISD[%s]: packet_encode_message udhlen8=%d, msglen8=%d",     *       octstr_get_cstr(conn->id), udhlen8, msglen8);     * debug("bb.sms.oisd", 0, "OISD[%s]: packet_encode_message udhlen7=%d, msglen7=%d",     *       octstr_get_cstr(conn->id), udhlen7, msglen7);     */    /* copy text */    octstr_append(packet->data, udhdata);    octstr_append(packet->data, msgdata);    /* Sub-logical SME number */    octstr_append_char(packet->data, 0);    octstr_append_char(packet->data, 0);    octstr_destroy(udhdata);    octstr_destroy(msgdata);    return packet;}/*************************************************************************** * Protocol functions.  These implement various transactions.              * ***************************************************************************//* Give this packet a proper sequence number for sending. */static void packet_set_send_sequence(struct packet *packet, PrivData *pdata){    gw_assert(pdata != NULL);    packet_set_sequence(packet, pdata->send_seq);    pdata->send_seq++;}static struct packet *oisd_get_packet(PrivData *pdata, Octstr **ts){    struct packet *packet = NULL;    gw_assert(pdata != NULL);    /* If packet is already available, don't try to read anything */    packet = packet_extract(pdata->inbuffer, pdata->conn);    while (packet == NULL) {        if (read_available(pdata->socket, RESPONSE_TIMEOUT) != 1) {            warning(0, "OISD[%s]: SMSC is not responding",                    octstr_get_cstr(pdata->conn->id));            return NULL;        }        if (octstr_append_from_socket(pdata->inbuffer, pdata->socket) <= 0) {            error(0, "OISD[%s]: oisd_get_packet: read failed",                  octstr_get_cstr(pdata->conn->id));            return NULL;        }        packet = packet_extract(pdata->inbuffer, pdata->conn);    }    packet_check_can_receive(packet, pdata->conn);    debug("bb.sms.oisd", 0, "OISD[%s]: received",          octstr_get_cstr(pdata->conn->id));    if (packet->operation != RETRIEVE_REQUEST + RESPONSE)        octstr_dump(packet->data, 0);    if (ts)        *ts = octstr_copy(packet->data, 15, 14);    if (pdata->keepalive > 0)        pdata->next_ping = time(NULL) + pdata->keepalive;    return packet;}/* * Acknowledge a request. */static void oisd_send_response(struct packet *request, PrivData *pdata){    struct packet *response;    gw_assert(request != NULL);    gw_assert(request->operation < RESPONSE);    response = packet_create(request->operation + RESPONSE, request->opref);    octstr_append_char(response->data, (char) RESULT_SUCCESS);    packet_set_data_size(response);    debug("bb.sms.oisd", 0, "OISD[%s]: sending response",          octstr_get_cstr(pdata->conn->id));    octstr_dump(response->data, 0);    /* Don't check errors here because if there is something     * wrong with the socket, the main loop will detect it. */    octstr_write_to_socket(pdata->socket, response->data);    packet_destroy(response);}static Msg *oisd_accept_message(struct packet *request, SMSCConn *conn){    Msg *msg = NULL;    int DCS;    int dest_len;    int origin_len;    int add_info;    int msglen7, msglen8;    int udh_len;    msg = msg_create(sms);    /* See GSM 03.38.  The bit patterns we can handle are:     *   000xyyxx  Uncompressed text, yy indicates alphabet.     *                   yy = 00, default alphabet     *                   yy = 01, 8-bit data     *                   yy = 10, UCS2     *                   yy = 11, reserved     *   1111xyxx  Data, y indicates alphabet.     *                   y = 0, default alphabet     *                   y = 1, 8-bit data     */    /* Additional information     *   xxxxxxyz  This field conveys additional information to assist

⌨️ 快捷键说明

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