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
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>