initial checkin of osmo-remsim

This adds some initial code, particularly the ASN.1 definition of the
RSPRO protocol, related makefile to build it using ffasn1c, and our
usual autoconf infrastructure to build it.

Change-Id: Ibaa993b59e9a65a0242b0f42b27d9cd29f8e1878
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..05ac9ae
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,10 @@
+SUBDIRS = rspro
+
+AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_builddir)/include \
+	    $(OSMOCORE_CFLAGS) $(ASN1C_CFLAGS)
+
+RSPRO_LIBVERSION=0:0:0
+lib_LTLIBRARIES = libosmo-rspro.la
+libosmo_rspro_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(RSPRO_LIBVERSION)
+libosmo_rspro_la_LIBADD = $(OSMOCORE_LIBS) $(ASN1C_LIBS) rspro/libosmo-asn1-rspro.la
+libosmo_rspro_la_SOURCES = rspro_util.c
diff --git a/src/driver_core.c b/src/driver_core.c
new file mode 100644
index 0000000..dbdf23f
--- /dev/null
+++ b/src/driver_core.c
@@ -0,0 +1,84 @@
+/*! \file reader_pcsc.c
+ * Card reader driver core */
+/*
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <talloc.h>
+#include <osmocom/core/linuxlist.h>
+
+#include "internal.h"
+
+static LLIST_HEAD(g_card_reader_drivers);
+static LLIST_HEAD(g_card_readers);
+
+struct card_reader *card_reader_alloc(void *ctx, const char *name,
+					const struct card_reader_driver *drv, void *drv_handle)
+{
+	struct card_reader *cr = talloc_zero(ctx, struct card_reader);
+	if (!cr)
+		return NULL;
+
+	cr->name = talloc_strdup(ctx, name);
+	cr->drv = drv;
+	cr->drv_handle = drv_handle;
+	INIT_LLIST_HEAD(&cr->slots);
+
+	llist_add(&cr->list, &g_card_readers);
+
+	printf("allocated reader '%s'\n", cr->name);
+
+	return cr;
+}
+
+/* allocate a new slot in the given reader */ 
+struct card_reader_slot *card_reader_slot_alloc(struct card_reader *cr, unsigned int slot_num)
+{
+	struct card_reader_slot *cs = talloc_zero(cr, struct card_reader_slot);
+	if (!cs)
+		return NULL;
+
+	cs->reader = cr;
+	llist_add(&cr->list, &cr->slots);
+	cs->num = slot_num;
+
+	return cs;
+}
+
+
+/* register a driver with the core, should typcially be called at start-up */
+void card_reader_driver_register(struct card_reader_driver *drv)
+{
+	llist_add_tail(&drv->list, &g_card_reader_drivers);
+}
+
+/* probe all readers on all drivers */
+void card_readers_probe(void *ctx)
+{
+	struct card_reader_driver *drv;
+
+	llist_for_each_entry(drv, &g_card_reader_drivers, list) {
+		printf("probing driver '%s' for drivers\n", drv->name);
+		drv->ops->probe(ctx);
+	}
+}
diff --git a/src/driver_pcsc.c b/src/driver_pcsc.c
new file mode 100644
index 0000000..d028e55
--- /dev/null
+++ b/src/driver_pcsc.c
@@ -0,0 +1,123 @@
+/*! \file reader_pcsc.c
+ * PC/SC Card reader backend for libosmosim. */
+/*
+ * (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <talloc.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/sim/sim.h>
+
+#include <wintypes.h>
+#include <winscard.h>
+
+#include "internal.h"
+
+#define PCSC_ERROR(rv, text) \
+if (rv != SCARD_S_SUCCESS) { \
+	fprintf(stderr, text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
+	goto end; \
+} else { \
+        printf(text ": OK\n\n"); \
+}
+
+static void pcsc_readers_probe(void *ctx)
+{
+	LONG rc;
+	LPSTR mszReaders = NULL;
+	DWORD dwReaders;
+	SCARDCONTEXT hContext;
+	unsigned int num_readers;
+	char *ptr;
+
+	rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+	PCSC_ERROR(rc, "SCardEstablishContext");
+
+	dwReaders = SCARD_AUTOALLOCATE;
+	rc = SCardListReaders(hContext, NULL, (LPSTR)&mszReaders, &dwReaders);
+	PCSC_ERROR(rc, "SCardListReaders");
+
+	num_readers = 0;
+	ptr = mszReaders;
+	while (*ptr != '\0') {
+		struct card_reader *cr;
+		/* while CCID has the nice feature to distinguish between readers and slots, PC/SC
+		 * doesn't have this distinction, so we end up having one "reader" per slot */
+		cr = card_reader_alloc(ctx, ptr, NULL, NULL);
+		card_reader_slot_alloc(cr, 0);
+		ptr += strlen(ptr)+1;
+		num_readers++;
+	}
+
+	printf("num_readers=%d\n", num_readers);
+
+end:
+	if (mszReaders)
+		SCardFreeMemory(hContext, mszReaders);
+}
+
+static int pcsc_reader_open_slot(struct card_reader_slot *slot)
+{
+	struct osim_card_hdl *card;
+	LONG rc;
+
+	if (proto != OSIM_PROTO_T0)
+		return NULL;
+
+	rc = SCardConnect(st->hContext, st->name, SCARD_SHARE_SHARED,
+			  SCARD_PROTOCOL_T0, &st->hCard, &st->dwActiveProtocol);
+	PCSC_ERROR(rc, "SCardConnect");
+
+	st->pioSendPci = SCARD_PCI_T0;
+
+	card = talloc_zero(rh, struct osim_card_hdl);
+	INIT_LLIST_HEAD(&card->channels);
+	card->reader = rh;
+	rh->card = card;
+
+end:
+	return NULL;
+}
+
+
+static const struct card_reader_driver_ops pcsc_driver_ops = {
+	.probe = pcsc_readers_probe,
+	.open_slot = pcsc_reader_open_slot,
+	.close_slot = NULL,
+	.transceive_apdu = NULL,
+};
+
+static struct card_reader_driver pcsc_driver = {
+	.name = "PCSC",
+	.ops = &pcsc_driver_ops,
+};
+
+__attribute__ ((constructor)) void pcsc_reader_init(void)
+{
+	card_reader_driver_register(&pcsc_driver);
+}
diff --git a/src/internal.h b/src/internal.h
new file mode 100644
index 0000000..cc93319
--- /dev/null
+++ b/src/internal.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <osmocom/core/linuxlist.h>
+
+struct card_reader_slot;
+
+struct card_reader_driver_ops {
+	/* probe system for card readers */
+	void (*probe)(void *ctx);
+	/* open a given slot, attempt to reset/start the card */
+	int (*open_slot)(struct card_reader_slot *slot);
+	/* close a given slot, power down the card */
+	void (*close_slot)(struct card_reader_slot *slot);
+	/* transceive an APDU */
+	int (*transceive_apdu)(struct card_reader_slot *slot);
+};
+
+struct card_reader_driver {
+	/* global list of drivers */
+	struct llist_head list;
+	/* name of the driver */
+	char *name;
+	const struct card_reader_driver_ops *ops;
+};
+
+struct card_reader {
+	/* global list of card readers */
+	struct llist_head list;
+	/* name of this reader */
+	char *name;
+	/* driver providing access to this reader */
+	const struct card_reader_driver *drv;
+	void *drv_handle;
+	/* list of card slots for this reader */
+	struct llist_head slots;
+};
+
+enum card_slot_state {
+	CARD_SLOT_OFF,
+	CARD_SLOT_OPEN,
+};
+
+struct card_reader_slot {
+	/* links to card_reader.slots */
+	struct llist_head list;
+	/* back-pointer to reader serving this slot */
+	struct card_reader *reader;
+	/* slot number */
+	unsigned int num;
+	/* state in which the slot is */
+	enum card_slot_state state;
+};
+
+
+struct card_reader *card_reader_alloc(void *ctx, const char *name,
+					const struct card_reader_driver *drv, void *drv_handle);
+struct card_reader_slot *card_reader_slot_alloc(struct card_reader *cr, unsigned int slot_num);
+
+void card_reader_driver_register(struct card_reader_driver *drv);
+void card_readers_probe(void *ctx);
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..977785c
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,42 @@
+/*! \file main.c */
+/*
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <talloc.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/sim/sim.h>
+
+#include <wintypes.h>
+#include <winscard.h>
+
+#include "internal.h"
+
+int main(int argc, char **argv)
+{
+	card_readers_probe(NULL);
+}
diff --git a/src/rspro/ATR.c b/src/rspro/ATR.c
new file mode 100644
index 0000000..55b2916
--- /dev/null
+++ b/src/rspro/ATR.c
@@ -0,0 +1,129 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ATR.h>
+
+int
+ATR_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+	size_t size;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	size = st->size;
+	
+	if((size >= 1l && size <= 55l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ATR_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
+	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
+	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
+	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
+	td->xer_encoder    = asn_DEF_OCTET_STRING.xer_encoder;
+	td->uper_decoder   = asn_DEF_OCTET_STRING.uper_decoder;
+	td->uper_encoder   = asn_DEF_OCTET_STRING.uper_encoder;
+	td->aper_decoder   = asn_DEF_OCTET_STRING.aper_decoder;
+	td->aper_encoder   = asn_DEF_OCTET_STRING.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+	td->elements       = asn_DEF_OCTET_STRING.elements;
+	td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+	td->specifics      = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+ATR_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ATR_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ATR_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ATR_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ATR_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ATR_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ATR_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_ATR_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ATR = {
+	"ATR",
+	"ATR",
+	ATR_free,
+	ATR_print,
+	ATR_constraint,
+	ATR_decode_ber,
+	ATR_encode_der,
+	ATR_decode_xer,
+	ATR_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ATR_tags_1,
+	sizeof(asn_DEF_ATR_tags_1)
+		/sizeof(asn_DEF_ATR_tags_1[0]), /* 1 */
+	asn_DEF_ATR_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ATR_tags_1)
+		/sizeof(asn_DEF_ATR_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/BankId.c b/src/rspro/BankId.c
new file mode 100644
index 0000000..7e97ea6
--- /dev/null
+++ b/src/rspro/BankId.c
@@ -0,0 +1,128 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/BankId.h>
+
+int
+BankId_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 1023l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using NativeInteger,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+BankId_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeInteger.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeInteger.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+	td->specifics      = asn_DEF_NativeInteger.specifics;
+}
+
+void
+BankId_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+BankId_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+BankId_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+BankId_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+BankId_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+BankId_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	BankId_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_BankId_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_BankId = {
+	"BankId",
+	"BankId",
+	BankId_free,
+	BankId_print,
+	BankId_constraint,
+	BankId_decode_ber,
+	BankId_encode_der,
+	BankId_decode_xer,
+	BankId_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_BankId_tags_1,
+	sizeof(asn_DEF_BankId_tags_1)
+		/sizeof(asn_DEF_BankId_tags_1[0]), /* 1 */
+	asn_DEF_BankId_tags_1,	/* Same as above */
+	sizeof(asn_DEF_BankId_tags_1)
+		/sizeof(asn_DEF_BankId_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/BankSlot.c b/src/rspro/BankSlot.c
new file mode 100644
index 0000000..64bc013
--- /dev/null
+++ b/src/rspro/BankSlot.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/BankSlot.h>
+
+static asn_TYPE_member_t asn_MBR_BankSlot_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct BankSlot, bankId),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_BankId,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bankId"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct BankSlot, slotNr),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_SlotNumber,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"slotNr"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_BankSlot_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_BankSlot_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* bankId */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 0 } /* slotNr */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_BankSlot_specs_1 = {
+	sizeof(struct BankSlot),
+	offsetof(struct BankSlot, _asn_ctx),
+	asn_MAP_BankSlot_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_BankSlot = {
+	"BankSlot",
+	"BankSlot",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_BankSlot_tags_1,
+	sizeof(asn_DEF_BankSlot_tags_1)
+		/sizeof(asn_DEF_BankSlot_tags_1[0]), /* 1 */
+	asn_DEF_BankSlot_tags_1,	/* Same as above */
+	sizeof(asn_DEF_BankSlot_tags_1)
+		/sizeof(asn_DEF_BankSlot_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_BankSlot_1,
+	2,	/* Elements count */
+	&asn_SPC_BankSlot_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/BankSlotStatusInd.c b/src/rspro/BankSlotStatusInd.c
new file mode 100644
index 0000000..81a0723
--- /dev/null
+++ b/src/rspro/BankSlotStatusInd.c
@@ -0,0 +1,79 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/BankSlotStatusInd.h>
+
+static asn_TYPE_member_t asn_MBR_BankSlotStatusInd_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct BankSlotStatusInd, fromBankSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"fromBankSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct BankSlotStatusInd, toClientSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"toClientSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct BankSlotStatusInd, slotPhysStatus),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_SlotPhysStatus,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"slotPhysStatus"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_BankSlotStatusInd_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_BankSlotStatusInd_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 2 }, /* fromBankSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 1 }, /* toClientSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 2, -2, 0 } /* slotPhysStatus */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_BankSlotStatusInd_specs_1 = {
+	sizeof(struct BankSlotStatusInd),
+	offsetof(struct BankSlotStatusInd, _asn_ctx),
+	asn_MAP_BankSlotStatusInd_tag2el_1,
+	3,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	2,	/* Start extensions */
+	4	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_BankSlotStatusInd = {
+	"BankSlotStatusInd",
+	"BankSlotStatusInd",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_BankSlotStatusInd_tags_1,
+	sizeof(asn_DEF_BankSlotStatusInd_tags_1)
+		/sizeof(asn_DEF_BankSlotStatusInd_tags_1[0]), /* 1 */
+	asn_DEF_BankSlotStatusInd_tags_1,	/* Same as above */
+	sizeof(asn_DEF_BankSlotStatusInd_tags_1)
+		/sizeof(asn_DEF_BankSlotStatusInd_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_BankSlotStatusInd_1,
+	3,	/* Elements count */
+	&asn_SPC_BankSlotStatusInd_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ClientId.c b/src/rspro/ClientId.c
new file mode 100644
index 0000000..f84c2ec
--- /dev/null
+++ b/src/rspro/ClientId.c
@@ -0,0 +1,128 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ClientId.h>
+
+int
+ClientId_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 1023l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using NativeInteger,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ClientId_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeInteger.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeInteger.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+	td->specifics      = asn_DEF_NativeInteger.specifics;
+}
+
+void
+ClientId_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ClientId_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ClientId_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ClientId_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ClientId_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ClientId_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ClientId_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_ClientId_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ClientId = {
+	"ClientId",
+	"ClientId",
+	ClientId_free,
+	ClientId_print,
+	ClientId_constraint,
+	ClientId_decode_ber,
+	ClientId_encode_der,
+	ClientId_decode_xer,
+	ClientId_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ClientId_tags_1,
+	sizeof(asn_DEF_ClientId_tags_1)
+		/sizeof(asn_DEF_ClientId_tags_1[0]), /* 1 */
+	asn_DEF_ClientId_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ClientId_tags_1)
+		/sizeof(asn_DEF_ClientId_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/ClientSlot.c b/src/rspro/ClientSlot.c
new file mode 100644
index 0000000..6747d89
--- /dev/null
+++ b/src/rspro/ClientSlot.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ClientSlot.h>
+
+static asn_TYPE_member_t asn_MBR_ClientSlot_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ClientSlot, clientId),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_ClientId,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"clientId"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ClientSlot, slotNr),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_SlotNumber,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"slotNr"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ClientSlot_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ClientSlot_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* clientId */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 0 } /* slotNr */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ClientSlot_specs_1 = {
+	sizeof(struct ClientSlot),
+	offsetof(struct ClientSlot, _asn_ctx),
+	asn_MAP_ClientSlot_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ClientSlot = {
+	"ClientSlot",
+	"ClientSlot",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ClientSlot_tags_1,
+	sizeof(asn_DEF_ClientSlot_tags_1)
+		/sizeof(asn_DEF_ClientSlot_tags_1[0]), /* 1 */
+	asn_DEF_ClientSlot_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ClientSlot_tags_1)
+		/sizeof(asn_DEF_ClientSlot_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ClientSlot_1,
+	2,	/* Elements count */
+	&asn_SPC_ClientSlot_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ClientSlotStatusInd.c b/src/rspro/ClientSlotStatusInd.c
new file mode 100644
index 0000000..03110bc
--- /dev/null
+++ b/src/rspro/ClientSlotStatusInd.c
@@ -0,0 +1,79 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ClientSlotStatusInd.h>
+
+static asn_TYPE_member_t asn_MBR_ClientSlotStatusInd_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ClientSlotStatusInd, fromClientSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"fromClientSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ClientSlotStatusInd, toBankSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"toBankSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ClientSlotStatusInd, slotPhysStatus),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_SlotPhysStatus,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"slotPhysStatus"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ClientSlotStatusInd_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ClientSlotStatusInd_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 2 }, /* fromClientSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 1 }, /* toBankSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 2, -2, 0 } /* slotPhysStatus */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ClientSlotStatusInd_specs_1 = {
+	sizeof(struct ClientSlotStatusInd),
+	offsetof(struct ClientSlotStatusInd, _asn_ctx),
+	asn_MAP_ClientSlotStatusInd_tag2el_1,
+	3,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	2,	/* Start extensions */
+	4	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ClientSlotStatusInd = {
+	"ClientSlotStatusInd",
+	"ClientSlotStatusInd",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ClientSlotStatusInd_tags_1,
+	sizeof(asn_DEF_ClientSlotStatusInd_tags_1)
+		/sizeof(asn_DEF_ClientSlotStatusInd_tags_1[0]), /* 1 */
+	asn_DEF_ClientSlotStatusInd_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ClientSlotStatusInd_tags_1)
+		/sizeof(asn_DEF_ClientSlotStatusInd_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ClientSlotStatusInd_1,
+	3,	/* Elements count */
+	&asn_SPC_ClientSlotStatusInd_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ComponentIdentity.c b/src/rspro/ComponentIdentity.c
new file mode 100644
index 0000000..0703952
--- /dev/null
+++ b/src/rspro/ComponentIdentity.c
@@ -0,0 +1,139 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ComponentIdentity.h>
+
+static asn_TYPE_member_t asn_MBR_ComponentIdentity_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ComponentIdentity, type),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ComponentType,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"type"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ComponentIdentity, name),
+		(ASN_TAG_CLASS_UNIVERSAL | (22 << 2)),
+		0,
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"name"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ComponentIdentity, software),
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"software"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ComponentIdentity, swVersion),
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"swVersion"
+		},
+	{ ATF_POINTER, 5, offsetof(struct ComponentIdentity, hwManufacturer),
+		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"hwManufacturer"
+		},
+	{ ATF_POINTER, 4, offsetof(struct ComponentIdentity, hwModel),
+		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"hwModel"
+		},
+	{ ATF_POINTER, 3, offsetof(struct ComponentIdentity, hwSerialNr),
+		(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"hwSerialNr"
+		},
+	{ ATF_POINTER, 2, offsetof(struct ComponentIdentity, hwVersion),
+		(ASN_TAG_CLASS_CONTEXT | (5 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"hwVersion"
+		},
+	{ ATF_POINTER, 1, offsetof(struct ComponentIdentity, fwVersion),
+		(ASN_TAG_CLASS_CONTEXT | (6 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ComponentName,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"fwVersion"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ComponentIdentity_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ComponentIdentity_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 }, /* type */
+    { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), 1, 0, 0 }, /* name */
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 2, 0, 0 }, /* software */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 3, 0, 0 }, /* swVersion */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 4, 0, 0 }, /* hwManufacturer */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 5, 0, 0 }, /* hwModel */
+    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 6, 0, 0 }, /* hwSerialNr */
+    { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 7, 0, 0 }, /* hwVersion */
+    { (ASN_TAG_CLASS_CONTEXT | (6 << 2)), 8, 0, 0 } /* fwVersion */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ComponentIdentity_specs_1 = {
+	sizeof(struct ComponentIdentity),
+	offsetof(struct ComponentIdentity, _asn_ctx),
+	asn_MAP_ComponentIdentity_tag2el_1,
+	9,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	8,	/* Start extensions */
+	10	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ComponentIdentity = {
+	"ComponentIdentity",
+	"ComponentIdentity",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ComponentIdentity_tags_1,
+	sizeof(asn_DEF_ComponentIdentity_tags_1)
+		/sizeof(asn_DEF_ComponentIdentity_tags_1[0]), /* 1 */
+	asn_DEF_ComponentIdentity_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ComponentIdentity_tags_1)
+		/sizeof(asn_DEF_ComponentIdentity_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ComponentIdentity_1,
+	9,	/* Elements count */
+	&asn_SPC_ComponentIdentity_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ComponentName.c b/src/rspro/ComponentName.c
new file mode 100644
index 0000000..4dbed5f
--- /dev/null
+++ b/src/rspro/ComponentName.c
@@ -0,0 +1,143 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ComponentName.h>
+
+static int check_permitted_alphabet_1(const void *sptr) {
+	/* The underlying type is IA5String */
+	const IA5String_t *st = (const IA5String_t *)sptr;
+	const uint8_t *ch = st->buf;
+	const uint8_t *end = ch + st->size;
+	
+	for(; ch < end; ch++) {
+		uint8_t cv = *ch;
+		if(!(cv <= 127l)) return -1;
+	}
+	return 0;
+}
+
+int
+ComponentName_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	const IA5String_t *st = (const IA5String_t *)sptr;
+	size_t size;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	size = st->size;
+	
+	if((size >= 1l && size <= 32l)
+		 && !check_permitted_alphabet_1(st)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using IA5String,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ComponentName_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_IA5String.free_struct;
+	td->print_struct   = asn_DEF_IA5String.print_struct;
+	td->check_constraints = asn_DEF_IA5String.check_constraints;
+	td->ber_decoder    = asn_DEF_IA5String.ber_decoder;
+	td->der_encoder    = asn_DEF_IA5String.der_encoder;
+	td->xer_decoder    = asn_DEF_IA5String.xer_decoder;
+	td->xer_encoder    = asn_DEF_IA5String.xer_encoder;
+	td->uper_decoder   = asn_DEF_IA5String.uper_decoder;
+	td->uper_encoder   = asn_DEF_IA5String.uper_encoder;
+	td->aper_decoder   = asn_DEF_IA5String.aper_decoder;
+	td->aper_encoder   = asn_DEF_IA5String.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_IA5String.per_constraints;
+	td->elements       = asn_DEF_IA5String.elements;
+	td->elements_count = asn_DEF_IA5String.elements_count;
+	td->specifics      = asn_DEF_IA5String.specifics;
+}
+
+void
+ComponentName_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ComponentName_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ComponentName_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ComponentName_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ComponentName_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ComponentName_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentName_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_ComponentName_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ComponentName = {
+	"ComponentName",
+	"ComponentName",
+	ComponentName_free,
+	ComponentName_print,
+	ComponentName_constraint,
+	ComponentName_decode_ber,
+	ComponentName_encode_der,
+	ComponentName_decode_xer,
+	ComponentName_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ComponentName_tags_1,
+	sizeof(asn_DEF_ComponentName_tags_1)
+		/sizeof(asn_DEF_ComponentName_tags_1[0]), /* 1 */
+	asn_DEF_ComponentName_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ComponentName_tags_1)
+		/sizeof(asn_DEF_ComponentName_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/ComponentType.c b/src/rspro/ComponentType.c
new file mode 100644
index 0000000..855625d
--- /dev/null
+++ b/src/rspro/ComponentType.c
@@ -0,0 +1,130 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ComponentType.h>
+
+int
+ComponentType_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	/* Replace with underlying type checker */
+	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
+	return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using NativeEnumerated,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ComponentType_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeEnumerated.free_struct;
+	td->print_struct   = asn_DEF_NativeEnumerated.print_struct;
+	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeEnumerated.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeEnumerated.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeEnumerated.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeEnumerated.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeEnumerated.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeEnumerated.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeEnumerated.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeEnumerated.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeEnumerated.per_constraints;
+	td->elements       = asn_DEF_NativeEnumerated.elements;
+	td->elements_count = asn_DEF_NativeEnumerated.elements_count;
+     /* td->specifics      = asn_DEF_NativeEnumerated.specifics;	// Defined explicitly */
+}
+
+void
+ComponentType_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ComponentType_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ComponentType_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ComponentType_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ComponentType_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ComponentType_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ComponentType_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const asn_INTEGER_enum_map_t asn_MAP_ComponentType_value2enum_1[] = {
+	{ 0,	12,	"remsimClient" },
+	{ 1,	12,	"remsimServer" },
+	{ 2,	11,	"remsimBankd" }
+};
+static const unsigned int asn_MAP_ComponentType_enum2value_1[] = {
+	2,	/* remsimBankd(2) */
+	0,	/* remsimClient(0) */
+	1	/* remsimServer(1) */
+};
+static const asn_INTEGER_specifics_t asn_SPC_ComponentType_specs_1 = {
+	asn_MAP_ComponentType_value2enum_1,	/* "tag" => N; sorted by tag */
+	asn_MAP_ComponentType_enum2value_1,	/* N => "tag"; sorted by N */
+	3,	/* Number of elements in the maps */
+	0,	/* Enumeration is not extensible */
+	1,	/* Strict enumeration */
+	0,	/* Native long size */
+	0
+};
+static const ber_tlv_tag_t asn_DEF_ComponentType_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ComponentType = {
+	"ComponentType",
+	"ComponentType",
+	ComponentType_free,
+	ComponentType_print,
+	ComponentType_constraint,
+	ComponentType_decode_ber,
+	ComponentType_encode_der,
+	ComponentType_decode_xer,
+	ComponentType_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ComponentType_tags_1,
+	sizeof(asn_DEF_ComponentType_tags_1)
+		/sizeof(asn_DEF_ComponentType_tags_1[0]), /* 1 */
+	asn_DEF_ComponentType_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ComponentType_tags_1)
+		/sizeof(asn_DEF_ComponentType_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* Defined elsewhere */
+	&asn_SPC_ComponentType_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConfigClientReq.c b/src/rspro/ConfigClientReq.c
new file mode 100644
index 0000000..1221b4a
--- /dev/null
+++ b/src/rspro/ConfigClientReq.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConfigClientReq.h>
+
+static asn_TYPE_member_t asn_MBR_ConfigClientReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConfigClientReq, clientId),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_ClientId,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"clientId"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ConfigClientReq, bankd),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_IpPort,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bankd"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConfigClientReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConfigClientReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* clientId */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 } /* bankd */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConfigClientReq_specs_1 = {
+	sizeof(struct ConfigClientReq),
+	offsetof(struct ConfigClientReq, _asn_ctx),
+	asn_MAP_ConfigClientReq_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConfigClientReq = {
+	"ConfigClientReq",
+	"ConfigClientReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConfigClientReq_tags_1,
+	sizeof(asn_DEF_ConfigClientReq_tags_1)
+		/sizeof(asn_DEF_ConfigClientReq_tags_1[0]), /* 1 */
+	asn_DEF_ConfigClientReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConfigClientReq_tags_1)
+		/sizeof(asn_DEF_ConfigClientReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConfigClientReq_1,
+	2,	/* Elements count */
+	&asn_SPC_ConfigClientReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConfigClientRes.c b/src/rspro/ConfigClientRes.c
new file mode 100644
index 0000000..e30fda1
--- /dev/null
+++ b/src/rspro/ConfigClientRes.c
@@ -0,0 +1,59 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConfigClientRes.h>
+
+static asn_TYPE_member_t asn_MBR_ConfigClientRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConfigClientRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConfigClientRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConfigClientRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* result */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConfigClientRes_specs_1 = {
+	sizeof(struct ConfigClientRes),
+	offsetof(struct ConfigClientRes, _asn_ctx),
+	asn_MAP_ConfigClientRes_tag2el_1,
+	1,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	0,	/* Start extensions */
+	2	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConfigClientRes = {
+	"ConfigClientRes",
+	"ConfigClientRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConfigClientRes_tags_1,
+	sizeof(asn_DEF_ConfigClientRes_tags_1)
+		/sizeof(asn_DEF_ConfigClientRes_tags_1[0]), /* 1 */
+	asn_DEF_ConfigClientRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConfigClientRes_tags_1)
+		/sizeof(asn_DEF_ConfigClientRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConfigClientRes_1,
+	1,	/* Elements count */
+	&asn_SPC_ConfigClientRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConnectBankReq.c b/src/rspro/ConnectBankReq.c
new file mode 100644
index 0000000..0d33aa8
--- /dev/null
+++ b/src/rspro/ConnectBankReq.c
@@ -0,0 +1,79 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConnectBankReq.h>
+
+static asn_TYPE_member_t asn_MBR_ConnectBankReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectBankReq, identity),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ComponentIdentity,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"identity"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectBankReq, bankId),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_BankId,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bankId"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectBankReq, numberOfSlots),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_SlotNumber,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"numberOfSlots"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConnectBankReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConnectBankReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 1 }, /* bankId */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* numberOfSlots */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 0 } /* identity */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConnectBankReq_specs_1 = {
+	sizeof(struct ConnectBankReq),
+	offsetof(struct ConnectBankReq, _asn_ctx),
+	asn_MAP_ConnectBankReq_tag2el_1,
+	3,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	2,	/* Start extensions */
+	4	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConnectBankReq = {
+	"ConnectBankReq",
+	"ConnectBankReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConnectBankReq_tags_1,
+	sizeof(asn_DEF_ConnectBankReq_tags_1)
+		/sizeof(asn_DEF_ConnectBankReq_tags_1[0]), /* 1 */
+	asn_DEF_ConnectBankReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConnectBankReq_tags_1)
+		/sizeof(asn_DEF_ConnectBankReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConnectBankReq_1,
+	3,	/* Elements count */
+	&asn_SPC_ConnectBankReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConnectBankRes.c b/src/rspro/ConnectBankRes.c
new file mode 100644
index 0000000..091aedd
--- /dev/null
+++ b/src/rspro/ConnectBankRes.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConnectBankRes.h>
+
+static asn_TYPE_member_t asn_MBR_ConnectBankRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectBankRes, identity),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ComponentIdentity,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"identity"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectBankRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConnectBankRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConnectBankRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 0 }, /* result */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 0 } /* identity */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConnectBankRes_specs_1 = {
+	sizeof(struct ConnectBankRes),
+	offsetof(struct ConnectBankRes, _asn_ctx),
+	asn_MAP_ConnectBankRes_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConnectBankRes = {
+	"ConnectBankRes",
+	"ConnectBankRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConnectBankRes_tags_1,
+	sizeof(asn_DEF_ConnectBankRes_tags_1)
+		/sizeof(asn_DEF_ConnectBankRes_tags_1[0]), /* 1 */
+	asn_DEF_ConnectBankRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConnectBankRes_tags_1)
+		/sizeof(asn_DEF_ConnectBankRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConnectBankRes_1,
+	2,	/* Elements count */
+	&asn_SPC_ConnectBankRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConnectClientReq.c b/src/rspro/ConnectClientReq.c
new file mode 100644
index 0000000..84decb3
--- /dev/null
+++ b/src/rspro/ConnectClientReq.c
@@ -0,0 +1,59 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConnectClientReq.h>
+
+static asn_TYPE_member_t asn_MBR_ConnectClientReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectClientReq, identity),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ComponentIdentity,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"identity"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConnectClientReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConnectClientReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 0 } /* identity */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConnectClientReq_specs_1 = {
+	sizeof(struct ConnectClientReq),
+	offsetof(struct ConnectClientReq, _asn_ctx),
+	asn_MAP_ConnectClientReq_tag2el_1,
+	1,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	0,	/* Start extensions */
+	2	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConnectClientReq = {
+	"ConnectClientReq",
+	"ConnectClientReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConnectClientReq_tags_1,
+	sizeof(asn_DEF_ConnectClientReq_tags_1)
+		/sizeof(asn_DEF_ConnectClientReq_tags_1[0]), /* 1 */
+	asn_DEF_ConnectClientReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConnectClientReq_tags_1)
+		/sizeof(asn_DEF_ConnectClientReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConnectClientReq_1,
+	1,	/* Elements count */
+	&asn_SPC_ConnectClientReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ConnectClientRes.c b/src/rspro/ConnectClientRes.c
new file mode 100644
index 0000000..676e22e
--- /dev/null
+++ b/src/rspro/ConnectClientRes.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ConnectClientRes.h>
+
+static asn_TYPE_member_t asn_MBR_ConnectClientRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectClientRes, identity),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ComponentIdentity,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"identity"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct ConnectClientRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_ConnectClientRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ConnectClientRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 0 }, /* result */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 0 } /* identity */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_ConnectClientRes_specs_1 = {
+	sizeof(struct ConnectClientRes),
+	offsetof(struct ConnectClientRes, _asn_ctx),
+	asn_MAP_ConnectClientRes_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_ConnectClientRes = {
+	"ConnectClientRes",
+	"ConnectClientRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ConnectClientRes_tags_1,
+	sizeof(asn_DEF_ConnectClientRes_tags_1)
+		/sizeof(asn_DEF_ConnectClientRes_tags_1[0]), /* 1 */
+	asn_DEF_ConnectClientRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ConnectClientRes_tags_1)
+		/sizeof(asn_DEF_ConnectClientRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_ConnectClientRes_1,
+	2,	/* Elements count */
+	&asn_SPC_ConnectClientRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/CreateMappingReq.c b/src/rspro/CreateMappingReq.c
new file mode 100644
index 0000000..23b2d4f
--- /dev/null
+++ b/src/rspro/CreateMappingReq.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/CreateMappingReq.h>
+
+static asn_TYPE_member_t asn_MBR_CreateMappingReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct CreateMappingReq, client),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"client"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct CreateMappingReq, bank),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bank"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_CreateMappingReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_CreateMappingReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 1 }, /* client */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 0 } /* bank */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_CreateMappingReq_specs_1 = {
+	sizeof(struct CreateMappingReq),
+	offsetof(struct CreateMappingReq, _asn_ctx),
+	asn_MAP_CreateMappingReq_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_CreateMappingReq = {
+	"CreateMappingReq",
+	"CreateMappingReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_CreateMappingReq_tags_1,
+	sizeof(asn_DEF_CreateMappingReq_tags_1)
+		/sizeof(asn_DEF_CreateMappingReq_tags_1[0]), /* 1 */
+	asn_DEF_CreateMappingReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_CreateMappingReq_tags_1)
+		/sizeof(asn_DEF_CreateMappingReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_CreateMappingReq_1,
+	2,	/* Elements count */
+	&asn_SPC_CreateMappingReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/CreateMappingRes.c b/src/rspro/CreateMappingRes.c
new file mode 100644
index 0000000..d0c6048
--- /dev/null
+++ b/src/rspro/CreateMappingRes.c
@@ -0,0 +1,59 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/CreateMappingRes.h>
+
+static asn_TYPE_member_t asn_MBR_CreateMappingRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct CreateMappingRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_CreateMappingRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_CreateMappingRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* result */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_CreateMappingRes_specs_1 = {
+	sizeof(struct CreateMappingRes),
+	offsetof(struct CreateMappingRes, _asn_ctx),
+	asn_MAP_CreateMappingRes_tag2el_1,
+	1,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	0,	/* Start extensions */
+	2	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_CreateMappingRes = {
+	"CreateMappingRes",
+	"CreateMappingRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_CreateMappingRes_tags_1,
+	sizeof(asn_DEF_CreateMappingRes_tags_1)
+		/sizeof(asn_DEF_CreateMappingRes_tags_1[0]), /* 1 */
+	asn_DEF_CreateMappingRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_CreateMappingRes_tags_1)
+		/sizeof(asn_DEF_CreateMappingRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_CreateMappingRes_1,
+	1,	/* Elements count */
+	&asn_SPC_CreateMappingRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/IpAddress.c b/src/rspro/IpAddress.c
new file mode 100644
index 0000000..4dfb46d
--- /dev/null
+++ b/src/rspro/IpAddress.c
@@ -0,0 +1,65 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/IpAddress.h>
+
+static asn_TYPE_member_t asn_MBR_IpAddress_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct IpAddress, choice.ipv4),
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_Ipv4Address,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"ipv4"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct IpAddress, choice.ipv6),
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_Ipv6Address,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"ipv6"
+		},
+};
+static const asn_TYPE_tag2member_t asn_MAP_IpAddress_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ipv4 */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* ipv6 */
+};
+static asn_CHOICE_specifics_t asn_SPC_IpAddress_specs_1 = {
+	sizeof(struct IpAddress),
+	offsetof(struct IpAddress, _asn_ctx),
+	offsetof(struct IpAddress, present),
+	sizeof(((struct IpAddress *)0)->present),
+	asn_MAP_IpAddress_tag2el_1,
+	2,	/* Count of tags in the map */
+	0,
+	-1	/* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_IpAddress = {
+	"IpAddress",
+	"IpAddress",
+	CHOICE_free,
+	CHOICE_print,
+	CHOICE_constraint,
+	CHOICE_decode_ber,
+	CHOICE_encode_der,
+	CHOICE_decode_xer,
+	CHOICE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	CHOICE_outmost_tag,
+	0,	/* No effective tags (pointer) */
+	0,	/* No effective tags (count) */
+	0,	/* No tags (pointer) */
+	0,	/* No tags (count) */
+	0,	/* No PER visible constraints */
+	asn_MBR_IpAddress_1,
+	2,	/* Elements count */
+	&asn_SPC_IpAddress_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/IpPort.c b/src/rspro/IpPort.c
new file mode 100644
index 0000000..003bbdb
--- /dev/null
+++ b/src/rspro/IpPort.c
@@ -0,0 +1,70 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/IpPort.h>
+
+static asn_TYPE_member_t asn_MBR_IpPort_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct IpPort, ip),
+		-1 /* Ambiguous tag (CHOICE?) */,
+		0,
+		&asn_DEF_IpAddress,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"ip"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct IpPort, port),
+		(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+		0,
+		&asn_DEF_PortNumber,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"port"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_IpPort_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_IpPort_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* port */
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ipv4 */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 0, 0, 0 } /* ipv6 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_IpPort_specs_1 = {
+	sizeof(struct IpPort),
+	offsetof(struct IpPort, _asn_ctx),
+	asn_MAP_IpPort_tag2el_1,
+	3,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	-1,	/* Start extensions */
+	-1	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_IpPort = {
+	"IpPort",
+	"IpPort",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_IpPort_tags_1,
+	sizeof(asn_DEF_IpPort_tags_1)
+		/sizeof(asn_DEF_IpPort_tags_1[0]), /* 1 */
+	asn_DEF_IpPort_tags_1,	/* Same as above */
+	sizeof(asn_DEF_IpPort_tags_1)
+		/sizeof(asn_DEF_IpPort_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_IpPort_1,
+	2,	/* Elements count */
+	&asn_SPC_IpPort_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/Ipv4Address.c b/src/rspro/Ipv4Address.c
new file mode 100644
index 0000000..03ec023
--- /dev/null
+++ b/src/rspro/Ipv4Address.c
@@ -0,0 +1,129 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/Ipv4Address.h>
+
+int
+Ipv4Address_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+	size_t size;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	size = st->size;
+	
+	if((size == 4l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Ipv4Address_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
+	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
+	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
+	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
+	td->xer_encoder    = asn_DEF_OCTET_STRING.xer_encoder;
+	td->uper_decoder   = asn_DEF_OCTET_STRING.uper_decoder;
+	td->uper_encoder   = asn_DEF_OCTET_STRING.uper_encoder;
+	td->aper_decoder   = asn_DEF_OCTET_STRING.aper_decoder;
+	td->aper_encoder   = asn_DEF_OCTET_STRING.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+	td->elements       = asn_DEF_OCTET_STRING.elements;
+	td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+	td->specifics      = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+Ipv4Address_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Ipv4Address_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Ipv4Address_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Ipv4Address_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Ipv4Address_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Ipv4Address_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv4Address_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_Ipv4Address_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Ipv4Address = {
+	"Ipv4Address",
+	"Ipv4Address",
+	Ipv4Address_free,
+	Ipv4Address_print,
+	Ipv4Address_constraint,
+	Ipv4Address_decode_ber,
+	Ipv4Address_encode_der,
+	Ipv4Address_decode_xer,
+	Ipv4Address_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_Ipv4Address_tags_1,
+	sizeof(asn_DEF_Ipv4Address_tags_1)
+		/sizeof(asn_DEF_Ipv4Address_tags_1[0]), /* 1 */
+	asn_DEF_Ipv4Address_tags_1,	/* Same as above */
+	sizeof(asn_DEF_Ipv4Address_tags_1)
+		/sizeof(asn_DEF_Ipv4Address_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/Ipv6Address.c b/src/rspro/Ipv6Address.c
new file mode 100644
index 0000000..2f1333c
--- /dev/null
+++ b/src/rspro/Ipv6Address.c
@@ -0,0 +1,129 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/Ipv6Address.h>
+
+int
+Ipv6Address_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+	size_t size;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	size = st->size;
+	
+	if((size == 16l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Ipv6Address_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
+	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
+	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
+	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
+	td->xer_encoder    = asn_DEF_OCTET_STRING.xer_encoder;
+	td->uper_decoder   = asn_DEF_OCTET_STRING.uper_decoder;
+	td->uper_encoder   = asn_DEF_OCTET_STRING.uper_encoder;
+	td->aper_decoder   = asn_DEF_OCTET_STRING.aper_decoder;
+	td->aper_encoder   = asn_DEF_OCTET_STRING.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+	td->elements       = asn_DEF_OCTET_STRING.elements;
+	td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+	td->specifics      = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+Ipv6Address_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Ipv6Address_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Ipv6Address_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Ipv6Address_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Ipv6Address_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Ipv6Address_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	Ipv6Address_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_Ipv6Address_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Ipv6Address = {
+	"Ipv6Address",
+	"Ipv6Address",
+	Ipv6Address_free,
+	Ipv6Address_print,
+	Ipv6Address_constraint,
+	Ipv6Address_decode_ber,
+	Ipv6Address_encode_der,
+	Ipv6Address_decode_xer,
+	Ipv6Address_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_Ipv6Address_tags_1,
+	sizeof(asn_DEF_Ipv6Address_tags_1)
+		/sizeof(asn_DEF_Ipv6Address_tags_1[0]), /* 1 */
+	asn_DEF_Ipv6Address_tags_1,	/* Same as above */
+	sizeof(asn_DEF_Ipv6Address_tags_1)
+		/sizeof(asn_DEF_Ipv6Address_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/Makefile.am b/src/rspro/Makefile.am
new file mode 100644
index 0000000..dc3a822
--- /dev/null
+++ b/src/rspro/Makefile.am
@@ -0,0 +1,89 @@
+ASN_MODULE_SOURCES =	\
+	ATR.c \
+	BankId.c \
+	BankSlot.c \
+	BankSlotStatusInd.c \
+	ClientId.c \
+	ClientSlot.c \
+	ClientSlotStatusInd.c \
+	ComponentIdentity.c \
+	ComponentName.c \
+	ComponentType.c \
+	ConfigClientReq.c \
+	ConfigClientRes.c \
+	ConnectBankReq.c \
+	ConnectBankRes.c \
+	ConnectClientReq.c \
+	ConnectClientRes.c \
+	CreateMappingReq.c \
+	CreateMappingRes.c \
+	IpAddress.c \
+	IpPort.c \
+	Ipv4Address.c \
+	Ipv6Address.c \
+	OperationTag.c \
+	PortNumber.c \
+	RemoveMappingReq.c \
+	RemoveMappingRes.c \
+	ResultCode.c \
+	RsproPDU.c \
+	RsproPDUchoice.c \
+	SetAtrReq.c \
+	SetAtrRes.c \
+	SlotNumber.c \
+	SlotPhysStatus.c \
+	TpduCardToModem.c \
+	TpduFlags.c \
+	TpduModemToCard.c \
+	$(NULL)
+
+ASN_MODULE_INC = \
+	ATR.h \
+	BankId.h \
+	BankSlot.h \
+	BankSlotStatusInd.h \
+	ClientId.h \
+	ClientSlot.h \
+	ClientSlotStatusInd.h \
+	ComponentIdentity.h \
+	ComponentName.h \
+	ComponentType.h \
+	ConfigClientReq.h \
+	ConfigClientRes.h \
+	ConnectBankReq.h \
+	ConnectBankRes.h \
+	ConnectClientReq.h \
+	ConnectClientRes.h \
+	CreateMappingReq.h \
+	CreateMappingRes.h \
+	IpAddress.h \
+	IpPort.h \
+	Ipv4Address.h \
+	Ipv6Address.h \
+	OperationTag.h \
+	PortNumber.h \
+	RemoveMappingReq.h \
+	RemoveMappingRes.h \
+	ResultCode.h \
+	RsproPDU.h \
+	RsproPDUchoice.h \
+	SetAtrReq.h \
+	SetAtrRes.h \
+	SlotNumber.h \
+	SlotPhysStatus.h \
+	TpduCardToModem.h \
+	TpduFlags.h \
+	TpduModemToCard.h \
+	$(NULL)
+
+AM_CFLAGS = -I$(top_srcdir)/include $(ASN1C_CFLAGS) $(OSMOCORE_CFLAGS)
+
+noinst_LTLIBRARIES=libosmo-asn1-rspro.la
+libosmo_asn1_rspro_la_SOURCES=$(ASN_MODULE_SOURCES)
+libosmo_asn1_rspro_la_LIBADD=$(ASN1C_LDADD)
+
+regen: regenerate-from-asn1-source
+
+regenerate-from-asn1-source:
+	asn1c -R $(top_srcdir)/asn1/RSPRO.asn
+	$(top_srcdir)/move-asn1-header-files.sh osmocom/rspro $(ASN_MODULE_INC)
diff --git a/src/rspro/OperationTag.c b/src/rspro/OperationTag.c
new file mode 100644
index 0000000..4286b22
--- /dev/null
+++ b/src/rspro/OperationTag.c
@@ -0,0 +1,128 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/OperationTag.h>
+
+int
+OperationTag_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 2147483647l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using NativeInteger,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+OperationTag_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeInteger.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeInteger.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+	td->specifics      = asn_DEF_NativeInteger.specifics;
+}
+
+void
+OperationTag_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+OperationTag_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+OperationTag_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+OperationTag_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+OperationTag_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+OperationTag_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	OperationTag_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_OperationTag_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_OperationTag = {
+	"OperationTag",
+	"OperationTag",
+	OperationTag_free,
+	OperationTag_print,
+	OperationTag_constraint,
+	OperationTag_decode_ber,
+	OperationTag_encode_der,
+	OperationTag_decode_xer,
+	OperationTag_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_OperationTag_tags_1,
+	sizeof(asn_DEF_OperationTag_tags_1)
+		/sizeof(asn_DEF_OperationTag_tags_1[0]), /* 1 */
+	asn_DEF_OperationTag_tags_1,	/* Same as above */
+	sizeof(asn_DEF_OperationTag_tags_1)
+		/sizeof(asn_DEF_OperationTag_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/PortNumber.c b/src/rspro/PortNumber.c
new file mode 100644
index 0000000..7197d00
--- /dev/null
+++ b/src/rspro/PortNumber.c
@@ -0,0 +1,128 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/PortNumber.h>
+
+int
+PortNumber_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 65535l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using NativeInteger,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+PortNumber_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeInteger.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeInteger.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+	td->specifics      = asn_DEF_NativeInteger.specifics;
+}
+
+void
+PortNumber_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+PortNumber_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+PortNumber_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+PortNumber_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+PortNumber_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+PortNumber_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	PortNumber_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_PortNumber_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_PortNumber = {
+	"PortNumber",
+	"PortNumber",
+	PortNumber_free,
+	PortNumber_print,
+	PortNumber_constraint,
+	PortNumber_decode_ber,
+	PortNumber_encode_der,
+	PortNumber_decode_xer,
+	PortNumber_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_PortNumber_tags_1,
+	sizeof(asn_DEF_PortNumber_tags_1)
+		/sizeof(asn_DEF_PortNumber_tags_1[0]), /* 1 */
+	asn_DEF_PortNumber_tags_1,	/* Same as above */
+	sizeof(asn_DEF_PortNumber_tags_1)
+		/sizeof(asn_DEF_PortNumber_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/RemoveMappingReq.c b/src/rspro/RemoveMappingReq.c
new file mode 100644
index 0000000..dc4329e
--- /dev/null
+++ b/src/rspro/RemoveMappingReq.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/RemoveMappingReq.h>
+
+static asn_TYPE_member_t asn_MBR_RemoveMappingReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct RemoveMappingReq, client),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"client"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RemoveMappingReq, bank),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bank"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_RemoveMappingReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_RemoveMappingReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 1 }, /* client */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 0 } /* bank */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_RemoveMappingReq_specs_1 = {
+	sizeof(struct RemoveMappingReq),
+	offsetof(struct RemoveMappingReq, _asn_ctx),
+	asn_MAP_RemoveMappingReq_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_RemoveMappingReq = {
+	"RemoveMappingReq",
+	"RemoveMappingReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_RemoveMappingReq_tags_1,
+	sizeof(asn_DEF_RemoveMappingReq_tags_1)
+		/sizeof(asn_DEF_RemoveMappingReq_tags_1[0]), /* 1 */
+	asn_DEF_RemoveMappingReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_RemoveMappingReq_tags_1)
+		/sizeof(asn_DEF_RemoveMappingReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_RemoveMappingReq_1,
+	2,	/* Elements count */
+	&asn_SPC_RemoveMappingReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/RemoveMappingRes.c b/src/rspro/RemoveMappingRes.c
new file mode 100644
index 0000000..0b304f2
--- /dev/null
+++ b/src/rspro/RemoveMappingRes.c
@@ -0,0 +1,59 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/RemoveMappingRes.h>
+
+static asn_TYPE_member_t asn_MBR_RemoveMappingRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct RemoveMappingRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_RemoveMappingRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_RemoveMappingRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* result */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_RemoveMappingRes_specs_1 = {
+	sizeof(struct RemoveMappingRes),
+	offsetof(struct RemoveMappingRes, _asn_ctx),
+	asn_MAP_RemoveMappingRes_tag2el_1,
+	1,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	0,	/* Start extensions */
+	2	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_RemoveMappingRes = {
+	"RemoveMappingRes",
+	"RemoveMappingRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_RemoveMappingRes_tags_1,
+	sizeof(asn_DEF_RemoveMappingRes_tags_1)
+		/sizeof(asn_DEF_RemoveMappingRes_tags_1[0]), /* 1 */
+	asn_DEF_RemoveMappingRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_RemoveMappingRes_tags_1)
+		/sizeof(asn_DEF_RemoveMappingRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_RemoveMappingRes_1,
+	1,	/* Elements count */
+	&asn_SPC_RemoveMappingRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/ResultCode.c b/src/rspro/ResultCode.c
new file mode 100644
index 0000000..871a1fc
--- /dev/null
+++ b/src/rspro/ResultCode.c
@@ -0,0 +1,140 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/ResultCode.h>
+
+int
+ResultCode_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	/* Replace with underlying type checker */
+	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
+	return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using NativeEnumerated,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ResultCode_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeEnumerated.free_struct;
+	td->print_struct   = asn_DEF_NativeEnumerated.print_struct;
+	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeEnumerated.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeEnumerated.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeEnumerated.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeEnumerated.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeEnumerated.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeEnumerated.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeEnumerated.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeEnumerated.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeEnumerated.per_constraints;
+	td->elements       = asn_DEF_NativeEnumerated.elements;
+	td->elements_count = asn_DEF_NativeEnumerated.elements_count;
+     /* td->specifics      = asn_DEF_NativeEnumerated.specifics;	// Defined explicitly */
+}
+
+void
+ResultCode_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ResultCode_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ResultCode_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ResultCode_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ResultCode_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ResultCode_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	ResultCode_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const asn_INTEGER_enum_map_t asn_MAP_ResultCode_value2enum_1[] = {
+	{ 0,	2,	"ok" },
+	{ 1,	15,	"illegalClientId" },
+	{ 2,	13,	"illegalBankId" },
+	{ 3,	13,	"illegalSlotId" },
+	{ 100,	14,	"cardNotPresent" },
+	{ 101,	16,	"cardUnresponsive" },
+	{ 102,	21,	"cardTransmissionError" }
+	/* This list is extensible */
+};
+static const unsigned int asn_MAP_ResultCode_enum2value_1[] = {
+	4,	/* cardNotPresent(100) */
+	6,	/* cardTransmissionError(102) */
+	5,	/* cardUnresponsive(101) */
+	2,	/* illegalBankId(2) */
+	1,	/* illegalClientId(1) */
+	3,	/* illegalSlotId(3) */
+	0	/* ok(0) */
+	/* This list is extensible */
+};
+static const asn_INTEGER_specifics_t asn_SPC_ResultCode_specs_1 = {
+	asn_MAP_ResultCode_value2enum_1,	/* "tag" => N; sorted by tag */
+	asn_MAP_ResultCode_enum2value_1,	/* N => "tag"; sorted by N */
+	7,	/* Number of elements in the maps */
+	8,	/* Extensions before this member */
+	1,	/* Strict enumeration */
+	0,	/* Native long size */
+	0
+};
+static const ber_tlv_tag_t asn_DEF_ResultCode_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ResultCode = {
+	"ResultCode",
+	"ResultCode",
+	ResultCode_free,
+	ResultCode_print,
+	ResultCode_constraint,
+	ResultCode_decode_ber,
+	ResultCode_encode_der,
+	ResultCode_decode_xer,
+	ResultCode_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_ResultCode_tags_1,
+	sizeof(asn_DEF_ResultCode_tags_1)
+		/sizeof(asn_DEF_ResultCode_tags_1[0]), /* 1 */
+	asn_DEF_ResultCode_tags_1,	/* Same as above */
+	sizeof(asn_DEF_ResultCode_tags_1)
+		/sizeof(asn_DEF_ResultCode_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* Defined elsewhere */
+	&asn_SPC_ResultCode_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/RsproPDU.c b/src/rspro/RsproPDU.c
new file mode 100644
index 0000000..2aa0862
--- /dev/null
+++ b/src/rspro/RsproPDU.c
@@ -0,0 +1,122 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/RsproPDU.h>
+
+static int
+memb_version_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 32l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+static int asn_DFL_2_set_1(int set_value, void **sptr) {
+	long *st = *sptr;
+	
+	if(!st) {
+		if(!set_value) return -1;	/* Not a default value */
+		st = (*sptr = CALLOC(1, sizeof(*st)));
+		if(!st) return -1;
+	}
+	
+	if(set_value) {
+		/* Install default value 1 */
+		*st = 1l;
+		return 0;
+	} else {
+		/* Test default value 1 */
+		return (*st == 1);
+	}
+}
+static asn_TYPE_member_t asn_MBR_RsproPDU_1[] = {
+	{ ATF_POINTER, 1, offsetof(struct RsproPDU, version),
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_NativeInteger,
+		memb_version_constraint_1,
+		0,	/* PER is not compiled, use -gen-PER */
+		asn_DFL_2_set_1,	/* DEFAULT 1 */
+		"version"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDU, tag),
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_OperationTag,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"tag"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDU, msg),
+		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		+1,	/* EXPLICIT tag at current level */
+		&asn_DEF_RsproPDUchoice,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"msg"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_RsproPDU_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_RsproPDU_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* version */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* tag */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* msg */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_RsproPDU_specs_1 = {
+	sizeof(struct RsproPDU),
+	offsetof(struct RsproPDU, _asn_ctx),
+	asn_MAP_RsproPDU_tag2el_1,
+	3,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	-1,	/* Start extensions */
+	-1	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_RsproPDU = {
+	"RsproPDU",
+	"RsproPDU",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_RsproPDU_tags_1,
+	sizeof(asn_DEF_RsproPDU_tags_1)
+		/sizeof(asn_DEF_RsproPDU_tags_1[0]), /* 1 */
+	asn_DEF_RsproPDU_tags_1,	/* Same as above */
+	sizeof(asn_DEF_RsproPDU_tags_1)
+		/sizeof(asn_DEF_RsproPDU_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_RsproPDU_1,
+	3,	/* Elements count */
+	&asn_SPC_RsproPDU_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/RsproPDUchoice.c b/src/rspro/RsproPDUchoice.c
new file mode 100644
index 0000000..330821f
--- /dev/null
+++ b/src/rspro/RsproPDUchoice.c
@@ -0,0 +1,205 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/RsproPDUchoice.h>
+
+static asn_TYPE_member_t asn_MBR_RsproPDUchoice_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.connectBankReq),
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConnectBankReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"connectBankReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.connectBankRes),
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConnectBankRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"connectBankRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.connectClientReq),
+		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConnectClientReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"connectClientReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.connectClientRes),
+		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConnectClientRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"connectClientRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.createMappingReq),
+		(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_CreateMappingReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"createMappingReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.createMappingRes),
+		(ASN_TAG_CLASS_CONTEXT | (5 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_CreateMappingRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"createMappingRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.removeMappingReq),
+		(ASN_TAG_CLASS_CONTEXT | (6 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_RemoveMappingReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"removeMappingReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.removeMappingRes),
+		(ASN_TAG_CLASS_CONTEXT | (7 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_RemoveMappingRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"removeMappingRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.configClientReq),
+		(ASN_TAG_CLASS_CONTEXT | (8 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConfigClientReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"configClientReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.configClientRes),
+		(ASN_TAG_CLASS_CONTEXT | (9 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ConfigClientRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"configClientRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.setAtrReq),
+		(ASN_TAG_CLASS_CONTEXT | (10 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_SetAtrReq,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"setAtrReq"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.setAtrRes),
+		(ASN_TAG_CLASS_CONTEXT | (11 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_SetAtrRes,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"setAtrRes"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.tpduModemToCard),
+		(ASN_TAG_CLASS_CONTEXT | (12 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_TpduModemToCard,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"tpduModemToCard"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.tpduCardToModem),
+		(ASN_TAG_CLASS_CONTEXT | (13 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_TpduCardToModem,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"tpduCardToModem"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.clientSlotStatusInd),
+		(ASN_TAG_CLASS_CONTEXT | (14 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_ClientSlotStatusInd,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"clientSlotStatusInd"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct RsproPDUchoice, choice.bankSlotStatusInd),
+		(ASN_TAG_CLASS_CONTEXT | (15 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_BankSlotStatusInd,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"bankSlotStatusInd"
+		},
+};
+static const asn_TYPE_tag2member_t asn_MAP_RsproPDUchoice_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* connectBankReq */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* connectBankRes */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* connectClientReq */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* connectClientRes */
+    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 }, /* createMappingReq */
+    { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 }, /* createMappingRes */
+    { (ASN_TAG_CLASS_CONTEXT | (6 << 2)), 6, 0, 0 }, /* removeMappingReq */
+    { (ASN_TAG_CLASS_CONTEXT | (7 << 2)), 7, 0, 0 }, /* removeMappingRes */
+    { (ASN_TAG_CLASS_CONTEXT | (8 << 2)), 8, 0, 0 }, /* configClientReq */
+    { (ASN_TAG_CLASS_CONTEXT | (9 << 2)), 9, 0, 0 }, /* configClientRes */
+    { (ASN_TAG_CLASS_CONTEXT | (10 << 2)), 10, 0, 0 }, /* setAtrReq */
+    { (ASN_TAG_CLASS_CONTEXT | (11 << 2)), 11, 0, 0 }, /* setAtrRes */
+    { (ASN_TAG_CLASS_CONTEXT | (12 << 2)), 12, 0, 0 }, /* tpduModemToCard */
+    { (ASN_TAG_CLASS_CONTEXT | (13 << 2)), 13, 0, 0 }, /* tpduCardToModem */
+    { (ASN_TAG_CLASS_CONTEXT | (14 << 2)), 14, 0, 0 }, /* clientSlotStatusInd */
+    { (ASN_TAG_CLASS_CONTEXT | (15 << 2)), 15, 0, 0 } /* bankSlotStatusInd */
+};
+static asn_CHOICE_specifics_t asn_SPC_RsproPDUchoice_specs_1 = {
+	sizeof(struct RsproPDUchoice),
+	offsetof(struct RsproPDUchoice, _asn_ctx),
+	offsetof(struct RsproPDUchoice, present),
+	sizeof(((struct RsproPDUchoice *)0)->present),
+	asn_MAP_RsproPDUchoice_tag2el_1,
+	16,	/* Count of tags in the map */
+	0,
+	16	/* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_RsproPDUchoice = {
+	"RsproPDUchoice",
+	"RsproPDUchoice",
+	CHOICE_free,
+	CHOICE_print,
+	CHOICE_constraint,
+	CHOICE_decode_ber,
+	CHOICE_encode_der,
+	CHOICE_decode_xer,
+	CHOICE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	CHOICE_outmost_tag,
+	0,	/* No effective tags (pointer) */
+	0,	/* No effective tags (count) */
+	0,	/* No tags (pointer) */
+	0,	/* No tags (count) */
+	0,	/* No PER visible constraints */
+	asn_MBR_RsproPDUchoice_1,
+	16,	/* Elements count */
+	&asn_SPC_RsproPDUchoice_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/SetAtrReq.c b/src/rspro/SetAtrReq.c
new file mode 100644
index 0000000..213f353
--- /dev/null
+++ b/src/rspro/SetAtrReq.c
@@ -0,0 +1,69 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/SetAtrReq.h>
+
+static asn_TYPE_member_t asn_MBR_SetAtrReq_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct SetAtrReq, slot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"slot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct SetAtrReq, atr),
+		(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+		0,
+		&asn_DEF_ATR,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"atr"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_SetAtrReq_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_SetAtrReq_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* atr */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 0 } /* slot */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_SetAtrReq_specs_1 = {
+	sizeof(struct SetAtrReq),
+	offsetof(struct SetAtrReq, _asn_ctx),
+	asn_MAP_SetAtrReq_tag2el_1,
+	2,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	1,	/* Start extensions */
+	3	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_SetAtrReq = {
+	"SetAtrReq",
+	"SetAtrReq",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_SetAtrReq_tags_1,
+	sizeof(asn_DEF_SetAtrReq_tags_1)
+		/sizeof(asn_DEF_SetAtrReq_tags_1[0]), /* 1 */
+	asn_DEF_SetAtrReq_tags_1,	/* Same as above */
+	sizeof(asn_DEF_SetAtrReq_tags_1)
+		/sizeof(asn_DEF_SetAtrReq_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_SetAtrReq_1,
+	2,	/* Elements count */
+	&asn_SPC_SetAtrReq_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/SetAtrRes.c b/src/rspro/SetAtrRes.c
new file mode 100644
index 0000000..8dc3652
--- /dev/null
+++ b/src/rspro/SetAtrRes.c
@@ -0,0 +1,59 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/SetAtrRes.h>
+
+static asn_TYPE_member_t asn_MBR_SetAtrRes_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct SetAtrRes, result),
+		(ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
+		0,
+		&asn_DEF_ResultCode,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"result"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_SetAtrRes_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_SetAtrRes_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* result */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_SetAtrRes_specs_1 = {
+	sizeof(struct SetAtrRes),
+	offsetof(struct SetAtrRes, _asn_ctx),
+	asn_MAP_SetAtrRes_tag2el_1,
+	1,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	0,	/* Start extensions */
+	2	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_SetAtrRes = {
+	"SetAtrRes",
+	"SetAtrRes",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_SetAtrRes_tags_1,
+	sizeof(asn_DEF_SetAtrRes_tags_1)
+		/sizeof(asn_DEF_SetAtrRes_tags_1[0]), /* 1 */
+	asn_DEF_SetAtrRes_tags_1,	/* Same as above */
+	sizeof(asn_DEF_SetAtrRes_tags_1)
+		/sizeof(asn_DEF_SetAtrRes_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_SetAtrRes_1,
+	1,	/* Elements count */
+	&asn_SPC_SetAtrRes_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/SlotNumber.c b/src/rspro/SlotNumber.c
new file mode 100644
index 0000000..4824169
--- /dev/null
+++ b/src/rspro/SlotNumber.c
@@ -0,0 +1,128 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/SlotNumber.h>
+
+int
+SlotNumber_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	long value;
+	
+	if(!sptr) {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+	
+	value = *(const long *)sptr;
+	
+	if((value >= 0l && value <= 1023l)) {
+		/* Constraint check succeeded */
+		return 0;
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: constraint failed (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+}
+
+/*
+ * This type is implemented using NativeInteger,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+SlotNumber_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
+	td->aper_decoder   = asn_DEF_NativeInteger.aper_decoder;
+	td->aper_encoder   = asn_DEF_NativeInteger.aper_encoder;
+	if(!td->per_constraints)
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+	td->specifics      = asn_DEF_NativeInteger.specifics;
+}
+
+void
+SlotNumber_free(asn_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+SlotNumber_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+SlotNumber_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const void *bufptr, size_t size, int tag_mode) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+SlotNumber_encode_der(asn_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+SlotNumber_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+SlotNumber_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+		int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	SlotNumber_1_inherit_TYPE_descriptor(td);
+	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static const ber_tlv_tag_t asn_DEF_SlotNumber_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_SlotNumber = {
+	"SlotNumber",
+	"SlotNumber",
+	SlotNumber_free,
+	SlotNumber_print,
+	SlotNumber_constraint,
+	SlotNumber_decode_ber,
+	SlotNumber_encode_der,
+	SlotNumber_decode_xer,
+	SlotNumber_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_SlotNumber_tags_1,
+	sizeof(asn_DEF_SlotNumber_tags_1)
+		/sizeof(asn_DEF_SlotNumber_tags_1[0]), /* 1 */
+	asn_DEF_SlotNumber_tags_1,	/* Same as above */
+	sizeof(asn_DEF_SlotNumber_tags_1)
+		/sizeof(asn_DEF_SlotNumber_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
diff --git a/src/rspro/SlotPhysStatus.c b/src/rspro/SlotPhysStatus.c
new file mode 100644
index 0000000..1f1387a
--- /dev/null
+++ b/src/rspro/SlotPhysStatus.c
@@ -0,0 +1,89 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/SlotPhysStatus.h>
+
+static asn_TYPE_member_t asn_MBR_SlotPhysStatus_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct SlotPhysStatus, resetActive),
+		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"resetActive"
+		},
+	{ ATF_POINTER, 3, offsetof(struct SlotPhysStatus, vccPresent),
+		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"vccPresent"
+		},
+	{ ATF_POINTER, 2, offsetof(struct SlotPhysStatus, clkActive),
+		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"clkActive"
+		},
+	{ ATF_POINTER, 1, offsetof(struct SlotPhysStatus, cardPresent),
+		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+		-1,	/* IMPLICIT tag at current level */
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"cardPresent"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_SlotPhysStatus_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_SlotPhysStatus_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* resetActive */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* vccPresent */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* clkActive */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 } /* cardPresent */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_SlotPhysStatus_specs_1 = {
+	sizeof(struct SlotPhysStatus),
+	offsetof(struct SlotPhysStatus, _asn_ctx),
+	asn_MAP_SlotPhysStatus_tag2el_1,
+	4,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	3,	/* Start extensions */
+	5	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_SlotPhysStatus = {
+	"SlotPhysStatus",
+	"SlotPhysStatus",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_SlotPhysStatus_tags_1,
+	sizeof(asn_DEF_SlotPhysStatus_tags_1)
+		/sizeof(asn_DEF_SlotPhysStatus_tags_1[0]), /* 1 */
+	asn_DEF_SlotPhysStatus_tags_1,	/* Same as above */
+	sizeof(asn_DEF_SlotPhysStatus_tags_1)
+		/sizeof(asn_DEF_SlotPhysStatus_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_SlotPhysStatus_1,
+	4,	/* Elements count */
+	&asn_SPC_SlotPhysStatus_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/TpduCardToModem.c b/src/rspro/TpduCardToModem.c
new file mode 100644
index 0000000..883d937
--- /dev/null
+++ b/src/rspro/TpduCardToModem.c
@@ -0,0 +1,89 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/TpduCardToModem.h>
+
+static asn_TYPE_member_t asn_MBR_TpduCardToModem_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduCardToModem, fromBankSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"fromBankSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduCardToModem, toClientSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"toClientSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduCardToModem, flags),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_TpduFlags,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"flags"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduCardToModem, data),
+		(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+		0,
+		&asn_DEF_OCTET_STRING,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"data"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_TpduCardToModem_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_TpduCardToModem_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, 0, 0 }, /* data */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 2 }, /* fromBankSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 1 }, /* toClientSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 2, -2, 0 } /* flags */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_TpduCardToModem_specs_1 = {
+	sizeof(struct TpduCardToModem),
+	offsetof(struct TpduCardToModem, _asn_ctx),
+	asn_MAP_TpduCardToModem_tag2el_1,
+	4,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	3,	/* Start extensions */
+	5	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_TpduCardToModem = {
+	"TpduCardToModem",
+	"TpduCardToModem",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_TpduCardToModem_tags_1,
+	sizeof(asn_DEF_TpduCardToModem_tags_1)
+		/sizeof(asn_DEF_TpduCardToModem_tags_1[0]), /* 1 */
+	asn_DEF_TpduCardToModem_tags_1,	/* Same as above */
+	sizeof(asn_DEF_TpduCardToModem_tags_1)
+		/sizeof(asn_DEF_TpduCardToModem_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_TpduCardToModem_1,
+	4,	/* Elements count */
+	&asn_SPC_TpduCardToModem_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/TpduFlags.c b/src/rspro/TpduFlags.c
new file mode 100644
index 0000000..a43ec7a
--- /dev/null
+++ b/src/rspro/TpduFlags.c
@@ -0,0 +1,89 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/TpduFlags.h>
+
+static asn_TYPE_member_t asn_MBR_TpduFlags_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduFlags, tpduHeaderPresent),
+		(ASN_TAG_CLASS_UNIVERSAL | (1 << 2)),
+		0,
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"tpduHeaderPresent"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduFlags, finalPart),
+		(ASN_TAG_CLASS_UNIVERSAL | (1 << 2)),
+		0,
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"finalPart"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduFlags, procByteContinueTx),
+		(ASN_TAG_CLASS_UNIVERSAL | (1 << 2)),
+		0,
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"procByteContinueTx"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduFlags, procByteContinueRx),
+		(ASN_TAG_CLASS_UNIVERSAL | (1 << 2)),
+		0,
+		&asn_DEF_BOOLEAN,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"procByteContinueRx"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_TpduFlags_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_TpduFlags_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 0, 0, 3 }, /* tpduHeaderPresent */
+    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 1, -1, 2 }, /* finalPart */
+    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 2, -2, 1 }, /* procByteContinueTx */
+    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 3, -3, 0 } /* procByteContinueRx */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_TpduFlags_specs_1 = {
+	sizeof(struct TpduFlags),
+	offsetof(struct TpduFlags, _asn_ctx),
+	asn_MAP_TpduFlags_tag2el_1,
+	4,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	3,	/* Start extensions */
+	5	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_TpduFlags = {
+	"TpduFlags",
+	"TpduFlags",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_TpduFlags_tags_1,
+	sizeof(asn_DEF_TpduFlags_tags_1)
+		/sizeof(asn_DEF_TpduFlags_tags_1[0]), /* 1 */
+	asn_DEF_TpduFlags_tags_1,	/* Same as above */
+	sizeof(asn_DEF_TpduFlags_tags_1)
+		/sizeof(asn_DEF_TpduFlags_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_TpduFlags_1,
+	4,	/* Elements count */
+	&asn_SPC_TpduFlags_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro/TpduModemToCard.c b/src/rspro/TpduModemToCard.c
new file mode 100644
index 0000000..8accb1d
--- /dev/null
+++ b/src/rspro/TpduModemToCard.c
@@ -0,0 +1,89 @@
+/*
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
+ * From ASN.1 module "RSPRO"
+ * 	found in "../../asn1/RSPRO.asn"
+ */
+
+#include <osmocom/rspro/TpduModemToCard.h>
+
+static asn_TYPE_member_t asn_MBR_TpduModemToCard_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduModemToCard, fromClientSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_ClientSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"fromClientSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduModemToCard, toBankSlot),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_BankSlot,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"toBankSlot"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduModemToCard, flags),
+		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+		0,
+		&asn_DEF_TpduFlags,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"flags"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct TpduModemToCard, data),
+		(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+		0,
+		&asn_DEF_OCTET_STRING,
+		0,	/* Defer constraints checking to the member type */
+		0,	/* PER is not compiled, use -gen-PER */
+		0,
+		"data"
+		},
+};
+static const ber_tlv_tag_t asn_DEF_TpduModemToCard_tags_1[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_TpduModemToCard_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, 0, 0 }, /* data */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 2 }, /* fromClientSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 1 }, /* toBankSlot */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 2, -2, 0 } /* flags */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_TpduModemToCard_specs_1 = {
+	sizeof(struct TpduModemToCard),
+	offsetof(struct TpduModemToCard, _asn_ctx),
+	asn_MAP_TpduModemToCard_tag2el_1,
+	4,	/* Count of tags in the map */
+	0, 0, 0,	/* Optional elements (not needed) */
+	3,	/* Start extensions */
+	5	/* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_TpduModemToCard = {
+	"TpduModemToCard",
+	"TpduModemToCard",
+	SEQUENCE_free,
+	SEQUENCE_print,
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_decode_xer,
+	SEQUENCE_encode_xer,
+	0, 0,	/* No UPER support, use "-gen-PER" to enable */
+	0, 0,	/* No APER support, use "-gen-PER" to enable */
+	0,	/* Use generic outmost tag fetcher */
+	asn_DEF_TpduModemToCard_tags_1,
+	sizeof(asn_DEF_TpduModemToCard_tags_1)
+		/sizeof(asn_DEF_TpduModemToCard_tags_1[0]), /* 1 */
+	asn_DEF_TpduModemToCard_tags_1,	/* Same as above */
+	sizeof(asn_DEF_TpduModemToCard_tags_1)
+		/sizeof(asn_DEF_TpduModemToCard_tags_1[0]), /* 1 */
+	0,	/* No PER visible constraints */
+	asn_MBR_TpduModemToCard_1,
+	4,	/* Elements count */
+	&asn_SPC_TpduModemToCard_specs_1	/* Additional specs */
+};
+
diff --git a/src/rspro_util.c b/src/rspro_util.c
new file mode 100644
index 0000000..7a53859
--- /dev/null
+++ b/src/rspro_util.c
@@ -0,0 +1,156 @@
+
+
+#include <asn1c/asn_application.h>
+#include <asn1c/der_encoder.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/rspro/RsproPDU.h>
+
+struct msgb *rspro_msgb_alloc(void)
+{
+	return msgb_alloc_headroom(1024, 8, "RSPRO");
+}
+
+/*! BER-Encode an RSPRO message into  msgb. 
+ *  \param[in] pdu Structure describing RSPRO PDU. Is freed by this function on success
+ *  \returns callee-allocated message buffer containing encoded RSPRO PDU; NULL on error.
+ */
+struct msgb *rspro_enc_msg(RsproPDU_t *pdu)
+{
+	struct msgb *msg = rspro_msgb_alloc();
+	asn_enc_rval_t rval;
+
+	if (!msg)
+		return NULL;
+
+	rval = der_encode_to_buffer(&asn_DEF_RsproPDU, pdu, msgb_data(msg), msgb_length(msg));
+	if (rval.encoded < 0) {
+		return NULL;
+	}
+	msgb_put(msg, rval.encoded/8);
+
+	ASN_STRUCT_FREE(asn_DEF_RsproPDU, pdu);
+
+	return msg;
+}
+
+/* consumes 'msg' _if_ it is successful */
+RsproPDU_t *rspro_dec_msg(struct msgb *msg)
+{
+	RsproPDU_t *pdu;
+	asn_dec_rval_t rval;
+
+	rval = ber_decode(NULL, &asn_DEF_RsproPDU, (void **) &pdu, msgb_data(msg), msgb_length(msg));
+	if (rval.code != RC_OK) {
+		/* FIXME */
+		return NULL;
+	}
+
+	msgb_free(msg);
+
+	return pdu;
+}
+
+#define MAX_NAME_LEN 32
+struct app_comp_id {
+	char name[MAX_NAME_LEN+1];
+	char software[MAX_NAME_LEN+1];
+	char sw_version[MAX_NAME_LEN+1];
+	char hw_manufacturer[MAX_NAME_LEN+1];
+	char hw_model[MAX_NAME_LEN+1];
+	char hw_serial_nr[MAX_NAME_LEN+1];
+	char hw_version[MAX_NAME_LEN+1];
+	char fw_version[MAX_NAME_LEN+1];
+};
+
+static void fill_comp_id(ComponentIdentity_t *out, const struct app_comp_id *in)
+{
+	OCTET_STRING_fromString(&out->name, in->name);
+	OCTET_STRING_fromString(&out->software, in->software);
+	OCTET_STRING_fromString(&out->swVersion, in->sw_version);
+	if (strlen(in->hw_manufacturer))
+		out->hwManufacturer = OCTET_STRING_new_fromBuf(&asn_DEF_ComponentName,
+								in->hw_manufacturer, -1);
+	if (strlen(in->hw_model))
+		out->hwModel = OCTET_STRING_new_fromBuf(&asn_DEF_ComponentName, in->hw_model, -1);
+	if (strlen(in->hw_serial_nr))
+		out->hwSerialNr = OCTET_STRING_new_fromBuf(&asn_DEF_ComponentName, in->hw_serial_nr, -1);
+	if (strlen(in->hw_version))
+		out->hwVersion = OCTET_STRING_new_fromBuf(&asn_DEF_ComponentName, in->hw_version, -1);
+	if (strlen(in->fw_version))
+		out->fwVersion = OCTET_STRING_new_fromBuf(&asn_DEF_ComponentName, in->fw_version, -1);
+}
+
+static void fill_ip4_port(IpPort_t *out, uint32_t ip, uint16_t port)
+{
+	uint32_t ip_n = htonl(ip);
+	out->ip.present = IpAddress_PR_ipv4;
+	OCTET_STRING_fromBuf(&out->ip.choice.ipv4, (const char *) &ip_n, 4);
+	out->port = htons(port);
+}
+
+
+RsproPDU_t *rspro_gen_ConnectBankReq(const struct app_comp_id *a_cid,
+					uint16_t bank_id, uint16_t num_slots)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->msg.present = RsproPDUchoice_PR_connectBankReq;
+	fill_comp_id(&pdu->msg.choice.connectBankReq.identity, a_cid);
+	pdu->msg.choice.connectBankReq.bankId = bank_id;
+	pdu->msg.choice.connectBankReq.numberOfSlots = num_slots;
+
+	return pdu;
+}
+
+RsproPDU_t *rspro_gen_ConnectClientReq(const struct app_comp_id *a_cid)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->msg.present = RsproPDUchoice_PR_connectClientReq;
+	fill_comp_id(&pdu->msg.choice.connectClientReq.identity, a_cid);
+
+	return pdu;
+}
+
+RsproPDU_t *rspro_gen_CreateMappingReq(const ClientSlot_t *client, const BankSlot_t *bank)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->msg.present = RsproPDUchoice_PR_createMappingReq;
+	pdu->msg.choice.createMappingReq.client = *client;
+	pdu->msg.choice.createMappingReq.bank = *bank;
+
+	return pdu;
+}
+
+RsproPDU_t *rspro_gen_ConfigClientReq(uint16_t client_id, uint32_t ip, uint16_t port)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->msg.present = RsproPDUchoice_PR_configClientReq;
+	pdu->msg.choice.configClientReq.clientId = client_id;
+	fill_ip4_port(&pdu->msg.choice.configClientReq.bankd, ip, port);
+
+	return pdu;
+}
+
+RsproPDU_t *rspro_gen_SetAtrReq(uint16_t client_id, uint16_t slot_nr, const uint8_t *atr,
+				unsigned int atr_len)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->msg.present = RsproPDUchoice_PR_setAtrReq;
+	pdu->msg.choice.setAtrReq.slot.clientId = client_id;
+	pdu->msg.choice.setAtrReq.slot.slotNr = slot_nr;
+	OCTET_STRING_fromBuf(&pdu->msg.choice.setAtrReq.atr, (const char *)atr, atr_len);
+
+	return pdu;
+}
+
+