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

📄 smsc_at.c

📁 gateway-1.3.2.tar.gz WAP gw code
💻 C
📖 第 1 页 / 共 5 页
字号:
    message->sms.pid = pid;    /* deal with the user data -- 7 or 8 bit encoded */    tmpstr = octstr_copy(pdu, pos, len);    if (message->sms.coding == DC_8BIT || message->sms.coding == DC_UCS2) {        text = octstr_duplicate(tmpstr);    } else {        int offset = 0;        text = octstr_create("");        if (udhi && message->sms.coding == DC_7BIT) {            int nbits;            nbits = (udhlen + 1) * 8;            /* fill bits for UDH to septet boundary */            offset = (((nbits / 7) + 1) * 7 - nbits) % 7;             }        at2_decode7bituncompressed(tmpstr, len, text, offset);    }    message->sms.sender = origin;    if (octstr_len(privdata->my_number)) {        message->sms.receiver = octstr_duplicate(privdata->my_number);    } else {        /* Put a dummy address in the receiver for now (SMSC requires one) */        message->sms.receiver = octstr_create_from_data("1234", 4);    }    if (udhi) {        message->sms.udhdata = udh;    }    message->sms.msgdata = text;    message->sms.time = stime;    /* cleanup */    octstr_destroy(pdu);    octstr_destroy(tmpstr);    return message;    msg_error:    error(1,"AT2[%s]: Invalid DELIVER-SMS pdu !",	octstr_get_cstr(privdata->name));    O_DESTROY(udh);    O_DESTROY(origin);    O_DESTROY(text);    O_DESTROY(pdu);    return NULL;}Msg *at2_pdu_decode_report_sm(Octstr *data, PrivAT2data *privdata){   Msg* dlrmsg = NULL;   Octstr *pdu, *msg_id, *tmpstr = NULL, *receiver = NULL;   int type, tp_mr, len, ntype, pos;    /*     * parse the PDU.     */    /* convert the pdu to binary format for ease of processing */    pdu = at2_convertpdu(data);    /* Message reference */    tp_mr = octstr_get_char(pdu,1);    msg_id = octstr_format("%d",tp_mr);    debug("bb.smsc.at2",0,"AT2[%s]: got STATUS-REPORT for message <%d>:", octstr_get_cstr(privdata->name), tp_mr);        /* reciver address */    len = octstr_get_char(pdu, 2);    ntype = octstr_get_char(pdu, 3);    pos = 4;    if ((ntype & 0xD0) == 0xD0) {        /* Alphanumeric sender */        receiver = octstr_create("");        tmpstr = octstr_copy(pdu, pos, (len+1)/2);        at2_decode7bituncompressed(tmpstr, (((len - 1) * 4 - 3) / 7) + 1, receiver, 0);        octstr_destroy(tmpstr);        debug("bb.smsc.at2", 0, "AT2[%s]: Alphanumeric receiver <%s>",              octstr_get_cstr(privdata->name), octstr_get_cstr(receiver));        pos += (len + 1) / 2;    } else {	int i;        receiver = octstr_create("");        if ((ntype & 0x90) == 0x90) {            /* International number */            octstr_append_char(receiver, '+');        }        for (i = 0; i < len; i += 2, pos++) {            octstr_append_char(receiver, (octstr_get_char(pdu, pos) & 15) + 48);            if (i + 1 < len)                octstr_append_char(receiver, (octstr_get_char(pdu, pos) >> 4) + 48);        }        debug("bb.smsc.at2", 0, "AT2[%s]: Numeric receiver %s <%s>",              octstr_get_cstr(privdata->name), ((ntype & 0x90) == 0x90 ? "(international)" : ""),              octstr_get_cstr(receiver));    }    pos += 14; /* skip time stamps for now */    if ((type = octstr_get_char(pdu, pos)) == -1 ) {	error(1,"AT2[%s]: STATUS-REPORT pdu too short to have TP-Status field !",	    octstr_get_cstr(privdata->name));	goto error;    }	/* check DLR type:	 * 3GPP TS 23.040 defines this a bit mapped field with lots of options	 * most of which are not really intersting to us, as we are only interested	 * in one of three conditions : failed, held in SC for delivery later, or delivered successfuly	 * and here's how I suggest to test it (read the 3GPP reference for further detailes) -	 * we'll test the 6th and 5th bits (7th bit when set making all other values 'reseved' so I want to test it).	 */    type = type & 0xE0; /* filter out everything but the 7th, 6th and 5th bits */    switch (type) {        case 0x00:            /* 0 0 : success class */            type = DLR_SUCCESS;            tmpstr = octstr_create("Success");            break;        case 0x20:            /* 0 1 : buffered class (temporary error) */            type = DLR_BUFFERED;            tmpstr = octstr_create("Buffered");            break;        case 0x40:        case 0x60:        default:            /* 1 0 : failed class */            /* 1 1 : failed class (actually, temporary error but timed out) */            /* and any other value (can't think of any) is considered failure */            type = DLR_FAIL;            tmpstr = octstr_create("Failed");            break;    }    /* Actually, the above implementation is not correct, as the reference says that implementations should consider     * any "reserved" values to be "failure", but most reserved values fall into one of the three categories. it will catch     * "reserved" values where the first 3 MSBits are not set as "Success" which may not be correct. */    if ((dlrmsg = dlr_find(privdata->conn->id, msg_id, receiver, type)) == NULL) {	debug("bb.smsc.at2",1,"AT2[%s]: Received delivery notification but can't find that ID in the DLR storage",	    octstr_get_cstr(privdata->name));	    goto error;    }    /* Beware DLR URL is now in msg->sms.dlr_url given by dlr_find() */    dlrmsg->sms.msgdata = octstr_duplicate(tmpstr);	error:    O_DESTROY(tmpstr);    O_DESTROY(pdu);    O_DESTROY(receiver);    O_DESTROY(msg_id);    return dlrmsg;}Octstr *at2_convertpdu(Octstr *pdutext){    Octstr *pdu;    int i;    int len = octstr_len(pdutext);    pdu = octstr_create("");    for (i = 0; i < len; i += 2) {        octstr_append_char(pdu, at2_hexchar(octstr_get_char(pdutext, i)) * 16                           + at2_hexchar(octstr_get_char(pdutext, i + 1)));    }    return pdu;}int at2_rmask[8] = { 0, 1, 3, 7, 15, 31, 63, 127 };int at2_lmask[8] = { 0, 128, 192, 224, 240, 248, 252, 254 };void at2_decode7bituncompressed(Octstr *input, int len, Octstr *decoded, int offset){    unsigned char septet, octet, prevoctet;    int i;    int r = 1;    int c = 7;    int pos = 0;    /* Shift the buffer offset bits to the left */    if (offset > 0) {        unsigned char *ip;        for (i = 0, ip = octstr_get_cstr(input); i < octstr_len(input); i++) {            if (i == octstr_len(input) - 1)                *ip = *ip >> offset;            else                *ip = (*ip >> offset) | (*(ip + 1) << (8 - offset));            ip++;        }    }    octet = octstr_get_char(input, pos);    prevoctet = 0;    for (i = 0; i < len; i++) {        septet = ((octet & at2_rmask[c]) << (r - 1)) + prevoctet;        octstr_append_char(decoded, septet);        prevoctet = (octet & at2_lmask[r]) >> c;        /* When r=7 we have a full character in prevoctet */        if ((r == 7) && (i < len - 1)) {            i++;            octstr_append_char(decoded, prevoctet);            prevoctet = 0;        }        r = (r > 6) ? 1 : r + 1;        c = (c < 2) ? 7 : c - 1;        pos++;        octet = octstr_get_char(input, pos);    }    charset_gsm_to_latin1(decoded);}void at2_send_messages(PrivAT2data *privdata){    Msg *msg;    do {        if (privdata->modem->enable_mms && 			list_len(privdata->outgoing_queue) > 1)            at2_send_modem_command(privdata, "AT+CMMS=2", 0, 0);        if ((msg = list_extract_first(privdata->outgoing_queue)))            at2_send_one_message(privdata, msg);    } while (msg);}void at2_send_one_message(PrivAT2data *privdata, Msg *msg){    unsigned char command[500];    int ret = -1;    char sc[3];    int retries = RETRY_SEND;    if (octstr_len(privdata->my_number)) {        octstr_destroy(msg->sms.sender);        msg->sms.sender = octstr_duplicate(privdata->my_number);    }    /*      * The standard says you should be prepending the PDU with 00 to indicate      * to use the default SC. Some older modems dont expect this so it can be      * disabled      * NB: This extra padding is not counted in the CMGS byte count      */    sc[0] = '\0';    if (!privdata->modem->no_smsc)        strcpy(sc, "00");    if (msg_type(msg) == sms) {	Octstr* pdu;	if ((pdu = at2_pdu_encode(msg, privdata)) == NULL) {	    error(2, "AT2[%s]: Error encoding PDU!",octstr_get_cstr(privdata->name));	    return;	}	        ret = -99;        retries = RETRY_SEND;        while ((ret != 0) && (retries-- > 0)) {	    int msg_id = -1;            /*              * send the initial command and then wait for >              */            sprintf(command, "AT+CMGS=%ld", octstr_len(pdu) / 2);                        ret = at2_send_modem_command(privdata, command, 5, 1);            debug("bb.smsc.at2", 0, "AT2[%s]: send command status: %d",                  octstr_get_cstr(privdata->name), ret);            if (ret != 1) /* > only! */                continue;            /*              * ok the > has been see now so we can send the PDU now and a              * control Z but no CR or LF              */            sprintf(command, "%s%s", sc, octstr_get_cstr(pdu));            at2_write(privdata, command);            at2_write_ctrlz(privdata);            /* wait 20 secs for modem command */            ret = at2_wait_modem_command(privdata, 20, 0, &msg_id);            debug("bb.smsc.at2", 0, "AT2[%s]: send command status: %d",                  octstr_get_cstr(privdata->name), ret);            if (ret != 0) /* OK only */                continue;	    /* store DLR message if needed for SMSC generated delivery reports */	    if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {		if (msg_id == -1)		    error(0,"AT2[%s]: delivery notification requested, but I have no message ID!",			octstr_get_cstr(privdata->name));		else {                    Octstr *dlrmsgid = octstr_format("%d", msg_id);                    dlr_add(privdata->conn->id, dlrmsgid, msg);		    O_DESTROY(dlrmsgid);		}	    }            bb_smscconn_sent(privdata->conn, msg, NULL);        }        if (ret != 0) {            /*             * no need to do counter_increase(privdata->conn->failed) here,             * since bb_smscconn_send_failed() will inc the counter on             * SMSCCONN_FAILED_MALFORMED             */            bb_smscconn_send_failed(privdata->conn, msg,	        SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED"));        }        O_DESTROY(pdu);    }}Octstr* at2_pdu_encode(Msg *msg, PrivAT2data *privdata){    /*     * Message coding is done as a binary octet string,     * as per 3GPP TS 23.040 specification (GSM 03.40),     */    Octstr *pdu = NULL, *temp = NULL, *buffer = octstr_create("");         int len, setvalidity = 0;    /*      * message type SUBMIT , bit mapped :     * bit7                            ..                                    bit0     * TP-RP , TP-UDHI, TP-SRR, TP-VPF(4), TP-VPF(3), TP-RD, TP-MTI(1), TP-MTI(0)     */    octstr_append_char(buffer,	((msg->sms.rpi > 0 ? 1 : 0) << 7) /* TP-RP */	| ((octstr_len(msg->sms.udhdata)  ? 1 : 0) << 6) /* TP-UDHI */	| ((DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask) ? 1 : 0) << 5) /* TP-SRR */	| 16 /* TP-VP(Rel)*/	| 1 /* TP-MTI: SUBMIT_SM */	);    /* message reference (0 for now) */    octstr_append_char(buffer, 0);    /* destination address */    if ((temp = at2_format_address_field(msg->sms.receiver)) == NULL)	goto error;    octstr_append(buffer, temp);    O_DESTROY(temp);    octstr_append_char(buffer, (msg->sms.pid == -1 ? 0 : msg->sms.pid) ); /* protocol identifier */    octstr_append_char(buffer, fields_to_dcs(msg, /* data coding scheme */	(msg->sms.alt_dcs != -1 ? msg->sms.alt_dcs : privdata->conn->alt_dcs)));    /*      * Validity-Period (TP-VP)     * see GSM 03.40 section 9.2.3.12     * defaults to 24 hours = 167 if not set      */    if ( msg->sms.validity >= 0) {        if (msg->sms.validity > 635040)            setvalidity = 255;        if (msg->sms.validity >= 50400 && msg->sms.validity <= 635040)            setvalidity = (msg->sms.validity - 1) / 7 / 24 / 60 + 192 + 1;        if (msg->sms.validity > 43200 && msg->sms.validity < 50400)            setvalidity = 197;        if (msg->sms.validity >= 2880 && msg->sms.validity <= 43200)            setvalidity = (msg->sms.validity - 1) / 24 / 60 + 166 + 1;        if (msg->sms.validity > 1440 && msg->sms.validity < 2880)            setvalidity = 168;        if (msg->sms.validity >= 750 && msg->sms.validity <= 1440)            setvalidity = (msg->sms.validity - 720 - 1) / 30 + 143 + 1;        if (msg->sms.validity > 720 && msg->sms.validity < 750)            setvalidity = 144;        if (msg->sms.validity >= 5 && msg->sms.validity <= 720)            setvalidity = (msg->sms.validity - 1) / 5 - 1 + 1;        if (msg->sms.validity < 5)            setvalidity = 0;    } else        setvalidity = (privdata->validityperiod != NULL ?             atoi(octstr_get_cstr(privdata->validityperiod)) : 167);    if (setvalidity >= 0 && setvalidity <= 143)        debug("bb.smsc.at2", 0, "AT2[%s]: TP-Validity-Period: %d minutes",              octstr_get_cstr(privdata->name), (setvalidity + 1)*5);    else if (setvalidity >= 144 && setvalidity <= 167)        debug("bb.smsc.at2", 0, "AT2[%s]: TP-Validity-Period: %3.1f hours",              octstr_get_cstr(privdata->name), ((float)(setvalidity - 143) / 2) + 12);    else if (setvalidity >= 168 && setvalidity <= 196)        debug("bb.smsc.at2", 0, "AT2[%s]: TP-Validity-Period: %d days",              octstr_get_cstr(privda

⌨️ 快捷键说明

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