diff --git a/include/libtcap.h b/include/libtcap.h index c55ae06..ee2d32f 100644 --- a/include/libtcap.h +++ b/include/libtcap.h @@ -4,10 +4,11 @@ #include "TCMessage.h" #include "Invoke.h" +#include "constr_TYPE.h" TCMessage_t *tcap_decode(const char *buf, size_t len); -void *inap_decode(Invoke_t *invoke); +void *inap_decode(Invoke_t *invoke, asn_TYPE_descriptor_t **); #endif diff --git a/src/tcap.c b/src/tcap.c index 417fd3c..5b05eca 100644 --- a/src/tcap.c +++ b/src/tcap.c @@ -13,11 +13,20 @@ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + #define INVOKE_OPCODE_INITIALDP 0 #define INVOKE_OPCODE_CONNECT 20 #define INVOKE_OPCODE_FURNISHCHARGINGINFORMATION 34 +static asn_TYPE_descriptor_t *opcode_type_map[] = { + [INVOKE_OPCODE_INITIALDP] = &asn_DEF_InitialDPArg, + [INVOKE_OPCODE_CONNECT] = &asn_DEF_ConnectArg, + [INVOKE_OPCODE_FURNISHCHARGINGINFORMATION] = &asn_DEF_FurnishChargingInformationArg, +}; + + TCMessage_t *tcap_decode(const char *buf, size_t len) { TCMessage_t *ret = NULL; @@ -32,12 +41,12 @@ TCMessage_t *tcap_decode(const char *buf, size_t len) { return NULL; } -void *inap_decode(Invoke_t *invoke) { +void *inap_decode(Invoke_t *invoke, asn_TYPE_descriptor_t **type) { long opcode; int rv; void *arg = 0; - if (!invoke || !invoke->parameter) + if (!invoke || !invoke->parameter || !type) goto nothing; if (invoke->opCode.present != OPERATION_PR_localValue) @@ -46,28 +55,20 @@ void *inap_decode(Invoke_t *invoke) { if (asn_INTEGER2long(&invoke->opCode.choice.localValue, &opcode)) goto nothing; - switch (opcode) { - case INVOKE_OPCODE_INITIALDP: - rv = ANY_to_type(invoke->parameter, &asn_DEF_InitialDPArg, &arg); - break; - - case INVOKE_OPCODE_CONNECT: - rv = ANY_to_type(invoke->parameter, &asn_DEF_ConnectArg, &arg); - break; + if (opcode >= ARRAY_SIZE(opcode_type_map)) + goto nothing; - case INVOKE_OPCODE_FURNISHCHARGINGINFORMATION: - rv = ANY_to_type(invoke->parameter, &asn_DEF_FurnishChargingInformationArg, &arg); - break; + *type = opcode_type_map[opcode]; - default: - goto nothing; - } + rv = ANY_to_type(invoke->parameter, *type, &arg); if (!rv) return arg; - /* free struct */ + if (arg) + (*type)->free_struct(*type, arg, 0); nothing: + *type = NULL; return NULL; } diff --git a/tests/basic.c b/tests/basic.c index 6f017f0..868fdff 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -15,6 +15,7 @@ int main() { Component_t *component; int i; void *arg; + asn_TYPE_descriptor_t *type; tcm = tcap_decode(tcap, tcap_len); @@ -65,8 +66,8 @@ int main() { case Component_PR_invoke: printf("invoke\n"); - arg = inap_decode(&component->choice.invoke); - printf("arg: %p\n", arg); + arg = inap_decode(&component->choice.invoke, &type); + printf("arg: type %s -> %p\n", type ? type->name : "n/a", arg); break; case Component_PR_returnResultLast: