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

📄 smpp_pdu.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
字号:
/* * smpp_pdu.c - parse and generate SMPP PDUs * * Lars Wirzenius */#include <string.h>#include "smpp_pdu.h"#define MIN_SMPP_PDU_LEN    (4*4)#define MAX_SMPP_PDU_LEN    (1024)static unsigned long decode_integer(Octstr *os, long pos, int octets){    unsigned long u;    int i;        gw_assert(octstr_len(os) >= pos + octets);    u = 0;    for (i = 0; i < octets; ++i)    	u = (u << 8) | octstr_get_char(os, pos + i);    return u;}static void append_encoded_integer(Octstr *os, unsigned long u, long octets){    long i;    for (i = 0; i < octets; ++i)    	octstr_append_char(os, (u >> ((octets - i - 1) * 8)) & 0xFF);}static Octstr *copy_until_nul(Octstr *os, long *pos, long max_octets){    long nul;    Octstr *data;    nul = octstr_search_char(os, '\0', *pos);    if (nul == -1) {	warning(0, "SMPP: PDU NUL terminated string has no NUL.");    	return NULL;    }    if (*pos + max_octets < nul) {	error(0, "SMPP: PDU NUL terminated string longer than allowed.");    	return NULL;    }    data = (nul - *pos > 0) ? octstr_copy(os, *pos, nul - *pos) : NULL;    *pos = nul + 1;    return data;}SMPP_PDU *smpp_pdu_create(unsigned long type, unsigned long seq_no){    SMPP_PDU *pdu;        pdu = gw_malloc(sizeof(*pdu));    pdu->type = type;        switch (type) {    #define INTEGER(name, octets) \   	if (strcmp(#name, "command_id") == 0) p->name = type; \    	else if (strcmp(#name, "sequence_number") == 0) p->name = seq_no; \    	else p->name = 0;    #define NULTERMINATED(name, max_octets) p->name = NULL;    #define OCTETS(name, field_giving_octetst) p->name = NULL;    #define PDU(name, id, fields) \    	case id: { \	    struct name *p = &pdu->u.name; \	    pdu->type_name = #name; \	    fields \	} break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error.");    	gw_free(pdu);	return NULL;    }        return pdu;}void smpp_pdu_destroy(SMPP_PDU *pdu){    if (pdu == NULL)    	return;    switch (pdu->type) {    #define INTEGER(name, octets) p->name = 0; /* Make sure "p" is used */    #define NULTERMINATED(name, max_octets) octstr_destroy(p->name);    #define OCTETS(name, field_giving_octets) octstr_destroy(p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while destroying.");    }    gw_free(pdu);}Octstr *smpp_pdu_pack(SMPP_PDU *pdu){    Octstr *os;    Octstr *temp;        os = octstr_create("");    /*     * Fix lengths of octet string fields.     */    switch (pdu->type) {    #define INTEGER(name, octets) p = *(&p);    #define NULTERMINATED(name, max_octets) p = *(&p);    #define OCTETS(name, field_giving_octets) \    	p->field_giving_octets = octstr_len(p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while packing.");    }    switch (pdu->type) {    #define INTEGER(name, octets) \    	append_encoded_integer(os, p->name, octets);    #define NULTERMINATED(name, max_octets) \        if (p->name != NULL) { \            if (octstr_len(p->name) >= max_octets) { \                warning(0, "SMPP: PDU element <%s> to long " \                        "(length is %ld, should be %d)", \                        #name, octstr_len(p->name), max_octets); \                temp = octstr_copy(p->name, 0, max_octets-1); \            } else \                temp = octstr_duplicate(p->name); \            octstr_append(os, temp); \            octstr_destroy(temp); \        } \        octstr_append_char(os, '\0');    #define OCTETS(name, field_giving_octets) \    	octstr_append(os, p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while packing.");    }    temp = octstr_create("");    append_encoded_integer(temp, octstr_len(os) + 4, 4);    octstr_insert(os, temp, 0);    octstr_destroy(temp);    return os;}SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len){    SMPP_PDU *pdu;    unsigned long type;    long pos;        if (octstr_len(data_without_len) < 4) {	error(0, "SMPP: PDU was too short (%ld bytes).", 	      octstr_len(data_without_len));	return NULL;    }    type = decode_integer(data_without_len, 0, 4);    pdu = smpp_pdu_create(type, 0);    if (pdu == NULL)    	return NULL;        pos = 0;    switch (type) {    #define INTEGER(name, octets) \    	p->name = decode_integer(data_without_len, pos, octets); \	pos += octets;    #define NULTERMINATED(name, max_octets) \    	p->name = copy_until_nul(data_without_len, &pos, max_octets);    #define OCTETS(name, field_giving_octets) \    	p->name = octstr_copy(data_without_len, pos, \	    	    	      p->field_giving_octets); \    	gw_assert(p->field_giving_octets == \	    	  (unsigned long) octstr_len(p->name)); \	pos += p->field_giving_octets;    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while unpacking.");    }    return pdu;}void smpp_pdu_dump(SMPP_PDU *pdu){    debug("sms.smpp", 0, "SMPP PDU %p dump:", (void *) pdu);    debug("sms.smpp", 0, "  type_name: %s", pdu->type_name);    switch (pdu->type) {    #define INTEGER(name, octets) \    	debug("sms.smpp", 0, "  %s: %lu = 0x%08lx", #name, p->name, p->name);    #define NULTERMINATED(name, max_octets) \	octstr_dump_short(p->name, 2, #name);    #define OCTETS(name, field_giving_octets) \        octstr_dump_short(p->name, 2, #name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error.");	break;    }    debug("sms.smpp", 0, "SMPP PDU dump ends.");}long smpp_pdu_read_len(Connection *conn){    Octstr *os;    char buf[4];    /* The length is 4 octets. */    long len;        os = conn_read_fixed(conn, sizeof(buf));    if (os == NULL)    	return 0;    octstr_get_many_chars(buf, os, 0, sizeof(buf));    octstr_destroy(os);    len = decode_network_long(buf);    if (len < MIN_SMPP_PDU_LEN) {	error(0, "SMPP: PDU length was too small (%ld, minimum is %ld).",	      len, (long) MIN_SMPP_PDU_LEN);    	return -1;    }    if (len > MAX_SMPP_PDU_LEN) {	error(0, "SMPP: PDU length was too large (%ld, maximum is %ld).",	      len, (long) MIN_SMPP_PDU_LEN);    	return -1;    }    return len;}Octstr *smpp_pdu_read_data(Connection *conn, long len){    Octstr *os;        os = conn_read_fixed(conn, len - 4);    /* `len' includes itself. */    return os;}

⌨️ 快捷键说明

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