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 <lynxis(a)fe80.eu>