aboutsummaryrefslogtreecommitdiffstats
path: root/src/hnbgw_hnbap.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2015-08-30 16:57:53 +0200
committerHarald Welte <laforge@gnumonks.org>2015-08-30 16:57:53 +0200
commitee77cff224bd414aee47142d9af6f998b1ee66d1 (patch)
treec103ff2533f6eb1300b125587ac53e7636ab0dab /src/hnbgw_hnbap.c
parentc3fa0b0e4338cd6df4586ba77eea0f7e7ad17c0f (diff)
hnbgw: Actually link in + call ffasn1c runtime library
Diffstat (limited to 'src/hnbgw_hnbap.c')
-rw-r--r--src/hnbgw_hnbap.c83
1 files changed, 81 insertions, 2 deletions
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 8d9e1c8..9db670e 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -2,6 +2,7 @@
#include <osmocom/core/utils.h>
#include <unistd.h>
+#include <errno.h>
#include <string.h>
#include "asn1helpers.h"
@@ -10,6 +11,49 @@
#include "hnbgw.h"
#include "hnbap_const.h"
+#define IU_MSG_NUM_IES 32
+#define IU_MSG_NUM_EXT_IES 32
+
+/* common structure of a HNBAP / RUA / RANAP message, must have identical
+ * memory footprint as the other messages, such as HNBRegisterRequest */
+struct iu_common_msg {
+ ProtocolIE_Container_1 protocolIEs;
+ BOOL protocolExtensions_option;
+ ProtocolIE_Container_1 protocolExtensions;
+};
+
+/* Add an IE to a Iu message
+ * \param _msg Message to which we want to add
+ * \param[in] ie Information Element to be added (ffasn1c generated struct)
+ * \param[in] iei Information Element Identifier
+ * \param[in] type asn1_type of the IE
+ * \param[in] ext should this be an extension field?
+ */
+int iu_msg_add_ie(void *_msg, void *ie, int iei, ASN1CType *type, int ext)
+{
+ struct iu_common_msg *msg = _msg;
+ ProtocolIE_Field_1 *field;
+
+ if (ext) {
+ msg->protocolExtensions_option = TRUE;
+ if (msg->protocolExtensions.count >= IU_MSG_NUM_EXT_IES)
+ return -ERANGE;
+ field = &msg->protocolExtensions.tab[msg->protocolExtensions.count++];
+ } else {
+ if (msg->protocolIEs.count >= IU_MSG_NUM_IES)
+ return -ERANGE;
+ field = &msg->protocolIEs.tab[msg->protocolIEs.count++];
+ }
+
+ field->id = iei;
+ //field->criticality = FIXME;
+ field->value.type = type;
+ field->value.u.data = ie;
+
+ return 0;
+}
+
+
static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
{
@@ -24,16 +68,34 @@ static int hnbgw_tx_hnb_register_acc()
static int hnbgw_tx_ue_register_acc()
{
+#if 0
+ HNBAP_PDU pdu;
+ HNBRegisterAccept hnb_reg_acc;
+
+ hnb_reg_acc.protocol_IEs
+
+ pdu.choice = HNBAP_PDU_successfulOutcome;
+ pdu.u.successfulOutcome.procedureCode = HNBAP_PC_HNBRegister;
+ pdu.u.successfulOutcome.criticality = ;
+ pdu.u.successfulOutcome.value.type = asn1_type_HNBRegisterAccept;
+ pdu.u.successfulOutcome.value.u.data = &hnb_reg_acc;
+#endif
/* FIXME */
/* Single required response IE: RNC-ID */
}
+/* we type-cast to ProtocolIE_Container_1, as all the containers structs have
+ * the same definiition. This is of course ugly, but I see no cleaner way.
+ * Similarly, from the IEI it is clear what the type should be, but in a
+ * statically typed language we can only return 'void *' and hope the caller
+ * doesn the right typecast. */
#define FIND_IE(cont, id) find_ie((const struct ProtocolIE_Container_1 *)cont, id)
-
static void *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
{
int i;
+ /* iterate over the array of IEs in the IE container and look for the first
+ * occurrence of the right IEI */
for (i = 0; i < cont->count; i++) {
ProtocolIE_Field_1 *field = &cont->tab[i];
if (field->id == id) {
@@ -73,6 +135,8 @@ static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegister
//ctx->id.mcc FIXME
//ctx->id.mnc FIXME
+ DEBUGP(DMAIN, "HNB-REGISTER-REQ from %s\n", ctx->identity_info);
+
/* FIXME: Send HNBRegisterAccept */
}
@@ -156,7 +220,22 @@ static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu)
int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg)
{
- /* FIXME: decode and handle to _hnbgw_hnbap_rx() */
+ HNBAP_PDU *pdu;
+ ASN1Error err;
+ int rc;
+
+ /* decode and handle to _hnbgw_hnbap_rx() */
+
+ rc = asn1_aper_decode(&pdu, asn1_type_HNBAP_PDU, msg->data, msgb_length(msg), &err);
+ if (rc < 0) {
+ LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode (bit=%d): %s\n", err.bit_pos, err.msg);
+ return rc;
+ }
+
+ rc = _hnbgw_hnbap_rx(hnb, pdu);
+ asn1_free_value(asn1_type_HNBAP_PDU, pdu);
+
+ return rc;
}