aboutsummaryrefslogtreecommitdiffstats
path: root/src/hnbgw_hnbap.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-09-26 01:27:55 +0200
committerHarald Welte <laforge@gnumonks.org>2016-09-27 05:55:55 +0000
commitc94ed09f50a124b962abb1f71f11c006db30e587 (patch)
tree2b9edfcacea99e5b3bcf61ad86853d91cd11fd3b /src/hnbgw_hnbap.c
parentc83e49fc8ddb64fabf506ec3ed8cb622a4e4772c (diff)
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
Diffstat (limited to 'src/hnbgw_hnbap.c')
-rw-r--r--src/hnbgw_hnbap.c131
1 files 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);