[PATCH] osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI

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/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Thu Sep 22 17:56:58 UTC 2016


Review at  https://gerrit.osmocom.org/910

hnbap: accept UE Register Requests with TMSI and pTMSI

HNBGW so far keeps track of UEs that have registered, with their IMSI. When a
UE registers with only a TMSI, we obviously can't store an IMSI. However, since
we're so far never *using* the list of UEs in osmo-hnbgw, we might as well just
accept the TMSI registration and carry on as usual. All that is needed for
proper operation is a valid UE context.

This is particularly helpful with an ip.access nano3G femto cell, as it
apparently feeds whichever identification the UE sends through to HNBAP
(TMSI+LAI, pTMSI+RAI), instead of an IMSI as expected. So far this caused
failures and the need to make the UE clear its TMSI (wait several minutes or
attempt to subscribe to a different network), so that UE registration switched
back to IMSI. When simply accepting the TMSI in osmo-hngw, no problems are
apparent in our current code state.

For example, a Samsung Galaxy S4 seems to send a UE_Identity_PR_tMSILAI (CS
identity), and a GT-I9100 seems to send a UE_Identity_PR_pTMSIRAI (PS identity)
upon first registration to the network.

Recording the IMSI in hnbgw: we could use the subscriber list during paging,
but on the other hand, it doesn't hurt to anyway always page to all HNBs
connected to osmo-hnbgw. The paging procedure does include a page-to-all-HNBs
in case the first HNB paging fails. However, since we're now failing to record
UEs that register by TMSI, we must be aware that trying to page such UE on only
its last seen HNB will fail; it is plainly missing in the list.

Patch-by: Harald Welte <laforge at gnumonks.org>, me
Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589
---
M src/hnbgw_hnbap.c
1 file changed, 83 insertions(+), 44 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/10/910/1

diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index dab6f4f..2f3a717 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -114,65 +114,100 @@
 	return hnbgw_hnbap_tx(ue->hnb, msg);
 }
 
-static int hnbgw_tx_ue_register_rej_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id)
+static int hnbgw_tx_ue_register_acc_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id)
 {
-	UERegisterReject_t reject_out;
-	UERegisterRejectIEs_t reject;
+	UERegisterAccept_t accept_out;
+	UERegisterAcceptIEs_t accept;
 	struct msgb *msg;
+	uint32_t ctx_id;
+	uint32_t tmsi = 0;
+	struct ue_context *ue;
 	int rc;
 
-	memset(&reject, 0, sizeof(reject));
-	reject.uE_Identity.present = ue_id->present;
+	memset(&accept, 0, sizeof(accept));
+	accept.uE_Identity.present = ue_id->present;
 
-	if (ue_id->present != UE_Identity_PR_tMSILAI) {
-		LOGP(DHNBAP, LOGL_ERROR, "Trying to reject UE Register without IMSI: only rejects of UE_Identity_PR_tMSILAI supported so far.\n");
+	switch (ue_id->present) {
+	case UE_Identity_PR_tMSILAI:
+		BIT_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.tMSI,
+				   ue_id->choice.tMSILAI.tMSI.buf,
+				   ue_id->choice.tMSILAI.tMSI.size * 8
+				   - ue_id->choice.tMSILAI.tMSI.bits_unused);
+		tmsi = *(uint32_t*)accept.uE_Identity.choice.tMSILAI.tMSI.buf;
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.pLMNID,
+				     ue_id->choice.tMSILAI.lAI.pLMNID.buf,
+				     ue_id->choice.tMSILAI.lAI.pLMNID.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.lAC,
+				     ue_id->choice.tMSILAI.lAI.lAC.buf,
+				     ue_id->choice.tMSILAI.lAI.lAC.size);
+		break;
+	case UE_Identity_PR_pTMSIRAI:
+		BIT_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.pTMSI,
+				   ue_id->choice.pTMSIRAI.pTMSI.buf,
+				   ue_id->choice.pTMSIRAI.pTMSI.size * 8
+				   - ue_id->choice.pTMSIRAI.pTMSI.bits_unused);
+		tmsi = *(uint32_t*)accept.uE_Identity.choice.pTMSIRAI.pTMSI.buf;
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.rAC,
+				     ue_id->choice.pTMSIRAI.rAI.rAC.buf,
+				     ue_id->choice.pTMSIRAI.rAI.rAC.size);
+		break;
+	default:
+		LOGP(DHNBAP, LOGL_ERROR, "Unsupportedccept UE ID (present=%d)\n",
+			ue_id->present);
 		return -1;
 	}
 
-	LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id tMSI %d %s\n",
-	     ue_id->choice.tMSILAI.tMSI.size,
-	     osmo_hexdump(ue_id->choice.tMSILAI.tMSI.buf,
-			  ue_id->choice.tMSILAI.tMSI.size));
+	tmsi = ntohl(tmsi);
+	LOGP(DHNBAP, LOGL_DEBUG, "HNBAP register with TMSI %x\n",
+	     tmsi);
 
-	LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n",
-	     ue_id->choice.tMSILAI.lAI.pLMNID.size,
-	     osmo_hexdump(ue_id->choice.tMSILAI.lAI.pLMNID.buf,
-			  ue_id->choice.tMSILAI.lAI.pLMNID.size));
+	ue = ue_context_by_tmsi(hnb->gw, tmsi);
+	if (!ue)
+		ue = ue_context_alloc(hnb, NULL, tmsi);
 
-	LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n",
-	     ue_id->choice.tMSILAI.lAI.lAC.size,
-	     osmo_hexdump(ue_id->choice.tMSILAI.lAI.lAC.buf,
-			  ue_id->choice.tMSILAI.lAI.lAC.size));
+	asn1_u24_to_bitstring(&accept.context_ID, &ctx_id, ue->context_id);
 
-	BIT_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.tMSI,
-			   ue_id->choice.tMSILAI.tMSI.buf,
-			   ue_id->choice.tMSILAI.tMSI.size * 8
-			   - ue_id->choice.tMSILAI.tMSI.bits_unused);
-	OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.pLMNID,
-			     ue_id->choice.tMSILAI.lAI.pLMNID.buf,
-			     ue_id->choice.tMSILAI.lAI.pLMNID.size);
-	OCTET_STRING_fromBuf(&reject.uE_Identity.choice.tMSILAI.lAI.lAC,
-			     ue_id->choice.tMSILAI.lAI.lAC.buf,
-			     ue_id->choice.tMSILAI.lAI.lAC.size);
-
-	reject.cause.present = Cause_PR_radioNetwork;
-	reject.cause.choice.radioNetwork = CauseRadioNetwork_invalid_UE_identity;
-
-	memset(&reject_out, 0, sizeof(reject_out));
-	rc = hnbap_encode_ueregisterrejecties(&reject_out, &reject);
+	memset(&accept_out, 0, sizeof(accept_out));
+	rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept);
 	if (rc < 0) {
 		return rc;
 	}
 
-	msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister,
-						  Criticality_reject,
-						  &asn_DEF_UERegisterReject,
-						  &reject_out);
+	msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister,
+						Criticality_reject,
+						&asn_DEF_UERegisterAccept,
+						&accept_out);
 
-	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, &reject.uE_Identity.choice.tMSILAI.tMSI);
-	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.pLMNID);
-	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, &reject.uE_Identity.choice.tMSILAI.lAI.lAC);
-	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out);
+	switch (ue_id->present) {
+	case UE_Identity_PR_tMSILAI:
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.tMSI);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.lAI.pLMNID);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.lAI.lAC);
+		break;
+	case UE_Identity_PR_pTMSIRAI:
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.pTMSI);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.rAC);
+		break;
+	default:
+		break;
+	}
+
+	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterAccept, &accept_out);
 
 	return hnbgw_hnbap_tx(hnb, msg);
 }
@@ -246,11 +281,15 @@
 		ranap_bcd_decode(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf,
 			      ies.uE_Identity.choice.iMSIESN.iMSIDS41.size);
 		break;
+	case UE_Identity_PR_tMSILAI:
+	case UE_Identity_PR_pTMSIRAI:
+		rc = hnbgw_tx_ue_register_acc_tmsi(ctx, &ies.uE_Identity);
+		hnbap_free_ueregisterrequesties(&ies);
+		return rc;
 	default:
 		LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n");
 		/* TODO: this is probably a TMSI registration. Store TMSIs
 		 * and look them up to accept UE Registration. */
-		rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity);
 		hnbap_free_ueregisterrequesties(&ies);
 		return rc;
 	}

-- 
To view, visit https://gerrit.osmocom.org/910
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589
Gerrit-PatchSet: 1
Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list