diff --git a/include/libtcap.h b/include/libtcap.h index 1e1313a..c55ae06 100644 --- a/include/libtcap.h +++ b/include/libtcap.h @@ -3,9 +3,11 @@ #include "TCMessage.h" +#include "Invoke.h" TCMessage_t *tcap_decode(const char *buf, size_t len); +void *inap_decode(Invoke_t *invoke); #endif diff --git a/src/tcap.c b/src/tcap.c index 45ef2ab..417fd3c 100644 --- a/src/tcap.c +++ b/src/tcap.c @@ -5,10 +5,20 @@ #include #include "TCMessage.h" +#include "Invoke.h" +#include "InitialDPArg.h" +#include "ConnectArg.h" +#include "FurnishChargingInformationArg.h" +#define INVOKE_OPCODE_INITIALDP 0 +#define INVOKE_OPCODE_CONNECT 20 +#define INVOKE_OPCODE_FURNISHCHARGINGINFORMATION 34 + + + TCMessage_t *tcap_decode(const char *buf, size_t len) { TCMessage_t *ret = NULL; asn_dec_rval_t rv; @@ -21,3 +31,43 @@ TCMessage_t *tcap_decode(const char *buf, size_t len) { asn_DEF_TCMessage.free_struct(&asn_DEF_TCMessage, ret, 0); return NULL; } + +void *inap_decode(Invoke_t *invoke) { + long opcode; + int rv; + void *arg = 0; + + if (!invoke || !invoke->parameter) + goto nothing; + + if (invoke->opCode.present != OPERATION_PR_localValue) + goto nothing; + + 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; + + case INVOKE_OPCODE_FURNISHCHARGINGINFORMATION: + rv = ANY_to_type(invoke->parameter, &asn_DEF_FurnishChargingInformationArg, &arg); + break; + + default: + goto nothing; + } + + if (!rv) + return arg; + + /* free struct */ + +nothing: + return NULL; +} diff --git a/tests/basic.c b/tests/basic.c index 030c753..6f017f0 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,5 +1,9 @@ #include #include "libtcap.h" +#include "ComponentPortion.h" +#include "Component.h" + + const char tcap[] = "\x64\x81\x86\x49\x03\x0a\x7e\x71\x6b\x2a\x28\x28\x06\x07\x00\x11\x86\x05\x01\x01\x01\xa0\x1d\x61\x1b\xa1\x0d\x06\x0b\x2a\x81\x76\x82\x15\x01\x01\x01\x01\x00\x01\xa2\x03\x02\x01\x00\xa3\x05\xa1\x03\x02\x01\x00\x6c\x53\xa1\x10\x02\x01\x58\x02\x01\x22\xbf\x33\x07\x83\x05\x31\x30\x30\x32\x34\xa1\x3f\x02\x01\x59\x02\x01\x14\x30\x37\xa0\x0e\x04\x0c\x83\x90\x89\x10\x10\x80\x22\x08\x00\x55\x50\x05\x83\x01\x09\x9a\x22\x30\x20\xa0\x1e\x80\x01\x00\x81\x01\x00\x82\x01\x01\x83\x01\x01\x84\x01\x00\x85\x01\x00\x86\x01\x01\x87\x01\x01\x88\x01\x00\x89\x01\x00"; const int tcap_len = sizeof(tcap) - 1; @@ -7,10 +11,82 @@ const int tcap_len = sizeof(tcap) - 1; int main() { TCMessage_t *tcm; + ComponentPortion_t *components = 0; + Component_t *component; + int i; + void *arg; tcm = tcap_decode(tcap, tcap_len); - printf("%p\n", tcm); + printf("TCMessage: %p\n", tcm); + + switch (tcm->present) { + case TCMessage_PR_NOTHING: + printf("nothing\n"); + break; + + case TCMessage_PR_unidirectional: + printf("unidirectional\n"); + components = &tcm->choice.unidirectional.components; + break; + + case TCMessage_PR_begin: + printf("begin\n"); + components = tcm->choice.begin.components; + break; + + case TCMessage_PR_end: + printf("end\n"); + components = tcm->choice.end.components; + break; + + case TCMessage_PR_continue: + printf("continue\n"); + components = tcm->choice.Continue.components; + break; + + case TCMessage_PR_abort: + printf("abort\n"); + break; + } + + if (components) { + printf("%i components\n", components->list.count); + + for (i = 0; i < components->list.count; i++) { + printf("Component #%i\n", i); + + component = components->list.array[i]; + + switch (component->present) { + case Component_PR_NOTHING: + printf("nothing\n"); + break; + + case Component_PR_invoke: + printf("invoke\n"); + arg = inap_decode(&component->choice.invoke); + printf("arg: %p\n", arg); + break; + + case Component_PR_returnResultLast: + printf("returnResultLast\n"); + break; + + case Component_PR_returnError: + printf("returnError\n"); + break; + + case Component_PR_reject: + printf("reject\n"); + break; + + case Component_PR_returnResultNotLast: + printf("returnResultNotLast\n"); + break; + } + } + } return 0; }