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 + -
显示快捷键?