diff --git a/src/Makefile.am b/src/Makefile.am index fa86556..ab77375 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,9 +10,10 @@ lib_LTLIBRARIES = libosmo-rspro.la libosmo_rspro_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(RSPRO_LIBVERSION) libosmo_rspro_la_LIBADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \ rspro/libosmo-asn1-rspro.la -libosmo_rspro_la_SOURCES = rspro_util.c +libosmo_rspro_la_SOURCES = rspro_util.c asn1c_helpers.c noinst_HEADERS = debug.h bankd.h client.h internal.h rspro_util.h slotmap.h rspro_client_fsm.h \ + asn1c_helpers.h \ simtrace2/apdu_dispatch.h \ simtrace2/libusb_util.h \ simtrace2/simtrace2-discovery.h \ diff --git a/src/asn1c_helpers.c b/src/asn1c_helpers.c new file mode 100644 index 0000000..ea3f5a6 --- /dev/null +++ b/src/asn1c_helpers.c @@ -0,0 +1,57 @@ +#include + +#include +#include +#include +#include + +#include "asn1c_helpers.h" + +const char *asn_type_name(const asn_TYPE_descriptor_t *td) +{ + return td->name; +} + +static int +_fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) { + const void *present_ptr; + int present; + + present_ptr = ((const char *)struct_ptr) + pres_offset; + + switch(pres_size) { + case sizeof(int): present = *(const int *)present_ptr; break; + case sizeof(short): present = *(const short *)present_ptr; break; + case sizeof(char): present = *(const char *)present_ptr; break; + default: + /* ANSI C mandates enum to be equivalent to integer */ + assert(pres_size != sizeof(int)); + return 0; /* If not aborted, pass back safe value */ + } + + return present; +} + +const char *asn_choice_name(const asn_TYPE_descriptor_t *td, const void *sptr) +{ + const asn_CHOICE_specifics_t *cspec = td->specifics; + int present = _fetch_present_idx(sptr, cspec->pres_offset, cspec->pres_size); + const asn_TYPE_member_t *elm; + + if (present < 0 || present >= td->elements_count) + return ""; + + elm = &td->elements[present-1]; + return elm->name; +} + +const char *asn_enum_name(const asn_TYPE_descriptor_t *td, int data) +{ + const asn_INTEGER_specifics_t *ispec = td->specifics; + + if (data < 0 || data >= ispec->map_count) + return ""; + + return ispec->value2enum[data].enum_name; + +} diff --git a/src/asn1c_helpers.h b/src/asn1c_helpers.h new file mode 100644 index 0000000..8d4e676 --- /dev/null +++ b/src/asn1c_helpers.h @@ -0,0 +1,7 @@ +#pragma once + +struct asn_TYPE_descriptor_t; + +const char *asn_type_name(const asn_TYPE_descriptor_t *td); +const char *asn_choice_name(const asn_TYPE_descriptor_t *td, const void *sptr); +const char *asn_enum_name(const asn_TYPE_descriptor_t *td, int data);