From c94ed09f50a124b962abb1f71f11c006db30e587 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 26 Sep 2016 01:27:55 +0200 Subject: hnbap: add UE Register Reject for pTMSIRAI identity This is aimed at the 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. Sending a proper registration reject speeds up the response seen on the UE and avoids needless waiting. See the upcoming commit that enables accepting TMSI identities for further detail. Change-Id: I03b69613e6ddd8a08d9358ffc2f74954c231fd2c --- src/hnbgw_hnbap.c | 131 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c index 7bf54c8..ae0d16c 100644 --- a/src/hnbgw_hnbap.c +++ b/src/hnbgw_hnbap.c @@ -124,54 +124,121 @@ static int hnbgw_tx_ue_register_rej_tmsi(struct hnb_context *hnb, UE_Identity_t memset(&reject, 0, sizeof(reject)); reject.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"); + /* Copy the identity over to the reject message */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + 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)); + + 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)); + + 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)); + + 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); + break; + + case UE_Identity_PR_pTMSIRAI: + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pTMSI %d %s\n", + ue_id->choice.pTMSIRAI.pTMSI.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.pTMSI.buf, + ue_id->choice.pTMSIRAI.pTMSI.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id pLMNID %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id lAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf, + ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size)); + + LOGP(DHNBAP, LOGL_DEBUG, "REJ UE_Id rAC %d %s\n", + ue_id->choice.pTMSIRAI.rAI.rAC.size, + osmo_hexdump(ue_id->choice.pTMSIRAI.rAI.rAC.buf, + ue_id->choice.pTMSIRAI.rAI.rAC.size)); + + BIT_STRING_fromBuf(&reject.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); + OCTET_STRING_fromBuf(&reject.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(&reject.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(&reject.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, "Cannot compose UE Register Reject:" + " unsupported 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)); - - 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)); - - 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)); - - 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); + LOGP(DHNBAP, LOGL_ERROR, "Rejecting UE Register Request:" + " TMSI identity registration is switched off\n"); 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); - if (rc < 0) { + if (rc < 0) return rc; - } msg = hnbap_generate_unsuccessful_outcome(ProcedureCode_id_UERegister, Criticality_reject, &asn_DEF_UERegisterReject, &reject_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); + /* Free copied identity IEs */ + switch (ue_id->present) { + case UE_Identity_PR_tMSILAI: + 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); + break; + + case UE_Identity_PR_pTMSIRAI: + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING, + &reject.uE_Identity.choice.pTMSIRAI.pTMSI); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING, + &reject.uE_Identity.choice.pTMSIRAI.rAI.rAC); + break; + + default: + /* should never happen after above switch() */ + break; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterReject, &reject_out); return hnbgw_hnbap_tx(hnb, msg); -- cgit v1.2.3