diff --git a/src/modules/ims_diameter_server/avp_helper.c b/src/modules/ims_diameter_server/avp_helper.c index 3cd878f7d23..9f6b67cf2eb 100644 --- a/src/modules/ims_diameter_server/avp_helper.c +++ b/src/modules/ims_diameter_server/avp_helper.c @@ -42,6 +42,7 @@ #include "../../core/basex.h" #define STRSIZE 8*1024 +#define HEXDUMP "hexdump" // ID of current message static unsigned int current_msg_id = 0; @@ -109,7 +110,7 @@ cJSON * avp2json(AAA_AVP *avp_t) { case AAA_AVP_DATA_TYPE: l = 0; for (i=0; i < avp_t->data.len; i++) { - l+=snprintf(dest+l,STRSIZE-l-1,"%x", ((unsigned char*)avp_t->data.s)[i]); + l+=snprintf(dest+l,STRSIZE-l-1,"%02x", ((unsigned char*)avp_t->data.s)[i]); } cJSON_AddStringToObject(avp, "data", dest); if (avp_t->data.len == 4) { @@ -250,6 +251,34 @@ int diameterserver_add_avp_list(AAA_AVP_LIST *list, char *d, int len, int avp_co return 1; } +unsigned int parse_hex_half_digit(const char * str) { + if (*str>='0' && *str<='9') { + return (*str)-'0'; + } else if (*str>='A' && *str<='F') { + return 10+(*str)-'A'; + } else if (*str>='a' && *str<='f') { + return 10+(*str)-'a'; + } + return 0; + +} + +char* parse_hexdump(const char * hexdump) { + const char *src = hexdump; + char *hexdump_copy = strdup(hexdump); + unsigned char *dst = (unsigned char*)hexdump_copy; + while (*src) { + unsigned h=parse_hex_half_digit(src++); + h=h<<4; + if (!*src) { + return hexdump_copy; + } + h+=parse_hex_half_digit(src++); + *dst++ = (unsigned char) h; + } + return hexdump_copy; +} + void parselist(AAAMessage *response, AAA_AVP_LIST *list, cJSON * item, int level) { int flags; char x[4]; @@ -274,13 +303,16 @@ void parselist(AAAMessage *response, AAA_AVP_LIST *list, cJSON * item, int level if (cJSON_GetObjectItem(item,"string")) { LM_DBG("%i) String: %s\n", level, cJSON_GetObjectItem(item,"string")->valuestring); } + if (cJSON_GetObjectItem(item,HEXDUMP)) { + LM_DBG("%i) String: %s\n", level, cJSON_GetObjectItem(item,HEXDUMP)->valuestring); + } if (cJSON_GetObjectItem(item,"int32")) { LM_DBG("%i) Integer: %i\n", level, cJSON_GetObjectItem(item,"int32")->valueint); } if (!cJSON_GetObjectItem(item,"avpCode")) { LM_WARN("mandatory field missing: avpCode\n"); - return; + return; } if (!cJSON_GetObjectItem(item,"vendorId")) { LM_WARN("mandatory field missing: vendorId (avpCode %i)\n", cJSON_GetObjectItem(item,"avpCode")->valueint); @@ -327,8 +359,20 @@ void parselist(AAAMessage *response, AAA_AVP_LIST *list, cJSON * item, int level strlen(cJSON_GetObjectItem(item,"string")->valuestring), cJSON_GetObjectItem(item,"avpCode")->valueint, flags, cJSON_GetObjectItem(item,"vendorId")->valueint, AVP_DUPLICATE_DATA, __FUNCTION__); } + } else if (cJSON_GetObjectItem(item,HEXDUMP)) { + char * binary_form = parse_hexdump(cJSON_GetObjectItem(item,HEXDUMP)->valuestring); + if (list) { + diameterserver_add_avp_list(list, binary_form, + strlen(cJSON_GetObjectItem(item,HEXDUMP)->valuestring) / 2, cJSON_GetObjectItem(item,"avpCode")->valueint, flags, + cJSON_GetObjectItem(item,"vendorId")->valueint, AVP_DUPLICATE_DATA, __FUNCTION__); + } else { + diameterserver_add_avp(response, binary_form, + strlen(cJSON_GetObjectItem(item,HEXDUMP)->valuestring) / 2, cJSON_GetObjectItem(item,"avpCode")->valueint, flags, + cJSON_GetObjectItem(item,"vendorId")->valueint, AVP_DUPLICATE_DATA, __FUNCTION__); + } + free(binary_form); } else { - LM_WARN("Not a string, int32, list? Invalid field definition... (%i:%i)\n", + LM_WARN("Not a string, int32, list, hexdump? Invalid field definition... (%i:%i)\n", cJSON_GetObjectItem(item,"avpCode")->valueint, cJSON_GetObjectItem(item,"vendorId")->valueint); } }