lynxis lazus has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-sgsn/+/40688?usp=email )
Change subject: routing area: introduce ran_type on the RA
......................................................................
routing area: introduce ran_type on the RA
A Routing Area should be unique identified by the RAI.
Following this, it is forbidden to have a RAI which is valid
in both, GERAN and UTRAN.
Change-Id: I59c35f1a4912ff11574bb31e4fe424816993548c
---
M include/osmocom/sgsn/gprs_routing_area.h
M src/sgsn/gprs_routing_area.c
M tests/gprs_routing_area/gprs_routing_area_test.c
3 files changed, 73 insertions(+), 20 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/88/40688/1
diff --git a/include/osmocom/sgsn/gprs_routing_area.h
b/include/osmocom/sgsn/gprs_routing_area.h
index caaed47..6629169 100644
--- a/include/osmocom/sgsn/gprs_routing_area.h
+++ b/include/osmocom/sgsn/gprs_routing_area.h
@@ -6,6 +6,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm23003.h>
struct sgsn_instance;
@@ -16,18 +17,35 @@
struct llist_head ra_list;
};
+enum sgsn_ra_ran_type {
+ RA_TYPE_GERAN_Gb,
+ RA_TYPE_UTRAN_Iu,
+};
+
+extern const struct value_string sgsn_ra_ran_type_names[];
+
struct sgsn_ra {
/* Entry in sgsn_ra_global->ra_list */
struct llist_head list;
struct osmo_routing_area_id rai;
- /* cells contains a list of sgsn_ra_cells which are alive */
- struct llist_head cells;
-};
-enum sgsn_ra_ran_type {
- RA_TYPE_GERAN_Gb,
- RA_TYPE_UTRAN_Iu,
+ /* For GERAN: every PCU is connected to the SGSN. It allows the SGSN to know every
single cell
+ * and for routing, the SGSN must know to which PCU a given cell is connected.
+ * It is possible that 2x PCU serves the same Routing Area
+ *
+ * For UTRAN: only the RNC (HNB via HNBGW) is communicating with the SGSN.
+ * The SGSN doesn't know every cell, because they aren't accepted individual by
the SGSN.
+ * The SGSN only "knows" RAI/SAI if they has been used. In the future it would
be a good idea to
+ * allow configuring RA in the vty/config as well.
+ * Similar to the GERAN Cell, but iu_client doesn't notify us for every given SAI,
only for RAC.
+ * Further the SGSN doesn't get informed about Service Area and can't relate the
SAI to a given UE.
+ * For UTRAN only do a LAC/RAC <> RNC relation and don't have a specific cell
relation.
+ */
+ enum sgsn_ra_ran_type ran_type;
+
+ /* GERAN/UTRAN: cells contains a list of sgsn_ra_cells which are alive */
+ struct llist_head cells;
};
struct sgsn_ra_cell {
@@ -55,7 +73,7 @@
void sgsn_ra_init(struct sgsn_instance *inst);
-struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai);
+struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai, enum
sgsn_ra_ran_type ran_type);
void sgsn_ra_free(struct sgsn_ra *ra);
struct sgsn_ra_cell *sgsn_ra_cell_alloc_geran(struct sgsn_ra *ra, uint16_t cell_id,
uint16_t nsei, uint16_t bvci);
void sgsn_ra_cell_free(struct sgsn_ra_cell *cell);
@@ -72,6 +90,7 @@
struct sgsn_ra_cell *sgsn_ra_get_cell_by_ra(const struct sgsn_ra *ra, uint16_t cell_id);
struct sgsn_ra_cell *sgsn_ra_get_cell_by_gb(uint16_t nsei, uint16_t bvci);
struct sgsn_ra *sgsn_ra_get_ra(const struct osmo_routing_area_id *ra_id);
+struct sgsn_ra *sgsn_ra_get_ra_geran(const struct osmo_routing_area_id *ra_id);
/*
diff --git a/src/sgsn/gprs_routing_area.c b/src/sgsn/gprs_routing_area.c
index 67b15ae..23847f2 100644
--- a/src/sgsn/gprs_routing_area.c
+++ b/src/sgsn/gprs_routing_area.c
@@ -23,6 +23,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gprs_bssgp.h>
@@ -31,6 +32,11 @@
#include <osmocom/sgsn/gprs_routing_area.h>
+const struct value_string sgsn_ra_ran_type_names[] = {
+ { RA_TYPE_GERAN_Gb, "GERAN_Gb"},
+ { RA_TYPE_UTRAN_Iu, "UTRAN_Iu"},
+};
+
static void _sgsn_ra_cell_free(struct sgsn_ra_cell *cell, bool drop_empty_ra)
{
struct sgsn_ra *ra;
@@ -72,7 +78,7 @@
talloc_free(ra);
}
-struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai)
+struct sgsn_ra *sgsn_ra_alloc(const struct osmo_routing_area_id *rai, enum
sgsn_ra_ran_type ran_type)
{
struct sgsn_ra *ra;
ra = talloc_zero(sgsn->routing_area, struct sgsn_ra);
@@ -81,6 +87,7 @@
INIT_LLIST_HEAD(&ra->cells);
ra->rai = *rai;
+ ra->ran_type = ran_type;
llist_add(&ra->list, &sgsn->routing_area->ra_list);
return ra;
}
@@ -115,6 +122,19 @@
return NULL;
}
+struct sgsn_ra *sgsn_ra_get_ra_geran(const struct osmo_routing_area_id *ra_id)
+{
+ struct sgsn_ra *ra = sgsn_ra_get_ra(ra_id);
+
+ if (!ra)
+ return ra;
+
+ if (ra->ran_type == RA_TYPE_GERAN_Gb)
+ return ra;
+
+ return NULL;
+}
+
struct sgsn_ra_cell *sgsn_ra_get_cell_by_gb(uint16_t nsei, uint16_t bvci)
{
struct sgsn_ra *ra;
@@ -125,6 +145,9 @@
return NULL;
llist_for_each_entry(ra, &sgsn->routing_area->ra_list, list) {
+ if (ra->ran_type != RA_TYPE_GERAN_Gb)
+ continue;
+
llist_for_each_entry(cell, &ra->cells, list) {
if (cell->ran_type != RA_TYPE_GERAN_Gb)
continue;
@@ -174,10 +197,14 @@
return sgsn_ra_foreach_cell(ra, cb, cb_data);
}
+/* valid for GERAN */
struct sgsn_ra_cell *sgsn_ra_get_cell_by_ra(const struct sgsn_ra *ra, uint16_t cell_id)
{
struct sgsn_ra_cell *cell;
+ if (ra->ran_type != RA_TYPE_GERAN_Gb)
+ return NULL;
+
llist_for_each_entry(cell, &ra->cells, list) {
if (cell->cell_id == cell_id)
return cell;
@@ -186,6 +213,7 @@
return NULL;
}
+/* valid for GERAN */
struct sgsn_ra_cell *sgsn_ra_get_cell_by_lai(const struct osmo_location_area_id *lai,
uint16_t cell_id)
{
struct sgsn_ra *ra;
@@ -194,6 +222,9 @@
/* This is a little bit in-efficient. A more performance way, but more complex would
* adding a llist for LAC on top of the routing areas */
llist_for_each_entry(ra, &sgsn->routing_area->ra_list, list) {
+ if (ra->ran_type != RA_TYPE_GERAN_Gb)
+ continue;
+
if (osmo_lai_cmp(&ra->rai.lac, lai) != 0)
continue;
@@ -206,7 +237,7 @@
return NULL;
}
-/*! Return the cell by searching for the RA, when found, search the cell within the RA
+/*! Return the GERAN cell by searching for the RA, when found, search the cell within the
RA
*
* \param cgi_ps
* \return the cell or NULL if not found
@@ -217,7 +248,7 @@
OSMO_ASSERT(cgi_ps);
- ra = sgsn_ra_get_ra(&cgi_ps->rai);
+ ra = sgsn_ra_get_ra_geran(&cgi_ps->rai);
if (!ra)
return NULL;
@@ -246,9 +277,10 @@
OSMO_ASSERT(cgi_ps);
/* TODO: do we have to move all MS to GMM IDLE state when this happens for a alive cell
which got reseted? */
- ra = sgsn_ra_get_ra(&cgi_ps->rai);
+ ra = sgsn_ra_get_ra_geran(&cgi_ps->rai);
if (!ra) {
- ra = sgsn_ra_alloc(&cgi_ps->rai);
+ /* TODO: check for UTRAN rai when introducing UTRAN support */
+ ra = sgsn_ra_alloc(&cgi_ps->rai, RA_TYPE_GERAN_Gb);
if (!ra)
return -ENOMEM;
ra_created = true;
@@ -312,6 +344,9 @@
bool found = false;
llist_for_each_entry_safe(ra, ra2, &sgsn->routing_area->ra_list, list) {
+ if (ra->ran_type != RA_TYPE_GERAN_Gb)
+ continue;
+
llist_for_each_entry_safe(cell, cell2, &ra->cells, list) {
if (cell->ran_type != RA_TYPE_GERAN_Gb)
continue;
@@ -324,7 +359,6 @@
if (llist_empty(&ra->cells))
sgsn_ra_free(ra);
-
}
return found ? 0 : -ENOENT;
@@ -338,7 +372,7 @@
rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PAGING_PS));
- ra = sgsn_ra_get_ra(ra_id);
+ ra = sgsn_ra_get_ra_geran(ra_id);
if (!ra)
return -ENOENT;
diff --git a/tests/gprs_routing_area/gprs_routing_area_test.c
b/tests/gprs_routing_area/gprs_routing_area_test.c
index e1aec0f..6021d81 100644
--- a/tests/gprs_routing_area/gprs_routing_area_test.c
+++ b/tests/gprs_routing_area/gprs_routing_area_test.c
@@ -75,7 +75,7 @@
printf("Testing Routing Area create/free\n");
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
- ra = sgsn_ra_alloc(&raid);
+ ra = sgsn_ra_alloc(&raid, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
@@ -105,7 +105,7 @@
printf("Testing Routing Area create/free\n");
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
- ra = sgsn_ra_alloc(&raid);
+ ra = sgsn_ra_alloc(&raid, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
@@ -117,7 +117,7 @@
sgsn_ra_free(ra);
OSMO_ASSERT(llist_empty(&sgsn->routing_area->ra_list));
- ra = sgsn_ra_alloc(&raid);
+ ra = sgsn_ra_alloc(&raid, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
@@ -160,7 +160,7 @@
printf("Testing Routing Area find\n");
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
- ra_a = sgsn_ra_alloc(&ra_id);
+ ra_a = sgsn_ra_alloc(&ra_id, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra_a);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
@@ -194,7 +194,7 @@
cgi.cell_identity = cell_id_not_found;
cgi_ps.cell_identity = cell_id_not_found;
- ra_a = sgsn_ra_alloc(&ra_id);
+ ra_a = sgsn_ra_alloc(&ra_id, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra_a);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
@@ -263,7 +263,7 @@
printf("Testing Routing Area BSSGP BVC RESET IND\n");
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
- ra_a = sgsn_ra_alloc(&ra_id);
+ ra_a = sgsn_ra_alloc(&ra_id, RA_TYPE_GERAN_Gb);
OSMO_ASSERT(ra_a);
OSMO_ASSERT(llist_count(&sgsn->routing_area->ra_list) == 1);
OSMO_ASSERT(llist_count(&ra_a->cells) == 0);
--
To view, visit
https://gerrit.osmocom.org/c/osmo-sgsn/+/40688?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: I59c35f1a4912ff11574bb31e4fe424816993548c
Gerrit-Change-Number: 40688
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis(a)fe80.eu>