mms_pdu.c

来自「mms client」· C语言 代码 · 共 566 行 · 第 1/2 页

C
566
字号
/* mms_pdu.c - pack and unpack MMS packets * * Generates packing and unpacking code from mms_pdu.def. * Code is very similar to mms_pdu.c, please make any changes in both files. * * Richard Braakman */#include "gwlib/gwlib.h"#include "mms_pdu.h"#include "wap/wsp_headers.h"#include "wap/wsp_strings.h"#define WSP_QUOTE  127MMS_PDU *mms_pdu_create(int type) {	MMS_PDU *pdu;		pdu = gw_malloc(sizeof(*pdu));	pdu->type = type;	switch (pdu->type) {#define PDU(name, pdutype, docstring, fields, is_valid) \	case name: {\	struct name *p; p = &pdu->u.name; \	fields \	} break;#define UINT(field, fieldnr, docstring) p->field = 0;#define MMSVERSION(field, fieldnr, docstring) p->field = NULL;#define OCTSTR(field, fieldnr, docstring) p->field = NULL;#define OCTSTRE(field, fieldnr, docstring) p->field = NULL;#define ULONG(field, fieldnr, docstring) p->field = -1;#define ULONGABSREL(field, fieldnr, docstring) p->field = -1;#define ENCSTRVAL(field, fieldnr, docstring) p->field = NULL; p->field ## _charset = (unsigned long)128;#define ENCSTRVALE(field, fieldnr, docstring) p->field = NULL; p->field ## _charset = (unsigned long)128;#define REST(field, docstring) p->field = NULL;#include "mms_pdu.def"#undef REST#undef ENCSTRVAL#undef ENCSTRVALE#undef ULONG#undef ULONGABSREL#undef OCTSTR#undef OCTSTRE#undef MMSVERSION#undef UINT#undef PDU	default:		panic(0, "Internal error: Unknown PDU type %d", pdu->type);		break;	}	return pdu;}void mms_pdu_destroy(MMS_PDU *pdu) {	if (pdu == NULL)		return;	switch (pdu->type) {#define PDU(name, pdutype, docstring, fields, is_valid) \	case name: {\	struct name *p; p = &pdu->u.name; \	fields \	} break;#define UINT(field, fieldnr, docstring)#define MMSVERSION(field, fieldnr, docstring) octstr_destroy(p->field);#define OCTSTR(field, fieldnr, docstring) octstr_destroy(p->field);#define OCTSTRE(field, fieldnr, docstring) octstr_destroy(p->field);#define ULONG(field, fieldnr, docstring)#define ULONGABSREL(field, fieldnr, docstring)#define ENCSTRVAL(field, fieldnr, docstring) octstr_destroy(p->field);#define ENCSTRVALE(field, fieldnr, docstring) octstr_destroy(p->field);#define REST(field, docstring) octstr_destroy(p->field);#include "mms_pdu.def"#undef REST#undef ENCSTRVAL#undef ENCSTRVALE#undef ULONG#undef ULONGABSREL#undef OCTSTR#undef OCTSTRE#undef MMSVERSION#undef UINT#undef PDU	default:		panic(0, "Cannot destroy unknown MMS PDU type %d", pdu->type);		break;	}	gw_free(pdu);}void mms_pdu_destroy_item(void *pdu) {	mms_pdu_destroy(pdu);}/* Determine which type of PDU this is, using the TYPE macros in * the definition file. */static int mms_pdu_type(Octstr *data) {    /* first octet should be */    return octstr_get_char(data, 1);}unsigned long unpack_integer_val(ParseContext *context) {    unsigned long value;    int val;    val = parse_get_char(context);    if (val < 31) {        value = unpack_multi_octet_integer(context, val);    } else if (val > 127) {        value = val - 128;    } else {        warning(0, "WSP headers: bad integer-value.");        return -1;    }    return value;}unsigned long unpack_value_length(ParseContext *context) {    int len;    len = parse_get_char(context);    if (len > 30)         /* followed by uintvar */        return parse_get_uintvar(context);    else        return (unsigned long) len;}unsigned long parse_get_absoluterelative(ParseContext *context, int *absrelindication) {    unsigned long len;    len = unpack_value_length(context);    *absrelindication = parse_get_char(context);    return parse_get_long_integer(context);}Octstr *unpack_nul_string(ParseContext *context) {    Octstr *result = parse_get_nul_string(context);    if (result && octstr_get_char(result, 0) == WSP_QUOTE)        octstr_delete(result, 0, 1);    return result;}Octstr *unpack_encoded_string(ParseContext *context, unsigned long *charset) {    Octstr *result;    int c;    unsigned long len;        *charset = (unsigned long) 128;    c = parse_peek_char(context);    if (c < 32) {        len = unpack_value_length(context);        /* I think the charset is encoded as an integer value,           see WSP 8.4.2.8 */        c = parse_peek_char(context);        if (c == 128)             *charset = (unsigned long)parse_get_char(context);        else             *charset = unpack_integer_val(context);        /* still a null terminated string! won't need length then */        return unpack_nul_string(context);    }    else        /* text string */        return unpack_nul_string(context); }/* some MMS pdu's have a very specific coding */Octstr *e_unpack_from(ParseContext *context, unsigned long *charset) {    unpack_value_length(context);    if (parse_get_char(context) == MMS_TRUE_TOKEN) {        return unpack_encoded_string(context, charset);     }}Octstr *e_unpack_content_type(ParseContext *context) {    int val, ret;    unsigned char *ch = NULL;    Octstr *decoded = NULL;        ret = field_value(context, &val);    if (ret == WSP_FIELD_VALUE_NUL_STRING) {        decoded = parse_get_nul_string(context);    } else if (ret == WSP_FIELD_VALUE_ENCODED) {        ch = wsp_content_type_to_cstr(val);    } else if (ret == WSP_FIELD_VALUE_DATA) {        /* Content-general-form and Accept-general-form         * are defined separately in WSP, but their         * definitions are equivalent. */        decoded = unpack_accept_general_form(context);    }    parse_skip_to_limit(context);    parse_pop_limit(context);    if (ch == NULL && decoded != NULL)        ch = octstr_get_cstr(decoded);        octstr_destroy(decoded);    return octstr_create(ch);}MMS_PDU *mms_pdu_unpack(Octstr *data) {	MMS_PDU *pdu = NULL;    int type;    ParseContext *context;    int mms_field_name = 0;	gw_assert(data != NULL);    context = parse_context_create(data);	mms_field_name = unpack_integer_val(context);    if (mms_field_name != 12) {		warning(0, "MMS PDU does not start with field name");        parse_context_destroy(context);		return NULL;    }    type = parse_get_char(context);    pdu = mms_pdu_create(type);    /* do the headers first */	switch (pdu->type) {#define PDU(name, pdutype, docstring, fields, is_valid) \	case pdutype: { \		struct name *p = &pdu->u.name; \        while (parse_octets_left(context) > 0) { \            if ( mms_field_name == 4) \                mms_field_name = 0; /* the last header was the content type, now data expected */ \            else \                mms_field_name = unpack_integer_val(context); \            switch (mms_field_name) { \                fields \                default: \                /* some warning */ \            } \        } \	} break;#define UINT(field, fieldnr, docstring) \                case fieldnr: \                    p->field = parse_get_char(context); \                    break;#define MMSVERSION(field, fieldnr, docstring) \                case fieldnr: \                    p->field = unpack_version_value(parse_get_char(context) - 128); \                    break;#define ULONG(field, fieldnr, docstring) \                case fieldnr: \                    p->field = parse_get_long_integer(context); \                    break;#define ULONGABSREL(field, fieldnr, docstring) \                case fieldnr: \                    p->field = parse_get_absoluterelative(context, &p->field ## _absrelind); \                    break;#define ENCSTRVAL(field, fieldnr, docstring) \                case fieldnr: \                    p->field = unpack_encoded_string(context, &p->field ## _charset); \                    break;#define ENCSTRVALE(field, fieldnr, docstring) \                case fieldnr: \                    p->field = e_unpack_ ## field(context, &p->field ## _charset); \                    break;#define OCTSTR(field, fieldnr, docstring) \                case fieldnr: \

⌨️ 快捷键说明

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