[PATCH] osmo-iuh[master]: iu client: store multiple LAC, RAC per RNC = fix paging for m...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Dec 15 01:57:56 UTC 2017


Review at  https://gerrit.osmocom.org/5381

iu client: store multiple LAC,RAC per RNC = fix paging for multiple RNC

Introduce a list of LAC+RAC entries for each RNC, hence allow serving more than
one LAC per OsmoHNBGW.

iu_client is used by OsmoMSC and OsmoSGSN, both will be able to page
successfully in a setup with multiple LACs (read: multiple hNodeB) connected to
an OsmoHNBGW.

Change-Id: I189f8e2663353276b1c615d2f78455dafe568045
---
M src/iu_client.c
1 file changed, 75 insertions(+), 41 deletions(-)


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

diff --git a/src/iu_client.c b/src/iu_client.c
index 3ee900c..c8a8b11 100644
--- a/src/iu_client.c
+++ b/src/iu_client.c
@@ -47,6 +47,13 @@
 	uint16_t rnc_id;
 };
 
+struct iu_lac_rac_entry {
+	struct llist_head entry;
+
+	uint16_t lac;
+	uint8_t rac;
+};
+
 /* A remote RNC (Radio Network Controller, like BSC but for UMTS) that has
  * called us and is currently reachable at the given osmo_sccp_addr. So, when we
  * know a LAC for a subscriber, we can page it at the RNC matching that LAC or
@@ -58,9 +65,10 @@
 	struct llist_head entry;
 
 	uint16_t rnc_id;
-	uint16_t lac; /* Location Area Code (used for CS and PS) */
-	uint8_t rac; /* Routing Area Code (used for PS only) */
 	struct osmo_sccp_addr sccp_addr;
+
+	/* A list of struct iu_lac_rac_entry */
+	struct llist_head lac_rac_list;
 };
 
 void *talloc_iu_ctx;
@@ -119,53 +127,75 @@
 	return NULL;
 }
 
-static struct ranap_iu_rnc *iu_rnc_alloc(uint16_t rnc_id, uint16_t lac, uint8_t rac,
-					 struct osmo_sccp_addr *addr)
+static struct ranap_iu_rnc *iu_rnc_alloc(uint16_t rnc_id, struct osmo_sccp_addr *addr)
 {
 	struct ranap_iu_rnc *rnc = talloc_zero(talloc_iu_ctx, struct ranap_iu_rnc);
+	OSMO_ASSERT(rnc);
+
+	INIT_LLIST_HEAD(&rnc->lac_rac_list);
 
 	rnc->rnc_id = rnc_id;
-	rnc->lac = lac;
-	rnc->rac = rac;
 	rnc->sccp_addr = *addr;
 	llist_add(&rnc->entry, &rnc_list);
 
-	LOGPIU(LOGL_NOTICE, "New RNC %d (LAC=%d RAC=%d)\n",
-	       rnc->rnc_id, rnc->lac, rnc->rac);
+	LOGPIU(LOGL_NOTICE, "New RNC %d at %s\n", rnc->rnc_id, osmo_sccp_addr_dump(addr));
 
 	return rnc;
+}
+
+static bool same_sccp_addr(struct osmo_sccp_addr *a, struct osmo_sccp_addr *b)
+{
+	char buf[256];
+	osmo_strlcpy(buf, osmo_sccp_addr_dump(a), sizeof(buf));
+	return !strcmp(buf, osmo_sccp_addr_dump(b));
 }
 
 static struct ranap_iu_rnc *iu_rnc_register(uint16_t rnc_id, uint16_t lac,
 					    uint8_t rac, struct osmo_sccp_addr *addr)
 {
 	struct ranap_iu_rnc *rnc;
+	struct iu_lac_rac_entry *e;
+	bool found_rnc;
+	bool found_lac_rac;
+
+	found_rnc = false;
 	llist_for_each_entry(rnc, &rnc_list, entry) {
+
 		if (rnc->rnc_id != rnc_id)
 			continue;
 
-		/* We have this RNC Id registered already. Make sure that the
-		 * details match. */
-
-		/* TODO should a mismatch be an error? */
-		if (rnc->lac != lac || rnc->rac != rac)
-			LOGPIU(LOGL_NOTICE, "RNC %d changes its details:"
-			       " LAC=%d RAC=%d --> LAC=%d RAC=%d\n",
-			       rnc->rnc_id, rnc->lac, rnc->rac,
-			       lac, rac);
-		rnc->lac = lac;
-		rnc->rac = rac;
-
-		if (addr && memcmp(&rnc->sccp_addr, addr, sizeof(*addr)))
-			LOGPIU(LOGL_NOTICE, "RNC %d on New SCCP Addr %s"
-			       " (LAC=%d RAC=%d)\n",
-			       rnc->rnc_id, osmo_sccp_addr_dump(addr), rnc->lac, rnc->rac);
-		rnc->sccp_addr = *addr;
-		return rnc;
+		found_rnc = true;
+		break;
 	}
 
-	/* Not found, make a new one. */
-	return iu_rnc_alloc(rnc_id, lac, rac, addr);
+	if (!found_rnc) {
+		rnc = iu_rnc_alloc(rnc_id, addr);
+		found_lac_rac = false;
+	} else {
+		if (!same_sccp_addr(&rnc->sccp_addr, addr)) {
+			LOGPIU(LOGL_NOTICE, "RNC %u on New SCCP Addr %s (LAC=%u RAC=%u)\n",
+			       rnc_id, osmo_sccp_addr_dump(addr), lac, rac);
+			rnc->sccp_addr = *addr;
+		}
+
+		found_lac_rac = false;
+		llist_for_each_entry(e, &rnc->lac_rac_list, entry) {
+			if (e->lac == lac && e->rac == rac) {
+				found_lac_rac = true;
+				break;
+			}
+		}
+	}
+
+	if (!found_lac_rac) {
+		LOGPIU(LOGL_NOTICE, "RNC %u: new LAC %u RAC %u\n", rnc_id, lac, rac);
+		e = talloc_zero(rnc, struct iu_lac_rac_entry);
+		e->lac = lac;
+		e->rac = rac;
+		llist_add(&e->entry, &rnc->lac_rac_list);
+	}
+
+	return rnc;
 }
 
 /***********************************************************************
@@ -602,15 +632,16 @@
 	struct msgb *msg;
 	msg = ranap_new_msg_paging_cmd(imsi, tmsi, is_ps? 1 : 0, paging_cause);
 	msg->l2h = msg->data;
-	osmo_sccp_tx_unitdata_msg(g_scu, &g_local_sccp_addr, called_addr, msg);
-	return 0;
+	return osmo_sccp_tx_unitdata_msg(g_scu, &g_local_sccp_addr, called_addr, msg);
 }
 
 static int iu_page(const char *imsi, const uint32_t *tmsi_or_ptimsi,
 		   uint16_t lac, uint8_t rac, bool is_ps)
 {
 	struct ranap_iu_rnc *rnc;
+	struct iu_lac_rac_entry *e;
 	int pagings_sent = 0;
+	int rc;
 
 	if (tmsi_or_ptimsi) {
 		LOGPIU(LOGL_DEBUG, "%s: Looking for RNCs to page for IMSI %s"
@@ -628,19 +659,22 @@
 	}
 
 	llist_for_each_entry(rnc, &rnc_list, entry) {
-		if (rnc->lac != lac)
-			continue;
-		if (is_ps && rnc->rac != rac)
-			continue;
+		llist_for_each_entry(e, &rnc->lac_rac_list, entry) {
+			if (e->lac != lac)
+				continue;
+			if (is_ps && e->rac != rac)
+				continue;
 
-		/* Found a match! */
-		if (iu_tx_paging_cmd(&rnc->sccp_addr, imsi, tmsi_or_ptimsi, is_ps, 0)
-		    == 0) {
-			LOGPIU(LOGL_DEBUG,
-			       "%s: Paged for IMSI %s on RNC %d, on SCCP addr %s\n",
+			/* Found a match! */
+			rc = iu_tx_paging_cmd(&rnc->sccp_addr, imsi, tmsi_or_ptimsi, is_ps, 0);
+			LOGPIU(rc ? LOGL_ERROR : LOGL_DEBUG,
+			       "%s: %s for IMSI %s on RNC %u LAC %u RAC %u SCCP addr %s\n",
 			       is_ps? "IuPS" : "IuCS",
-			       imsi, rnc->rnc_id, osmo_sccp_addr_dump(&rnc->sccp_addr));
-			pagings_sent ++;
+			       rc ? "Paging failed" : "Paging",
+			       imsi, rnc->rnc_id, lac, rac,
+			       osmo_sccp_addr_dump(&rnc->sccp_addr));
+			if (!rc)
+				pagings_sent ++;
 		}
 	}
 

-- 
To view, visit https://gerrit.osmocom.org/5381
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I189f8e2663353276b1c615d2f78455dafe568045
Gerrit-PatchSet: 1
Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list