From e514e9a78931273e30eba01fbb5d0f8e4be033c1 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 22 Jun 2016 10:53:54 -0400 Subject: [PATCH] MT#20617 support BER/DER encoding Change-Id: Ic72b3817b3d2a1780493e6ee0fc964ea35029b9e --- include/libtcap.h | 2 ++ src/tcap.c | 32 ++++++++++++++++++++++++++ tests/.gitignore | 1 + tests/Makefile | 7 ++++-- tests/basic.c | 22 +++++++++++------- tests/encode.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 tests/encode.c diff --git a/include/libtcap.h b/include/libtcap.h index 1ab435b..93760e8 100644 --- a/include/libtcap.h +++ b/include/libtcap.h @@ -28,5 +28,7 @@ int inap_extract(const char *buf, size_t len, const char *spec, struct output_bu int isup_convert_number(const char *inp, int inlen, char *out); int isup_convert_number_hex(const char *inp, int inlen, char *out); +int tcap_encode(char **out, TCMessage_t *msg); + #endif diff --git a/src/tcap.c b/src/tcap.c index 5b32c5a..33b9201 100644 --- a/src/tcap.c +++ b/src/tcap.c @@ -36,6 +36,38 @@ static asn_TYPE_descriptor_t *opcode_type_map[] = { +static int buf_append(const void *buffer, size_t size, void *app_key) { + FILE *fp = app_key; + size_t ret; + + if (!buffer || !size) + return 0; + //fprintf(stderr, "writing %p %lu\n", buffer, size); + ret = fwrite(buffer, size, 1, fp); + return (ret == 1) ? 0 : -1; +} + +int tcap_encode(char **out, TCMessage_t *msg) { + FILE *fp; + char *str; + size_t len; + asn_enc_rval_t ec; + + fp = open_memstream(&str, &len); + if (!fp) + return -1; + + ec = der_encode(&asn_DEF_TCMessage, msg, buf_append, fp); + + fclose(fp); + + if (ec.encoded == -1) + return -1; + + *out = str; + return len; +} + TCMessage_t *tcap_decode(const char *buf, size_t len) { TCMessage_t *ret = NULL; asn_dec_rval_t rv; diff --git a/tests/.gitignore b/tests/.gitignore index cada14c..30d4e69 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,2 +1,3 @@ *.sw? basic +encode diff --git a/tests/Makefile b/tests/Makefile index 388c6a6..680124d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,9 +1,12 @@ .PHONY: all clean -all: basic +all: basic encode basic: basic.c ../src/libtcap.so.0 gcc -Wall -g -I ../include -I../asn1-compiled basic.c -o basic -L../src -ltcap +encode: encode.c ../src/libtcap.so.0 + gcc -Wall -g -I ../include -I../asn1-compiled encode.c -o encode -L../src -ltcap + clean: - rm -f basic + rm -f basic encode diff --git a/tests/basic.c b/tests/basic.c index 5ea4a62..7624a6e 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -6,8 +6,14 @@ //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 char tcap[] = "\x62\x51\x48\x03\x0a\x7e\x71\x6b\x22\x28\x20\x06\x07\x00\x11\x86\x05\x01\x01\x01\xa0\x15\x60\x13\x80\x02\x07\x80\xa1\x0d\x06\x0b\x2a\x81\x76\x82\x15\x01\x01\x01\x01\x00\x01\x6c\x26\xa1\x24\x02\x01\x01\x02\x01\x00\x30\x1c\x80\x01\x02\x82\x07\x03\x90\x08\x00\x55\x50\xf5\x83\x07\x83\x13\x17\x45\x64\x86\x08\x85\x01\x0a\x9a\x02\x20\x01"; -const int tcap_len = sizeof(tcap) - 1; +//const char tcap[] = "\x62\x51\x48\x03\x0a\x7e\x71\x6b\x22\x28\x20\x06\x07\x00\x11\x86\x05\x01\x01\x01\xa0\x15\x60\x13\x80\x02\x07\x80\xa1\x0d\x06\x0b\x2a\x81\x76\x82\x15\x01\x01\x01\x01\x00\x01\x6c\x26\xa1\x24\x02\x01\x01\x02\x01\x00\x30\x1c\x80\x01\x02\x82\x07\x03\x90\x08\x00\x55\x50\xf5\x83\x07\x83\x13\x17\x45\x64\x86\x08\x85\x01\x0a\x9a\x02\x20\x01"; +const char tcap[] = { + 0x62, 0x1c, 0x48, 0x00, 0x6c, 0x18, 0xa1, 0x16, 0x02, 0x01, 0x00, 0x02, + 0x01, 0x14, 0x30, 0x0e, 0xa0, 0x0c, 0x04, 0x0a, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 +}; +//const int tcap_len = sizeof(tcap) - 1; +const int tcap_len = sizeof(tcap); int main() { @@ -31,13 +37,13 @@ int main() { // i = inap_extract(tcap, tcap_len, "ConnectArg.destinationRoutingAddress", &out); // printf("inap_extract ConnectArg.destinationRoutingAddress: returned %i, value %.*s\n", i, (int) out.used, out.buf); // -// OUTPUT_BUFFER_INIT(&out, buf); -// i = inap_extract(tcap, tcap_len, "ConnectArg.destinationRoutingAddress.0", &out); -// printf("inap_extract ConnectArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); - OUTPUT_BUFFER_INIT(&out, buf); - i = inap_extract(tcap, tcap_len, "InitialDPArg.calledPartyNumber", &out); - printf("inap_extract InitialDPArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); + i = inap_extract(tcap, tcap_len, "ConnectArg.destinationRoutingAddress.0", &out); + printf("inap_extract ConnectArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); + +// OUTPUT_BUFFER_INIT(&out, buf); +// i = inap_extract(tcap, tcap_len, "InitialDPArg.calledPartyNumber", &out); +// printf("inap_extract InitialDPArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); return 0; } diff --git a/tests/encode.c b/tests/encode.c new file mode 100644 index 0000000..6dd5715 --- /dev/null +++ b/tests/encode.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "libtcap.h" +#include "TCMessage.h" +#include "ComponentPortion.h" +#include "Component.h" +#include "ConnectArg.h" +#include "CalledPartyNumber.h" + +int main() { + char *buf; + int ret; + TCMessage_t msg; + ComponentPortion_t cp; + Component_t *cmp_arr; + Component_t cmp; + ConnectArg_t ca; + CalledPartyNumber_t *cpn_arr; + CalledPartyNumber_t cpn; + + memset(&msg, 0, sizeof(msg)); + memset(&cp, 0, sizeof(cp)); + memset(&cmp, 0, sizeof(cmp)); + memset(&ca, 0, sizeof(ca)); + memset(&cpn, 0, sizeof(cpn)); + + msg.present = TCMessage_PR_begin; + msg.choice.begin.components = &cp; + + cp.list.count = 1; + cmp_arr = &cmp; + cp.list.array = &cmp_arr; + + cmp.present = Component_PR_invoke; + cmp.choice.invoke.opCode.present = OPERATION_PR_localValue; + asn_long2INTEGER(&cmp.choice.invoke.opCode.choice.localValue, 20); // connect + + ca.destinationRoutingAddress.list.count = 1; + cpn_arr = &cpn; + ca.destinationRoutingAddress.list.array = &cpn_arr; + + cpn.buf = "1234567890"; + cpn.size = 10; + + cmp.choice.invoke.parameter = ANY_new_fromType(&asn_DEF_ConnectArg, &ca); + + ret = tcap_encode(&buf, &msg); + fprintf(stderr, "ret: %i\n", ret); + fwrite(buf, ret, 1, stdout); + + free(buf); + asn_DEF_ANY.free_struct(&asn_DEF_ANY, cmp.choice.invoke.parameter, 0); + asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &cmp.choice.invoke.opCode.choice.localValue, 0); + + return 0; +}