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

📄 smsc_cimd2.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
        Octstr *name = operation_name(packet->operation);        warning(0, "CIMD2 SMSC sent us %s request",                octstr_get_cstr(name));        octstr_destroy(name);    }}/* Table of known error codes */static struct{    int code;    unsigned char *text;}cimd2_errors[] = {    { 0, "No error" },    { 1, "Unexpected operation" },    { 2, "Syntax error" },    { 3, "Unsupported parameter error" },    { 4, "Connection to message center lost" },    { 5, "No response from message center" },    { 6, "General system error" },    { 7, "Cannot find information" },    { 8, "Parameter formatting error" },    { 9, "Requested operation failed" },    /* LOGIN error codes */    { 100, "Invalid login" },    { 101, "Incorrect access type" },    { 102, "Too many users with this login id" },    { 103, "Login refused by message center" },    /* SUBMIT MESSAGE error codes */    { 300, "Incorrect destination address" },    { 301, "Incorrect number of destination addresses" },    { 302, "Syntax error in user data parameter" },    { 303, "Incorrect bin/head/normal user data parameter combination" },    { 304, "Incorrect data coding scheme parameter usage" },    { 305, "Incorrect validity period parameters usage" },    { 306, "Incorrect originator address usage" },    { 307, "Incorrect pid paramterer usage" },    { 308, "Incorrect first delivery parameter usage" },    { 309, "Incorrect reply path usage" },    { 310, "Incorrect status report request parameter usage" },    { 311, "Incorrect cancel enabled parameter usage" },    { 312, "Incorrect priority parameter usage" },    { 313, "Incorrect tariff class parameter usage" },    { 314, "Incorrect service description parameter usage" },    { 315, "Incorrect transport type parameter usage" },    { 316, "Incorrect message type parameter usage" },    { 318, "Incorrect mms parameter usage" },    { 319, "Incorrect operation timer parameter usage" },    /* ENQUIRE MESSAGE STATUS error codes */    { 400, "Incorrect address parameter usage" },    { 401, "Incorrect scts parameter usage" },    /* DELIVERY REQUEST error codes */    { 500, "Incorrect scts parameter usage" },    { 501, "Incorrect mode parameter usage" },    { 502, "Incorrect parameter combination" },    /* CANCEL MESSAGE error codes */    { 600, "Incorrect scts parameter usage" },    { 601, "Incorrect address parameter usage" },    { 602, "Incorrect mode parameter usage" },    { 603, "Incorrect parameter combination" },    /* SET error codes */    { 800, "Changing password failed" },    { 801, "Changing password not allowed" },    /* GET error codes */    { 900, "Unsupported item requested" },    { -1, NULL }};static int packet_display_error(struct packet *packet){    int code;    Octstr *text = NULL;    Octstr *opname = NULL;    code = packet_get_int_parm(packet, P_ERROR_CODE);    text = packet_get_string_parm(packet, P_ERROR_TEXT);    if (code <= 0) {        octstr_destroy(text);        return 0;    }    if (text == NULL) {        /* No error text.  Try to find it in the table. */        int i;        for (i = 0; cimd2_errors[i].text != NULL; i++) {            if (cimd2_errors[i].code == code) {                text = octstr_create(cimd2_errors[i].text);                break;            }        }    }    if (text == NULL) {        /* Still no error text.  Make one up. */        text = octstr_create("Unknown error");    }    opname = operation_name(packet->operation);    error(0, "CIMD2 %s contained error message:",          octstr_get_cstr(opname));    error(0, "code %03d: %s", code, octstr_get_cstr(text));    octstr_destroy(opname);    octstr_destroy(text);    return code;}/* Table of special combinations, for convert_gsm_to_latin1. *//* Each cimd1, cimd2 pair is mapped to a character in the GSM default * character set. */static const struct{    unsigned char cimd1, cimd2;    unsigned char gsm;}cimd_combinations[] = {    { 'O', 'a', 0 },     /* @ */    { 'L', '-', 1 },     /* Pounds sterling */    { 'Y', '-', 3 },     /* Yen */    { 'e', '`', 4 },     /* egrave */    { 'e', '\'', 5 },    /* eacute */    { 'u', '`', 6 },     /* ugrave */    { 'i', '`', 7 },     /* igrave */    { 'o', '`', 8 },     /* ograve */    { 'C', ',', 9 },     /* C cedilla */    { 'O', '/', 11 },    /* Oslash */    { 'o', '/', 12 },    /* oslash */    { 'A', '*', 14 },    /* Aring */    { 'a', '*', 15 },    /* aring */    { 'g', 'd', 16 },    /* greek delta */    { '-', '-', 17 },    /* underscore */    { 'g', 'f', 18 },    /* greek phi */    { 'g', 'g', 19 },    /* greek gamma */    { 'g', 'l', 20 },    /* greek lambda */    { 'g', 'o', 21 },    /* greek omega */    { 'g', 'p', 22 },    /* greek pi */    { 'g', 'i', 23 },    /* greek psi */    { 'g', 's', 24 },    /* greek sigma */    { 'g', 't', 25 },    /* greek theta */    { 'g', 'x', 26 },    /* greek xi */    { 'X', 'X', 27 },    /* escape */    { 'A', 'E', 28 },    /* AE ligature */    { 'a', 'e', 29 },    /* ae ligature */    { 's', 's', 30 },    /* german double s */    { 'E', '\'', 31 },   /* Eacute */    { 'q', 'q', '"' },    { 'o', 'x', 36 },    /* international currency symbol */    { '!', '!', 64 },    /* inverted ! */    { 'A', '"', 91 },    /* Adieresis */    { 'O', '"', 92 },    /* Odieresis */    { 'N', '~', 93 },    /* N tilde */    { 'U', '"', 94 },    /* Udieresis */    { 's', 'o', 95 },    /* section mark */    { '?', '?', 96 },    /* inverted ? */    { 'a', '"', 123 },   /* adieresis */    { 'o', '"', 124 },   /* odieresis */    { 'n', '~', 125 },   /* n tilde */    { 'u', '"', 126 },   /* udieresis */    { 'a', '`', 127 },   /* agrave */    { 0, 0, 0 }};/* Convert text in the CIMD2 User Data format to the GSM default * character set. * CIMD2 allows 8-bit characters in this format; they map directly * to the corresponding ISO-8859-1 characters.  Since we are heading * toward that character set in the end, we don't bother converting * those to GSM. */static void convert_cimd2_to_gsm(Octstr *text){    long pos, len;    int cimd1, cimd2;    int c;    int i;    /* CIMD2 uses four single-character mappings that do not map     * to themselves:     * '@' from 64 to 0, '$' from 36 to 2, ']' from 93 to 14 (A-ring),     * and '}' from 125 to 15 (a-ring).     * Other than those, we only have to worry about the escape     * sequences introduced by _ (underscore).     */    len = octstr_len(text);    for (pos = 0; pos < len; pos++) {        c = octstr_get_char(text, pos);        if (c == '@')            octstr_set_char(text, pos, 0);        else if (c == '$')            octstr_set_char(text, pos, 2);        else if (c == ']')            octstr_set_char(text, pos, 14);        else if (c == '}')            octstr_set_char(text, pos, 15);        else if (c == '_' && pos + 2 < len) {            cimd1 = octstr_get_char(text, pos + 1);            cimd2 = octstr_get_char(text, pos + 2);            for (i = 0; cimd_combinations[i].cimd1 != 0; i++) {                if (cimd_combinations[i].cimd1 == cimd1 &&                    cimd_combinations[i].cimd2 == cimd2)                    break;            }            if (cimd_combinations[i].cimd1 == 0)                warning(0, "CIMD2: Encountered unknown "                        "escape code _%c%c, ignoring.",                        cimd1, cimd2);            else {                octstr_delete(text, pos, 2);                octstr_set_char(text, pos, cimd_combinations[i].gsm);                len = octstr_len(text);            }        }    }}/* Convert text in the GSM default character set to the CIMD2 User Data * format, which is a representation of the GSM default character set * in the lower 7 bits of ISO-8859-1.  (8-bit characters are also * allowed, but it's just as easy not to use them.) */static void convert_gsm_to_cimd2(Octstr *text){    long pos, len;    len = octstr_len(text);    for (pos = 0; pos < len; pos++) {        int c, i;        c = octstr_get_char(text, pos);        /* If c is not in the GSM alphabet at this point,         * the caller did something badly wrong. */        gw_assert(c >= 0);        gw_assert(c < 128);        for (i = 0; cimd_combinations[i].cimd1 != 0; i++) {            if (cimd_combinations[i].gsm == c)                break;        }        if (cimd_combinations[i].gsm == c) {            /* Escape sequence */            octstr_insert_data(text, pos, "_ ", 2);            pos += 2;            len += 2;            octstr_set_char(text, pos - 1, cimd_combinations[i].cimd1);            octstr_set_char(text, pos, cimd_combinations[i].cimd2);        } else if (c == 2) {            /* The dollar sign is the only GSM character that            	 * does not have a CIMD escape sequence and does not             * map to itself. */            octstr_set_char(text, pos, '$');        }    }}/***************************************************************************//* Packet encoding functions.  They do not allow the creation of invalid   *//* CIMD 2 packets.                                                         *//***************************************************************************//* Build a new packet struct with this operation code and sequence number. */static struct packet *packet_create(int operation, int seq){    struct packet *packet;    unsigned char minpacket[sizeof("sOO:SSSte")];    packet = gw_malloc(sizeof(*packet));    packet->operation = operation;    packet->seq = seq;    sprintf(minpacket, STX_str "%02d:%03d" TAB_str ETX_str, operation, seq);    packet->data = octstr_create(minpacket);    return packet;}/* Add a parameter to the end of packet */static void packet_add_parm(struct packet *packet, int parmtype,                            int parmno, Octstr *value){    unsigned char parmh[sizeof("tPPP:")];    long position;    long len;    int copied = 0;    len = octstr_len(value);    gw_assert(packet != NULL);    gw_assert(parm_type(parmno) == parmtype);    if (len > parm_maxlen(parmno)) {        warning(0, "CIMD2: %s parameter too long, truncating from "                "%ld to %ld characters", parm_name(parmno),                len, (long) parm_maxlen(parmno));        value = octstr_copy(value, 0, parm_maxlen(parmno));        copied = 1;    }    /* There's a TAB and ETX at the end; insert it before those.     * The new parameter will come with a new starting TAB. */    position = octstr_len(packet->data) - 2;    sprintf(parmh, TAB_str "%03d:", parmno);    octstr_insert_data(packet->data, position, parmh, strlen(parmh));    octstr_insert(packet->data, value, position + strlen(parmh));    if (copied)        octstr_destroy(value);}/* Add a String parameter to the packet */static void packet_add_string_parm(struct packet *packet, int parmno, Octstr *value){    packet_add_parm(packet, P_STRING, parmno, value);}/* Add an Address parameter to the packet */static void packet_add_address_parm(struct packet *packet, int parmno, Octstr *value){    gw_assert(octstr_check_range(value, 0, octstr_len(value), isphonedigit));    packet_add_parm(packet, P_ADDRESS, parmno, value);}/* Add an SMS parameter to the packet.  The caller is expected to have done * the translation to the GSM character set already.  */static void packet_add_sms_parm(struct packet *packet, int parmno, Octstr *value){    packet_add_parm(packet, P_SMS, parmno, value);}/* There is no function for adding a Time parameter to the packet, because * the format makes Time parameters useless for us.  If you find that you * need to use them, then also add code for querying the SMS center timestamp * and using that for synchronization.  And beware of DST changes. *//* Add a Hexadecimal parameter to the packet */static void packet_add_hex_parm(struct packet *packet, int parmno, Octstr *value){    value = octstr_duplicate(value);    octstr_binary_to_hex(value, 1);   /* 1 for uppercase hex, i.e. A .. F */    packet_add_parm(packet, P_HEX, parmno, value);    octstr_destroy(value);}/* Add an Integer parameter to the packet */static void packet_add_int_parm(struct packet *packet, int parmno, long value){    unsigned char buf[128];    Octstr *valuestr;    gw_assert(parm_in_range(parmno, value));    sprintf(buf, "%ld", value);    valuestr = octstr_create(buf);    packet_add_parm(packet, P_INT, parmno, valuestr);    octstr_destroy(valuestr);}static void packet_set_checksum(struct packet *packet){    Octstr *data;    int checksum;    long pos, len;    unsigned char buf[16];    gw_assert(packet != NULL);    data = packet->data;    if (octstr_get_char(data, octstr_len(data) - 2) != TAB) {        /* Packet already has checksum; kill it. */        octstr_delete(data, octstr_len(data) - 3, 2);    }    gw_assert(octstr_get_char(data, octstr_len(data) - 2) == TAB);    /* Sum all the way up to the last TAB */    checksum = 0;    for (pos = 0, len = octstr_len(data); pos < len - 1; pos++) {        checksum += octstr_get_char(data, pos);        checksum &= 0xff;    }    sprintf(buf, "%02X", checksum);    octstr_insert_data(data, len - 1, buf, 2);}static void packet_set_sequence(struct packet *packet, int seq){    unsigned char buf[16];    gw_assert(packet != NULL);    gw_assert(seq >= 0);    gw_assert(seq < 256);    sprintf(buf, "%03d", seq);    /* Start at 4 to skip the <STX> ZZ: part of the header. */    octstr_set_char(packet->data, 4, buf[0]);

⌨️ 快捷键说明

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