pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-hnbgw/+/39995?usp=email )
Change subject: Improve paging to support Paging Area ID
......................................................................
Improve paging to support Paging Area ID
Avoid broadcasting to all HNBs if CN requests paging on a specific
LAI/RAI.
The overall logic is also improved, eg. avoid adding a record if we
didn't forward any paging request at all...
Change-Id: I915254a39ee04898aa740674b4632a328f281955
---
M include/osmocom/hnbgw/hnbgw_cn.h
M src/osmo-hnbgw/cnlink_paging.c
M src/osmo-hnbgw/hnbgw_ranap.c
3 files changed, 120 insertions(+), 26 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/95/39995/1
diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h
index 0c99b26..a758f24 100644
--- a/include/osmocom/hnbgw/hnbgw_cn.h
+++ b/include/osmocom/hnbgw/hnbgw_cn.h
@@ -25,7 +25,7 @@
void cnlink_resend_reset(struct hnbgw_cnlink *cnlink);
void cnlink_set_disconnected(struct hnbgw_cnlink *cnlink);
-const char *cnlink_paging_add_ranap(struct hnbgw_cnlink *cnlink,
RANAP_InitiatingMessage_t *imsg);
+const char *cnlink_paging_add_ranap(struct hnbgw_cnlink *cnlink,
RANAP_CN_DomainIndicator_t domain, const RANAP_PagingIEs_t *paging_ies);
struct hnbgw_cnlink *cnlink_find_by_paging_mi(struct hnbgw_cnpool *cnpool, const struct
osmo_mobile_identity *mi);
enum hnbgw_cnpool_ctr {
diff --git a/src/osmo-hnbgw/cnlink_paging.c b/src/osmo-hnbgw/cnlink_paging.c
index e5ef2c2..7a44198 100644
--- a/src/osmo-hnbgw/cnlink_paging.c
+++ b/src/osmo-hnbgw/cnlink_paging.c
@@ -164,34 +164,26 @@
return NULL;
}
-const char *cnlink_paging_add_ranap(struct hnbgw_cnlink *cnlink,
RANAP_InitiatingMessage_t *imsg)
+const char *cnlink_paging_add_ranap(struct hnbgw_cnlink *cnlink,
RANAP_CN_DomainIndicator_t domain, const RANAP_PagingIEs_t *paging_ies)
{
- RANAP_PagingIEs_t ies;
struct osmo_mobile_identity mi = {};
struct osmo_mobile_identity mi2 = {};
- RANAP_CN_DomainIndicator_t domain;
const char *errmsg;
- if (ranap_decode_pagingies(&ies, &imsg->value) < 0)
- return "decoding RANAP IEs failed";
+ domain = paging_ies->cN_DomainIndicator;
+ errmsg = omi_from_ranap_ue_id(&mi, &paging_ies->permanentNAS_UE_ID);
- domain = ies.cN_DomainIndicator;
- errmsg = omi_from_ranap_ue_id(&mi, &ies.permanentNAS_UE_ID);
+ if (!errmsg && (paging_ies->presenceMask &
PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT))
+ errmsg = omi_from_ranap_temp_ue_id(&mi2, &paging_ies->temporaryUE_ID);
- if (!errmsg && (ies.presenceMask & PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT))
- errmsg = omi_from_ranap_temp_ue_id(&mi2, &ies.temporaryUE_ID);
-
- ranap_free_pagingies(&ies);
- LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "Decoded Paging: %s %s %s%s%s\n",
- ranap_domain_name(domain), osmo_mobile_identity_to_str_c(OTC_SELECT, &mi),
+ LOG_CNLINK(cnlink, DCN, errmsg ? LOGL_NOTICE : LOGL_DEBUG,
+ "Decoded Paging: %s %s %s%s%s\n",
+ ranap_domain_name(domain),
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi),
mi2.type ? osmo_mobile_identity_to_str_c(OTC_SELECT, &mi2) : "-",
errmsg ? " -- MI error: " : "",
errmsg ? : "");
- if (cnlink->pool->domain != domain)
- return talloc_asprintf(OTC_SELECT, "message indicates domain %s, but this is %s on
domain %s\n",
- ranap_domain_name(domain), cnlink->name,
ranap_domain_name(cnlink->pool->domain));
-
if (errmsg)
return errmsg;
diff --git a/src/osmo-hnbgw/hnbgw_ranap.c b/src/osmo-hnbgw/hnbgw_ranap.c
index 3078b7d..511c751 100644
--- a/src/osmo-hnbgw/hnbgw_ranap.c
+++ b/src/osmo-hnbgw/hnbgw_ranap.c
@@ -322,35 +322,137 @@
return 0;
}
+static const struct value_string ranap_paging_area_id_names[] = {
+ { RANAP_PagingAreaID_PR_NOTHING, "NOTHING" },
+ { RANAP_PagingAreaID_PR_lAI, "LAI" },
+ { RANAP_PagingAreaID_PR_rAI, "RAI" },
+ { 0, NULL }
+};
+
+static bool hnb_paging_area_id_match(const struct hnb_context *hnb,
+ enum RANAP_PagingAreaID_PR t,
+ const struct osmo_routing_area_id *rai)
+{
+ switch (t) {
+ case RANAP_PagingAreaID_PR_NOTHING:
+ return true;
+ case RANAP_PagingAreaID_PR_rAI:
+ if (hnb->id.rac != rai->rac)
+ return false;
+ /* fall through */
+ case RANAP_PagingAreaID_PR_lAI:
+ if (hnb->id.lac != rai->lac.lac)
+ return false;
+ if (osmo_plmn_cmp(&hnb->id.plmn, &rai->lac.plmn))
+ return false;
+ /* fall through */
+ }
+ return true;
+}
+
+static int lai_from_RANAP_RANAP_LAI(struct osmo_location_area_id *lai, const RANAP_LAI_t
*ranap_lai)
+{
+ if (ranap_lai->pLMNidentity.size < 3)
+ return -EINVAL;
+ osmo_plmn_from_bcd(ranap_lai->pLMNidentity.buf, &lai->plmn);
+ lai->lac = asn1str_to_u16(&ranap_lai->lAC);
+ return 0;
+}
+
+static int rai_from_RANAP_PagingAreaID(struct osmo_routing_area_id *rai, const
RANAP_PagingAreaID_t *paid)
+{
+ switch (paid->present) {
+ case RANAP_PagingAreaID_PR_NOTHING:
+ break;
+ case RANAP_PagingAreaID_PR_lAI:
+ return lai_from_RANAP_RANAP_LAI(&rai->lac, &paid->choice.lAI);
+ case RANAP_PagingAreaID_PR_rAI:
+ rai->rac = asn1str_to_u8(&paid->choice.rAI.rAC);
+ return lai_from_RANAP_RANAP_LAI(&rai->lac, &paid->choice.rAI.lAI);
+ }
+ return 0;
+}
+
+/* 3GPP TS 25.413 8.15 */
static int cn_ranap_rx_paging_cmd(struct hnbgw_cnlink *cnlink,
RANAP_InitiatingMessage_t *imsg,
const uint8_t *data, unsigned int len)
{
+ RANAP_PagingIEs_t ies;
+ RANAP_CN_DomainIndicator_t domain;
const char *errmsg;
struct hnb_context *hnb;
bool is_ps = cnlink->pool->domain == DOMAIN_PS;
+ bool forwarded = false;
+ bool page_area_present;
+ struct osmo_routing_area_id page_rai = {};
- errmsg = cnlink_paging_add_ranap(cnlink, imsg);
- if (errmsg) {
- LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Rx Paging from CN: %s. Dropping paging
record."
- " Later on, the Paging Response may be forwarded to the wrong CN
peer.\n",
- errmsg);
+ if (ranap_decode_pagingies(&ies, &imsg->value) < 0) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR,
+ "Rx Paging from CN: decoding RANAP IEs failed\n");
return -1;
}
+ domain = ies.cN_DomainIndicator;
+ page_area_present = (ies.presenceMask & PAGINGIES_RANAP_PAGINGAREAID_PRESENT);
- /* FIXME: determine which HNBs to send this Paging command,
- * rather than broadcasting to all HNBs */
+ if (cnlink->pool->domain != domain) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR,
+ "Rx Paging from CN: message indicates domain %s, but this is %s on domain
%s\n",
+ ranap_domain_name(domain), cnlink->name,
+ ranap_domain_name(cnlink->pool->domain));
+ goto free_ies_ret;
+ }
+
+ if (page_area_present) {
+ if (rai_from_RANAP_PagingAreaID(&page_rai, &ies.pagingAreaID) < 0) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR,
+ "Rx Paging from CN: decoding RANAP IE Paging Area ID failed\n");
+ /* fail over to broadcast... */
+ page_area_present = false;
+ }
+ }
+
+ LOG_CNLINK(cnlink, DCN, LOGL_DEBUG,
+ "Rx Paging from CN: %s PagingAreaID: %s %s\n",
+ ranap_domain_name(domain),
+ page_area_present ?
+ get_value_string(ranap_paging_area_id_names, ies.pagingAreaID.present) :
+ "NOT_PRESENT",
+ osmo_rai_name2(&page_rai)
+ );
+
llist_for_each_entry(hnb, &g_hnbgw->hnb_list, list) {
if (!hnb->hnb_registered)
continue;
+ if (page_area_present &&
+ !hnb_paging_area_id_match(hnb, ies.pagingAreaID.present, &page_rai))
+ continue;
+
if (is_ps)
HNBP_CTR_INC(hnb->persistent, HNB_CTR_PS_PAGING_ATTEMPTED);
else
HNBP_CTR_INC(hnb->persistent, HNB_CTR_CS_PAGING_ATTEMPTED);
- rua_tx_udt(hnb, data, len);
+ if (rua_tx_udt(hnb, data, len) == 0)
+ forwarded = true;
}
+ if (forwarded) {
+ /* If Paging command was forwarded anywhere, store a record for it, to match paging
response: */
+ errmsg = cnlink_paging_add_ranap(cnlink, domain, &ies);
+ if (errmsg) {
+ LOG_CNLINK(cnlink, DCN, LOGL_ERROR,
+ "Rx Paging from CN: %s. Skip storing paging record."
+ " Later on, the Paging Response may be forwarded to the wrong CN
peer.\n",
+ errmsg);
+ goto free_ies_ret;
+ }
+ }
+ ranap_free_pagingies(&ies);
return 0;
+
+free_ies_ret:
+ ranap_free_pagingies(&ies);
+ return -1;
}
static int ranap_rx_udt_dl_initiating_msg(struct hnbgw_cnlink *cnlink,
--
To view, visit
https://gerrit.osmocom.org/c/osmo-hnbgw/+/39995?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I915254a39ee04898aa740674b4632a328f281955
Gerrit-Change-Number: 39995
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>