lynxis lazus has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-iuh/+/38945?usp=email )


Change subject: iu_client: refactor LAC/RAC handling
......................................................................

iu_client: refactor LAC/RAC handling

The iu client ignored the PLMN which might ran into duplicate
RACs. Replace all lac/rac handling by the "new" osmo_routing_area_id
struct which has improved handling.
Further it allows to use the embedded lac when CS paging is only required.
The old gprs_ra_id is still used to contain api stability.

Change-Id: Ie38fa3751cfce1c981d8d0bed1b8ff891593a638
---
M src/iu_client.c
1 file changed, 85 insertions(+), 21 deletions(-)



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

diff --git a/src/iu_client.c b/src/iu_client.c
index 3fc29bd..018813d 100644
--- a/src/iu_client.c
+++ b/src/iu_client.c
@@ -49,10 +49,7 @@
 struct iu_lac_rac_entry {
        struct llist_head entry;

-       /* LAC: Location Area Code (for CS and PS) */
-       uint16_t lac;
-       /* RAC: Routing Area Code (for PS only) */
-       uint8_t rac;
+       struct osmo_routing_area_id rai;
 };

 /* Entry to cache conn_id <-> sccp_addr mapping in case we receive an empty CR 
*/
@@ -229,7 +226,7 @@
  * If rnc and lre pointers are not NULL, *rnc / *lre are set to NULL if no 
match is found, or to the
  * match if a match is found.  Return true if a match is found. */
 static bool iu_rnc_lac_rac_find(struct ranap_iu_rnc **rnc, struct 
iu_lac_rac_entry **lre,
-                               uint16_t lac, uint8_t rac)
+                               const struct osmo_routing_area_id *ra_id)
 {
        struct ranap_iu_rnc *r;
        struct iu_lac_rac_entry *e;
@@ -241,7 +238,33 @@

        llist_for_each_entry(r, &rnc_list, entry) {
                llist_for_each_entry(e, &r->lac_rac_list, entry) {
-                       if (e->lac == lac && e->rac == rac) {
+                       if (!osmo_rai_cmp(&e->rai, ra_id)) {
+                               if (rnc)
+                                       *rnc = r;
+                               if (lre)
+                                       *lre = e;
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+
+/* legacy, do a first match with ignoring PLMN */
+static bool iu_rnc_lac_rac_find_legacy(struct ranap_iu_rnc **rnc, struct 
iu_lac_rac_entry **lre,
+                                      uint16_t lac, uint8_t rac)
+{
+       struct ranap_iu_rnc *r;
+       struct iu_lac_rac_entry *e;
+
+       if (rnc)
+               *rnc = NULL;
+       if (lre)
+               *lre = NULL;
+
+       llist_for_each_entry(r, &rnc_list, entry) {
+               llist_for_each_entry(e, &r->lac_rac_list, entry) {
+                       if (e->rai.lac.lac == lac && e->rai.rac == rac) {
                                if (rnc)
                                        *rnc = r;
                                if (lre)
@@ -270,8 +293,9 @@
        return !strcmp(buf, osmo_sccp_addr_dump(b));
 }

-static struct ranap_iu_rnc *iu_rnc_register(struct osmo_rnc_id *rnc_id, 
uint16_t lac,
-                                           uint8_t rac, struct osmo_sccp_addr 
*addr)
+static struct ranap_iu_rnc *iu_rnc_register(struct osmo_rnc_id *rnc_id,
+                                           const struct osmo_routing_area_id 
*rai,
+                                           struct osmo_sccp_addr *addr)
 {
        struct ranap_iu_rnc *rnc;
        struct ranap_iu_rnc *old_rnc;
@@ -282,31 +306,31 @@

        if (rnc) {
                if (!same_sccp_addr(&rnc->sccp_addr, addr)) {
-                       LOGPIU(LOGL_NOTICE, "RNC %s changed its SCCP addr to %s 
(LAC=%u RAC=%u)\n",
-                              osmo_rnc_id_name(rnc_id), 
osmo_sccp_addr_dump(addr), lac, rac);
+                       LOGPIU(LOGL_NOTICE, "RNC %s changed its SCCP addr to %s 
(LAC/RAC %s)\n",
+                              osmo_rnc_id_name(rnc_id), 
osmo_sccp_addr_dump(addr), osmo_rai_name2(rai));
                        rnc->sccp_addr = *addr;
                }
        } else
                rnc = iu_rnc_alloc(rnc_id, addr);

        /* Detect whether the LAC,RAC is already recorded in another RNC */
-       iu_rnc_lac_rac_find(&old_rnc, &lre, lac, rac);
+       iu_rnc_lac_rac_find(&old_rnc, &lre, rai);

        if (old_rnc && old_rnc != rnc) {
-               /* LAC,RAC already exists in a different RNC */
-               LOGPIU(LOGL_NOTICE, "LAC %u RAC %u moved from RNC %s %s",
-                      lac, rac, osmo_rnc_id_name(&old_rnc->rnc_id), 
osmo_sccp_addr_dump(&old_rnc->sccp_addr));
+               /* LAC, RAC already exists in a different RNC */
+               LOGPIU(LOGL_NOTICE, "LAC/RAC %s moved from RNC %s %s",
+                      osmo_rai_name2(rai),
+                      osmo_rnc_id_name(&old_rnc->rnc_id), 
osmo_sccp_addr_dump(&old_rnc->sccp_addr));
                LOGPIUC(LOGL_NOTICE, " to RNC %s %s\n",
                        osmo_rnc_id_name(&rnc->rnc_id), 
osmo_sccp_addr_dump(&rnc->sccp_addr));

                llist_del(&lre->entry);
                llist_add(&lre->entry, &rnc->lac_rac_list);
        } else if (!old_rnc) {
-               /* LAC,RAC not recorded yet */
-               LOGPIU(LOGL_NOTICE, "RNC %s: new LAC %u RAC %u\n", 
osmo_rnc_id_name(rnc_id), lac, rac);
+               /* LAC, RAC not recorded yet */
+               LOGPIU(LOGL_NOTICE, "RNC %s: new LAC/RAC %s\n", 
osmo_rnc_id_name(rnc_id), osmo_rai_name2(rai));
                lre = talloc_zero(rnc, struct iu_lac_rac_entry);
-               lre->lac = lac;
-               lre->rac = rac;
+               lre->rai = *rai;
                llist_add(&lre->entry, &rnc->lac_rac_list);
        }
        /* else, LAC,RAC already recorded with the current RNC. */
@@ -410,7 +434,8 @@
 static int ranap_handle_co_initial_ue(void *ctx, RANAP_InitialUE_MessageIEs_t 
*ies)
 {
        struct new_ue_conn_ctx *new_ctx = ctx;
-       struct gprs_ra_id ra_id;
+       struct gprs_ra_id ra_id = {};
+       struct osmo_routing_area_id ra_id2 = {};
        struct osmo_rnc_id rnc_id = {};
        uint16_t sai;
        struct ranap_ue_conn_ctx *ue;
@@ -436,8 +461,10 @@
        msgb_gmmh(msg) = msgb_put(msg, ies->nas_pdu.size);
        memcpy(msgb_gmmh(msg), ies->nas_pdu.buf, ies->nas_pdu.size);

+       gprs_rai_to_osmo(&ra_id2, &ra_id);
+
        /* Make sure we know the RNC Id and LAC+RAC coming in on this 
connection. */
-       rnc = iu_rnc_register(&rnc_id, ra_id.lac, ra_id.rac, 
&new_ctx->sccp_addr);
+       rnc = iu_rnc_register(&rnc_id, &ra_id2, &new_ctx->sccp_addr);

        ue = ue_conn_ctx_alloc(rnc, new_ctx->conn_id);
        OSMO_ASSERT(ue);
@@ -789,7 +816,7 @@
        int log_level;
        int paged = 0;

-       iu_rnc_lac_rac_find(&rnc, NULL, lac, rac);
+       iu_rnc_lac_rac_find_legacy(&rnc, NULL, lac, rac);
        if (rnc) {
                if (iu_tx_paging_cmd(&rnc->sccp_addr, imsi, tmsi_or_ptmsi, 
is_ps, 0) == 0) {
                        log_msg = "Paging";
@@ -818,6 +845,43 @@
        return paged;
 }

+static int iu_page2(const char *imsi, const uint32_t *tmsi_or_ptmsi,
+                  const struct osmo_routing_area_id *ra_id, bool is_ps)
+{
+       struct ranap_iu_rnc *rnc;
+       const char *log_msg;
+       int log_level;
+       int paged = 0;
+
+       iu_rnc_lac_rac_find(&rnc, NULL, ra_id);
+       if (rnc) {
+               if (iu_tx_paging_cmd(&rnc->sccp_addr, imsi, tmsi_or_ptmsi, 
is_ps, 0) == 0) {
+                       log_msg = "Paging";
+                       log_level = LOGL_DEBUG;
+                       paged = 1;
+               } else {
+                       log_msg = "Paging failed";
+                       log_level = LOGL_ERROR;
+               }
+       } else {
+               log_msg = "Found no RNC to Page";
+               log_level = LOGL_ERROR;
+       }
+
+       if (is_ps)
+               LOGPIU(log_level, "IuPS: %s on RAC %s", log_msg, 
osmo_rai_name2(ra_id));
+       else
+               LOGPIU(log_level, "IuCS: %s on LAC %s", log_msg, 
osmo_lai_name(&ra_id->lac));
+       if (rnc)
+               LOGPIUC(log_level, " at SCCP-addr %s", 
osmo_sccp_addr_dump(&rnc->sccp_addr));
+       if (tmsi_or_ptmsi)
+               LOGPIUC(log_level, ", for %s %08x\n", is_ps? "PTMSI" : "TMSI", 
*tmsi_or_ptmsi);
+       else
+               LOGPIUC(log_level, ", for IMSI %s\n", imsi);
+
+       return paged;
+}
+
 int ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac)
 {
        return iu_page(imsi, tmsi, lac, 0, false);

--
To view, visit https://gerrit.osmocom.org/c/osmo-iuh/+/38945?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Change-Id: Ie38fa3751cfce1c981d8d0bed1b8ff891593a638
Gerrit-Change-Number: 38945
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <[email protected]>

Reply via email to