Change in osmo-hnodeb[master]: Move protocol related code in main.c to related proto files

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Tue Nov 2 12:00:35 UTC 2021


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnodeb/+/26002 )

Change subject: Move protocol related code in main.c to related proto files
......................................................................

Move protocol related code in main.c to related proto files

Change-Id: I771b3d3f61207137477eed2b316a5f670fb79ef2
---
M include/osmocom/hnodeb/Makefile.am
M include/osmocom/hnodeb/hnodeb.h
A include/osmocom/hnodeb/nas.h
M include/osmocom/hnodeb/ranap.h
M include/osmocom/hnodeb/rua.h
M src/osmo-hnodeb/Makefile.am
M src/osmo-hnodeb/main.c
A src/osmo-hnodeb/nas.c
M src/osmo-hnodeb/ranap.c
M src/osmo-hnodeb/rua.c
M src/osmo-hnodeb/vty.c
11 files changed, 389 insertions(+), 339 deletions(-)

Approvals:
  pespin: Looks good to me, approved; Verified
  fixeria: Looks good to me, but someone else must approve
  laforge: Looks good to me, but someone else must approve



diff --git a/include/osmocom/hnodeb/Makefile.am b/include/osmocom/hnodeb/Makefile.am
index f6c91b4..197568c 100644
--- a/include/osmocom/hnodeb/Makefile.am
+++ b/include/osmocom/hnodeb/Makefile.am
@@ -1,6 +1,7 @@
 noinst_HEADERS = \
 	hnbap.h \
 	hnodeb.h \
+	nas.h \
 	ranap.h \
 	rua.h \
 	vty.h \
diff --git a/include/osmocom/hnodeb/hnodeb.h b/include/osmocom/hnodeb/hnodeb.h
index 261fc3a..50432d1 100644
--- a/include/osmocom/hnodeb/hnodeb.h
+++ b/include/osmocom/hnodeb/hnodeb.h
@@ -100,12 +100,5 @@
 struct hnb *hnb_alloc(void *tall_ctx);
 int hnb_connect(struct hnb *hnb);
 
-void hnb_rx_iu_release(struct hnb *hnb);
-void hnb_rx_paging(struct hnb *hnb, const char *imsi);
-void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len);
-void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg);
-
-struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi);
-
 extern void *tall_hnb_ctx;
 extern struct hnb *g_hnb;
diff --git a/include/osmocom/hnodeb/nas.h b/include/osmocom/hnodeb/nas.h
new file mode 100644
index 0000000..f6a7976
--- /dev/null
+++ b/include/osmocom/hnodeb/nas.h
@@ -0,0 +1,24 @@
+/* (C) 2015 by Daniel Willmann <dwillmann at sysmocom.de>
+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/lienses/>.
+ *
+ */
+
+#pragma once
+
+struct hnb;
+void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len);
diff --git a/include/osmocom/hnodeb/ranap.h b/include/osmocom/hnodeb/ranap.h
index f68006f..df756b1 100644
--- a/include/osmocom/hnodeb/ranap.h
+++ b/include/osmocom/hnodeb/ranap.h
@@ -19,8 +19,15 @@
  */
 #pragma once
 
+struct hnb;
 struct ranap_message_s;
 #include <osmocom/hnodeb/hnodeb.h>
 
+void hnb_rx_iu_release(struct hnb *hnb);
+void hnb_rx_paging(struct hnb *hnb, const char *imsi);
+void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg);
+
 void hnb_rua_dt_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg);
 void hnb_rua_cl_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg);
+void hnb_tx_iu_release_req(struct hnb *hnb);
+struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi);
diff --git a/include/osmocom/hnodeb/rua.h b/include/osmocom/hnodeb/rua.h
index 9d7cc12..52221be 100644
--- a/include/osmocom/hnodeb/rua.h
+++ b/include/osmocom/hnodeb/rua.h
@@ -22,5 +22,7 @@
 #include <asn1c/ANY.h>
 
 struct hnb;
+struct msgb;
 
 int hnb_rua_rx(struct hnb *hnb, struct msgb *msg);
+int hnb_tx_dt(struct hnb *hnb, struct msgb *txm);
diff --git a/src/osmo-hnodeb/Makefile.am b/src/osmo-hnodeb/Makefile.am
index 7353cd8..139b6b0 100644
--- a/src/osmo-hnodeb/Makefile.am
+++ b/src/osmo-hnodeb/Makefile.am
@@ -33,6 +33,7 @@
 	debug.c \
 	hnbap.c \
 	hnb.c \
+	nas.c \
 	ranap.c \
 	rua.c \
 	vty.c \
diff --git a/src/osmo-hnodeb/main.c b/src/osmo-hnodeb/main.c
index dc662aa..9c7a548 100644
--- a/src/osmo-hnodeb/main.c
+++ b/src/osmo-hnodeb/main.c
@@ -33,28 +33,12 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/logging.h>
 #include <osmocom/core/msgb.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm48.h>
 
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
 #include <osmocom/vty/command.h>
 
-#include <osmocom/crypt/auth.h>
-
-#include <osmocom/rua/rua_msg_factory.h>
-#include <osmocom/ranap/iu_helpers.h>
-
-#include <osmocom/ranap/ranap_msg_factory.h>
-
-#include <osmocom/rua/RUA_RUA-PDU.h>
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#include <osmocom/ranap/RANAP_ProcedureCode.h>
-#include <osmocom/ranap/RANAP_Criticality.h>
-#include <osmocom/ranap/RANAP_DirectTransfer.h>
-#include <osmocom/ranap/ranap_common.h>
+#include <osmocom/ranap/ranap_common.h> /* ranap_set_log_area() */
 
 #include <osmocom/hnodeb/hnbap.h>
 #include <osmocom/hnodeb/rua.h>
@@ -65,326 +49,11 @@
 void *tall_hnb_ctx;
 struct hnb *g_hnb;
 
-struct msgb *rua_new_udt(struct msgb *inmsg);
-
-static struct msgb *gen_nas_id_resp()
-{
-	uint8_t id_resp[] = {
-		GSM48_PDISC_MM,
-		GSM48_MT_MM_ID_RESP,
-		/* IMEISV */
-		0x09, /* len */
-		0x03, /* first digit (0000) + even (0) + id IMEISV (011) */
-		0x31, 0x91, 0x06, 0x00, 0x28, 0x47, 0x11, /* digits */
-		0xf2, /* filler (1111) + last digit (0010) */
-	};
-
-	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
-}
-
-static struct msgb *gen_nas_tmsi_realloc_compl()
-{
-	uint8_t id_resp[] = {
-		GSM48_PDISC_MM,
-		GSM48_MT_MM_TMSI_REALL_COMPL,
-	};
-
-	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
-}
-
-static struct msgb *gen_nas_auth_resp(uint8_t *sres)
-{
-	uint8_t id_resp[] = {
-		GSM48_PDISC_MM,
-		0x80 | GSM48_MT_MM_AUTH_RESP, /* simulate sequence nr 2 */
-		0x61, 0xb5, 0x69, 0xf5 /* hardcoded SRES */
-	};
-
-	memcpy(id_resp + 2, sres, 4);
-
-	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
-}
-
-static int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)
-{
-	struct hnb_chan *chan;
-	struct msgb *rua;
-
-	chan = hnb->cs.chan;
-	if (!chan) {
-		printf("hnb_nas_tx_tmsi_realloc_compl(): No CS channel established yet.\n");
-		return -1;
-	}
-
-	rua = rua_new_dt(chan->is_ps, chan->conn_id, txm);
-	osmo_wqueue_enqueue(&hnb->wqueue, rua);
-	return 0;
-}
-
-static struct tlv_parsed *parse_mm(struct gsm48_hdr *gh, int len)
-{
-	static struct tlv_parsed tp;
-	int parse_res;
-
-	len -= (const char *)&gh->data[0] - (const char *)gh;
-
-	OSMO_ASSERT(gsm48_hdr_pdisc(gh) == GSM48_PDISC_MM);
-
-	parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);
-	if (parse_res <= 0) {
-		uint8_t msg_type = gsm48_hdr_msg_type(gh);
-		printf("Error parsing MM message 0x%hhx: %d\n", msg_type, parse_res);
-		return NULL;
-	}
-
-	return &tp;
-}
-
-int hnb_nas_rx_lu_accept(struct gsm48_hdr *gh, int len, int *sent_tmsi)
-{
-	printf(" :D Location Update Accept :D\n");
-	struct gsm48_loc_area_id *lai;
-
-	lai = (struct gsm48_loc_area_id *)&gh->data[0];
-
-	struct osmo_location_area_id laid;
-	gsm48_decode_lai2(lai, &laid);
-	printf("LU: mcc %s  mnc %s  lac %hd\n",
-	       osmo_mcc_name(laid.plmn.mcc), osmo_mnc_name(laid.plmn.mnc, laid.plmn.mnc_3_digits),
-	       laid.lac);
-
-	struct tlv_parsed tp;
-	int parse_res;
-
-	len -= (const char *)&gh->data[0] - (const char *)gh;
-	parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);
-	if (parse_res <= 0) {
-		printf("Error parsing Location Update Accept message: %d\n", parse_res);
-		return -1;
-	}
-
-	if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
-		uint8_t type = TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)[0] & 0x0f;
-		if (type == GSM_MI_TYPE_TMSI)
-			*sent_tmsi = 1;
-		else *sent_tmsi = 0;
-	}
-	return 0;
-}
-
-void hnb_nas_rx_mm_info(struct gsm48_hdr *gh, int len)
-{
-	printf(" :) MM Info :)\n");
-	struct tlv_parsed *tp = parse_mm(gh, len);
-	if (!tp)
-		return;
-
-	if (TLVP_PRESENT(tp, GSM48_IE_NAME_SHORT)) {
-		char name[128] = {0};
-		gsm_7bit_decode_n(name, 127,
-				  TLVP_VAL(tp, GSM48_IE_NAME_SHORT)+1,
-				  (TLVP_LEN(tp, GSM48_IE_NAME_SHORT)-1)*8/7);
-		printf("Info: Short Network Name: %s\n", name);
-	}
-
-	if (TLVP_PRESENT(tp, GSM48_IE_NAME_LONG)) {
-		char name[128] = {0};
-		gsm_7bit_decode_n(name, 127,
-				  TLVP_VAL(tp, GSM48_IE_NAME_LONG)+1,
-				  (TLVP_LEN(tp, GSM48_IE_NAME_LONG)-1)*8/7);
-		printf("Info: Long Network Name: %s\n", name);
-	}
-}
-
-static int hnb_nas_rx_auth_req(struct hnb *hnb, struct gsm48_hdr *gh,
-				    int len)
-{
-	struct gsm48_auth_req *ar;
-
-	len -= (const char *)&gh->data[0] - (const char *)gh;
-
-	if (len < sizeof(*ar)) {
-		printf("GSM48 Auth Req does not fit.\n");
-		return -1;
-	}
-
-	printf(" :) Authentication Request :)\n");
-
-	ar = (struct gsm48_auth_req*) &gh->data[0];
-	int seq = ar->key_seq;
-
-	/* Generate SRES from *HARDCODED* Ki for Iuh testing */
-	struct osmo_auth_vector vec;
-	/* Ki 000102030405060708090a0b0c0d0e0f */
-	struct osmo_sub_auth_data auth = {
-		.type	= OSMO_AUTH_TYPE_GSM,
-		.algo	= OSMO_AUTH_ALG_COMP128v1,
-		.u.gsm.ki = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-			0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
-			0x0e, 0x0f
-		},
-	};
-
-	memset(&vec, 0, sizeof(vec));
-	osmo_auth_gen_vec(&vec, &auth, ar->rand);
-
-	printf("seq %d rand %s",
-	       seq, osmo_hexdump(ar->rand, sizeof(ar->rand)));
-	printf(" --> sres %s\n",
-	       osmo_hexdump(vec.sres, 4));
-
-	return hnb_tx_dt(hnb, gen_nas_auth_resp(vec.sres));
-}
-
-void hnb_tx_iu_release_req(struct hnb *hnb)
-{
-	RANAP_Cause_t cause = {
-		.present = RANAP_Cause_PR_radioNetwork,
-		.choice.transmissionNetwork = RANAP_CauseRadioNetwork_release_due_to_UE_generated_signalling_connection_release,
-	};
-	hnb_tx_dt(hnb, ranap_new_msg_iu_rel_req(&cause));
-}
-
-void hnb_tx_iu_release_compl(struct hnb *hnb)
-{
-	hnb_tx_dt(hnb, ranap_new_msg_iu_rel_compl());
-}
-
-static int hnb_nas_rx_mm(struct hnb *hnb, struct gsm48_hdr *gh, int len)
-{
-	struct hnb_chan *chan;
-
-	chan = hnb->cs.chan;
-	if (!chan) {
-		printf("hnb_nas_rx_mm(): No CS channel established yet.\n");
-		return -1;
-	}
-
-	OSMO_ASSERT(!chan->is_ps);
-
-	uint8_t msg_type = gsm48_hdr_msg_type(gh);
-	int sent_tmsi;
-
-	switch (msg_type) {
-	case GSM48_MT_MM_ID_REQ:
-		return hnb_tx_dt(hnb, gen_nas_id_resp());
-
-	case GSM48_MT_MM_LOC_UPD_ACCEPT:
-		if (hnb_nas_rx_lu_accept(gh, len, &sent_tmsi))
-			return -1;
-		if (sent_tmsi)
-			return hnb_tx_dt(hnb, gen_nas_tmsi_realloc_compl());
-		else
-			return 0;
-
-	case GSM48_MT_MM_LOC_UPD_REJECT:
-		printf("Received Location Update Reject\n");
-		return 0;
-
-	case GSM48_MT_MM_INFO:
-		hnb_nas_rx_mm_info(gh, len);
-		hnb_tx_iu_release_req(hnb);
-		return 0;
-
-	case GSM48_MT_MM_AUTH_REQ:
-		return hnb_nas_rx_auth_req(hnb, gh, len);
-
-	default:
-		printf("04.08 message type not handled by hnb-test: 0x%x\n",
-		       msg_type);
-		return 0;
-	}
-
-}
-
-void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len)
-{
-	int rc;
-	printf("got %d bytes: %s\n", len, osmo_hexdump(data, len));
-
-	// nas_pdu == '05 08 12' ==> IMEI Identity request
-	//            '05 04 0d' ==> LU reject
-
-	struct gsm48_hdr *gh = data;
-	if (len < sizeof(*gh)) {
-		printf("hnb_nas_rx_dtap(): NAS PDU is too short: %d. Ignoring.\n",
-		       len);
-		return;
-	}
-	uint8_t pdisc = gsm48_hdr_pdisc(gh);
-
-	switch (pdisc) {
-	case GSM48_PDISC_MM:
-		rc = hnb_nas_rx_mm(hnb, gh, len);
-		if (rc != 0)
-			printf("Error receiving MM message: %d\n", rc);
-		return;
-	default:
-		printf("04.08 discriminator not handled by hnb-test: %d\n",
-		       pdisc);
-		return;
-	}
-}
-
-void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg)
-{
-	printf(" :) Security Mode Command :)\n");
-	/* not caring about encryption yet, just pass 0 for No Encryption. */
-	hnb_tx_dt(hnb, ranap_new_msg_sec_mod_compl(ip_alg, 0));
-}
-
-void hnb_rx_iu_release(struct hnb *hnb)
-{
-	hnb_tx_iu_release_compl(hnb);
-}
-
-void hnb_rx_paging(struct hnb *hnb, const char *imsi)
-{
-	printf(" :) Paging Request for %s :)\n", imsi);
-	/* TODO reply */
-}
-
-extern void direct_transfer_nas_pdu_print(ANY_t *in);
-
 static struct vty_app_info vty_info = {
 	.name		= "OsmohNodeB",
 	.version	= "0",
 };
 
-
-struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi)
-{
-	uint8_t lu[] = { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST,
-		         0x70, 0x62, 0xf2, 0x30, 0xff, 0xf3, 0x57,
-		/*	 len, IMSI/type, IMSI-------------------------------- */
-			 0x08, 0x29, 0x26, 0x24, 0x10, 0x32, 0x54, 0x76, 0x98,
-			 0x33, 0x03, 0x57, 0x18 , 0xb2 };
-	uint8_t plmn_id[] = { 0x09, 0x01, 0x99 };
-	RANAP_GlobalRNC_ID_t rnc_id = {
-		.rNC_ID = 23,
-		.pLMNidentity.buf = plmn_id,
-		.pLMNidentity.size = sizeof(plmn_id),
-	};
-
-	/* FIXME: patch imsi */
-	/* Note: the Mobile Identitiy IE's IMSI data has the identity type and
-	 * an even/odd indicator bit encoded in the first octet. So the first
-	 * octet looks like this:
-	 *
-	 *   8  7  6  5 | 4        | 3 2 1
-	 *   IMSI-digit | even/odd | type
-	 *
-	 * followed by the remaining IMSI digits.
-	 * If digit count is even (bit 4 == 0), that first high-nibble is 0xf.
-	 * (derived from Iu pcap Location Update Request msg and TS 25.413)
-	 *
-	 * TODO I'm only 90% sure about this
-	 */
-
-	return ranap_new_msg_initial_ue(conn_id, is_ps, &rnc_id, lu, sizeof(lu));
-}
-
 static void handle_options(int argc, char **argv)
 {
 	while (1) {
diff --git a/src/osmo-hnodeb/nas.c b/src/osmo-hnodeb/nas.c
new file mode 100644
index 0000000..163f458
--- /dev/null
+++ b/src/osmo-hnodeb/nas.c
@@ -0,0 +1,268 @@
+/* (C) 2015 by Daniel Willmann <dwillmann at sysmocom.de>
+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/lienses/>.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/crypt/auth.h>
+
+#include <osmocom/ranap/ranap_msg_factory.h>
+
+#include <osmocom/hnodeb/rua.h>
+#include <osmocom/hnodeb/ranap.h>
+#include <osmocom/hnodeb/nas.h>
+#include <osmocom/hnodeb/hnodeb.h>
+
+static struct msgb *gen_nas_id_resp()
+{
+	uint8_t id_resp[] = {
+		GSM48_PDISC_MM,
+		GSM48_MT_MM_ID_RESP,
+		/* IMEISV */
+		0x09, /* len */
+		0x03, /* first digit (0000) + even (0) + id IMEISV (011) */
+		0x31, 0x91, 0x06, 0x00, 0x28, 0x47, 0x11, /* digits */
+		0xf2, /* filler (1111) + last digit (0010) */
+	};
+
+	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
+}
+
+static struct msgb *gen_nas_tmsi_realloc_compl()
+{
+	uint8_t id_resp[] = {
+		GSM48_PDISC_MM,
+		GSM48_MT_MM_TMSI_REALL_COMPL,
+	};
+
+	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
+}
+
+static struct msgb *gen_nas_auth_resp(uint8_t *sres)
+{
+	uint8_t id_resp[] = {
+		GSM48_PDISC_MM,
+		0x80 | GSM48_MT_MM_AUTH_RESP, /* simulate sequence nr 2 */
+		0x61, 0xb5, 0x69, 0xf5 /* hardcoded SRES */
+	};
+
+	memcpy(id_resp + 2, sres, 4);
+
+	return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));
+}
+
+static struct tlv_parsed *parse_mm(struct gsm48_hdr *gh, int len)
+{
+	static struct tlv_parsed tp;
+	int parse_res;
+
+	len -= (const char *)&gh->data[0] - (const char *)gh;
+
+	OSMO_ASSERT(gsm48_hdr_pdisc(gh) == GSM48_PDISC_MM);
+
+	parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);
+	if (parse_res <= 0) {
+		uint8_t msg_type = gsm48_hdr_msg_type(gh);
+		printf("Error parsing MM message 0x%hhx: %d\n", msg_type, parse_res);
+		return NULL;
+	}
+
+	return &tp;
+}
+
+int hnb_nas_rx_lu_accept(struct gsm48_hdr *gh, int len, int *sent_tmsi)
+{
+	printf(" :D Location Update Accept :D\n");
+	struct gsm48_loc_area_id *lai;
+
+	lai = (struct gsm48_loc_area_id *)&gh->data[0];
+
+	struct osmo_location_area_id laid;
+	gsm48_decode_lai2(lai, &laid);
+	printf("LU: mcc %s  mnc %s  lac %hd\n",
+	       osmo_mcc_name(laid.plmn.mcc), osmo_mnc_name(laid.plmn.mnc, laid.plmn.mnc_3_digits),
+	       laid.lac);
+
+	struct tlv_parsed tp;
+	int parse_res;
+
+	len -= (const char *)&gh->data[0] - (const char *)gh;
+	parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);
+	if (parse_res <= 0) {
+		printf("Error parsing Location Update Accept message: %d\n", parse_res);
+		return -1;
+	}
+
+	if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
+		uint8_t type = TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)[0] & 0x0f;
+		if (type == GSM_MI_TYPE_TMSI)
+			*sent_tmsi = 1;
+		else *sent_tmsi = 0;
+	}
+	return 0;
+}
+
+void hnb_nas_rx_mm_info(struct gsm48_hdr *gh, int len)
+{
+	printf(" :) MM Info :)\n");
+	struct tlv_parsed *tp = parse_mm(gh, len);
+	if (!tp)
+		return;
+
+	if (TLVP_PRESENT(tp, GSM48_IE_NAME_SHORT)) {
+		char name[128] = {0};
+		gsm_7bit_decode_n(name, 127,
+				  TLVP_VAL(tp, GSM48_IE_NAME_SHORT)+1,
+				  (TLVP_LEN(tp, GSM48_IE_NAME_SHORT)-1)*8/7);
+		printf("Info: Short Network Name: %s\n", name);
+	}
+
+	if (TLVP_PRESENT(tp, GSM48_IE_NAME_LONG)) {
+		char name[128] = {0};
+		gsm_7bit_decode_n(name, 127,
+				  TLVP_VAL(tp, GSM48_IE_NAME_LONG)+1,
+				  (TLVP_LEN(tp, GSM48_IE_NAME_LONG)-1)*8/7);
+		printf("Info: Long Network Name: %s\n", name);
+	}
+}
+
+static int hnb_nas_rx_auth_req(struct hnb *hnb, struct gsm48_hdr *gh,
+				    int len)
+{
+	struct gsm48_auth_req *ar;
+
+	len -= (const char *)&gh->data[0] - (const char *)gh;
+
+	if (len < sizeof(*ar)) {
+		printf("GSM48 Auth Req does not fit.\n");
+		return -1;
+	}
+
+	printf(" :) Authentication Request :)\n");
+
+	ar = (struct gsm48_auth_req*) &gh->data[0];
+	int seq = ar->key_seq;
+
+	/* Generate SRES from *HARDCODED* Ki for Iuh testing */
+	struct osmo_auth_vector vec;
+	/* Ki 000102030405060708090a0b0c0d0e0f */
+	struct osmo_sub_auth_data auth = {
+		.type	= OSMO_AUTH_TYPE_GSM,
+		.algo	= OSMO_AUTH_ALG_COMP128v1,
+		.u.gsm.ki = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+			0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+			0x0e, 0x0f
+		},
+	};
+
+	memset(&vec, 0, sizeof(vec));
+	osmo_auth_gen_vec(&vec, &auth, ar->rand);
+
+	printf("seq %d rand %s",
+	       seq, osmo_hexdump(ar->rand, sizeof(ar->rand)));
+	printf(" --> sres %s\n",
+	       osmo_hexdump(vec.sres, 4));
+
+	return hnb_tx_dt(hnb, gen_nas_auth_resp(vec.sres));
+}
+
+static int hnb_nas_rx_mm(struct hnb *hnb, struct gsm48_hdr *gh, int len)
+{
+	struct hnb_chan *chan;
+
+	chan = hnb->cs.chan;
+	if (!chan) {
+		printf("hnb_nas_rx_mm(): No CS channel established yet.\n");
+		return -1;
+	}
+
+	OSMO_ASSERT(!chan->is_ps);
+
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
+	int sent_tmsi;
+
+	switch (msg_type) {
+	case GSM48_MT_MM_ID_REQ:
+		return hnb_tx_dt(hnb, gen_nas_id_resp());
+
+	case GSM48_MT_MM_LOC_UPD_ACCEPT:
+		if (hnb_nas_rx_lu_accept(gh, len, &sent_tmsi))
+			return -1;
+		if (sent_tmsi)
+			return hnb_tx_dt(hnb, gen_nas_tmsi_realloc_compl());
+		else
+			return 0;
+
+	case GSM48_MT_MM_LOC_UPD_REJECT:
+		printf("Received Location Update Reject\n");
+		return 0;
+
+	case GSM48_MT_MM_INFO:
+		hnb_nas_rx_mm_info(gh, len);
+		hnb_tx_iu_release_req(hnb);
+		return 0;
+
+	case GSM48_MT_MM_AUTH_REQ:
+		return hnb_nas_rx_auth_req(hnb, gh, len);
+
+	default:
+		printf("04.08 message type not handled by hnb-test: 0x%x\n",
+		       msg_type);
+		return 0;
+	}
+
+}
+
+void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len)
+{
+	int rc;
+	printf("got %d bytes: %s\n", len, osmo_hexdump(data, len));
+
+	// nas_pdu == '05 08 12' ==> IMEI Identity request
+	//            '05 04 0d' ==> LU reject
+
+	struct gsm48_hdr *gh = data;
+	if (len < sizeof(*gh)) {
+		printf("hnb_nas_rx_dtap(): NAS PDU is too short: %d. Ignoring.\n",
+		       len);
+		return;
+	}
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+
+	switch (pdisc) {
+	case GSM48_PDISC_MM:
+		rc = hnb_nas_rx_mm(hnb, gh, len);
+		if (rc != 0)
+			printf("Error receiving MM message: %d\n", rc);
+		return;
+	default:
+		printf("04.08 discriminator not handled by hnb-test: %d\n",
+		       pdisc);
+		return;
+	}
+}
diff --git a/src/osmo-hnodeb/ranap.c b/src/osmo-hnodeb/ranap.c
index a6a92cc..8f1b9c0 100644
--- a/src/osmo-hnodeb/ranap.c
+++ b/src/osmo-hnodeb/ranap.c
@@ -18,11 +18,15 @@
  *
  */
 #include <osmocom/core/msgb.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
 
 #include <osmocom/ranap/ranap_common_cn.h>
 #include <osmocom/ranap/ranap_ies_defs.h>
 #include <osmocom/ranap/iu_helpers.h>
+#include <osmocom/ranap/ranap_msg_factory.h>
 
+#include <osmocom/hnodeb/nas.h>
+#include <osmocom/hnodeb/rua.h>
 #include <osmocom/hnodeb/ranap.h>
 
 static const char *printstr(OCTET_STRING_t *s)
@@ -105,3 +109,67 @@
 		return;
 	}
 }
+
+struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi)
+{
+	uint8_t lu[] = { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST,
+		         0x70, 0x62, 0xf2, 0x30, 0xff, 0xf3, 0x57,
+		/*	 len, IMSI/type, IMSI-------------------------------- */
+			 0x08, 0x29, 0x26, 0x24, 0x10, 0x32, 0x54, 0x76, 0x98,
+			 0x33, 0x03, 0x57, 0x18 , 0xb2 };
+	uint8_t plmn_id[] = { 0x09, 0x01, 0x99 };
+	RANAP_GlobalRNC_ID_t rnc_id = {
+		.rNC_ID = 23,
+		.pLMNidentity.buf = plmn_id,
+		.pLMNidentity.size = sizeof(plmn_id),
+	};
+
+	/* FIXME: patch imsi */
+	/* Note: the Mobile Identitiy IE's IMSI data has the identity type and
+	 * an even/odd indicator bit encoded in the first octet. So the first
+	 * octet looks like this:
+	 *
+	 *   8  7  6  5 | 4        | 3 2 1
+	 *   IMSI-digit | even/odd | type
+	 *
+	 * followed by the remaining IMSI digits.
+	 * If digit count is even (bit 4 == 0), that first high-nibble is 0xf.
+	 * (derived from Iu pcap Location Update Request msg and TS 25.413)
+	 *
+	 * TODO I'm only 90% sure about this
+	 */
+
+	return ranap_new_msg_initial_ue(conn_id, is_ps, &rnc_id, lu, sizeof(lu));
+}
+
+void hnb_tx_iu_release_req(struct hnb *hnb)
+{
+	RANAP_Cause_t cause = {
+		.present = RANAP_Cause_PR_radioNetwork,
+		.choice.transmissionNetwork = RANAP_CauseRadioNetwork_release_due_to_UE_generated_signalling_connection_release,
+	};
+	hnb_tx_dt(hnb, ranap_new_msg_iu_rel_req(&cause));
+}
+
+void hnb_tx_iu_release_compl(struct hnb *hnb)
+{
+	hnb_tx_dt(hnb, ranap_new_msg_iu_rel_compl());
+}
+
+void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg)
+{
+	printf(" :) Security Mode Command :)\n");
+	/* not caring about encryption yet, just pass 0 for No Encryption. */
+	hnb_tx_dt(hnb, ranap_new_msg_sec_mod_compl(ip_alg, 0));
+}
+
+void hnb_rx_iu_release(struct hnb *hnb)
+{
+	hnb_tx_iu_release_compl(hnb);
+}
+
+void hnb_rx_paging(struct hnb *hnb, const char *imsi)
+{
+	printf(" :) Paging Request for %s :)\n", imsi);
+	/* TODO reply */
+}
diff --git a/src/osmo-hnodeb/rua.c b/src/osmo-hnodeb/rua.c
index 0839c0d..229df30 100644
--- a/src/osmo-hnodeb/rua.c
+++ b/src/osmo-hnodeb/rua.c
@@ -24,10 +24,26 @@
 
 #include <osmocom/rua/rua_ies_defs.h>
 #include <osmocom/ranap/ranap_common_cn.h>
+#include <osmocom/rua/rua_msg_factory.h>
 
 #include <osmocom/hnodeb/rua.h>
 #include <osmocom/hnodeb/ranap.h>
 
+int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)
+{
+	struct hnb_chan *chan;
+	struct msgb *rua;
+
+	chan = hnb->cs.chan;
+	if (!chan) {
+		printf("hnb_nas_tx_tmsi_realloc_compl(): No CS channel established yet.\n");
+		return -1;
+	}
+
+	rua = rua_new_dt(chan->is_ps, chan->conn_id, txm);
+	osmo_wqueue_enqueue(&hnb->wqueue, rua);
+	return 0;
+}
 
 static void hnb_rua_dt_handle(struct hnb *hnb, ANY_t *in)
 {
diff --git a/src/osmo-hnodeb/vty.c b/src/osmo-hnodeb/vty.c
index b8dc7da..114f1c0 100644
--- a/src/osmo-hnodeb/vty.c
+++ b/src/osmo-hnodeb/vty.c
@@ -33,6 +33,7 @@
 #include <osmocom/ranap/ranap_msg_factory.h>
 
 #include <osmocom/hnodeb/hnbap.h>
+#include <osmocom/hnodeb/ranap.h>
 #include <osmocom/hnodeb/vty.h>
 #include <osmocom/hnodeb/hnodeb.h>
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-hnodeb/+/26002
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hnodeb
Gerrit-Branch: master
Gerrit-Change-Id: I771b3d3f61207137477eed2b316a5f670fb79ef2
Gerrit-Change-Number: 26002
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211102/e9f8d9f4/attachment.htm>


More information about the gerrit-log mailing list