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 <pes...@sysmocom.de>

Reply via email to