lynxis lazus has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-sgsn/+/40813?usp=email )
Change subject: WIP iuh
......................................................................
WIP iuh
Change-Id: I1b1aedd2a7c358bd388aa3d8a9f3c6a0011b4889
---
M include/osmocom/sgsn/gprs_routing_area.h
M src/sgsn/gprs_ranap.c
M src/sgsn/gprs_routing_area.c
3 files changed, 93 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/13/40813/1
diff --git a/include/osmocom/sgsn/gprs_routing_area.h
b/include/osmocom/sgsn/gprs_routing_area.h
index 1e60ccc..c32e332 100644
--- a/include/osmocom/sgsn/gprs_routing_area.h
+++ b/include/osmocom/sgsn/gprs_routing_area.h
@@ -56,6 +56,12 @@
* For UTRAN only do a LAC/RAC <> RNC relation and don't have a specific cell
relation.
*/
enum sgsn_ra_ran_type ran_type;
+ union {
+ struct {
+ /* the RNC id must be the same for a given Routing Area */
+ struct osmo_rnc_id rnc_id;
+ } utran;
+ } u;
/* GERAN/UTRAN: cells contains a list of sgsn_ra_cells which are alive */
struct llist_head cells_alive_list;
@@ -77,8 +83,7 @@
} geran;
struct {
- /* TODO: unused */
- uint16_t rncid;
+ /* the RNC id must be the same for a given Routing Area */
uint16_t sac;
} utran;
} u;
@@ -100,14 +105,18 @@
/* Called by NS-VC layer to inform about an unavailable NSEI (and all BVCI on them) */
int sgsn_ra_nsei_failure_ind(uint16_t nsei);
+/* UTRAN */
+int sgsn_ra_utran_register(const struct osmo_routing_area_id *rai, const struct
osmo_rnc_id *rnc_id);
+
struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi_ps(const struct osmo_cell_global_id_ps
*cgi_ps);
struct sgsn_ra_cell *sgsn_ra_get_cell_by_lai(const struct osmo_location_area_id *lai,
uint16_t cell_id);
struct sgsn_ra_cell *sgsn_ra_get_cell_by_cgi(const struct osmo_cell_global_id *cgi);
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 *rai);
struct sgsn_ra *sgsn_ra_get_ra_geran(const struct osmo_routing_area_id *rai);
-
+struct sgsn_ra *sgsn_ra_get_ra_utran(const struct osmo_routing_area_id *rai);
/*
* return value for callbacks.
@@ -125,3 +134,4 @@
/* Page the whole routing area for this mmctx */
int sgsn_ra_geran_page_ra(const struct osmo_routing_area_id *rai, struct sgsn_mm_ctx
*mmctx);
+int sgsn_ra_utran_page_ra(const struct osmo_routing_area_id *rai, const struct
sgsn_mm_ctx *mmctx);
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index 3252ee6..2ff7397 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -38,6 +38,7 @@
#include <osmocom/sgsn/gprs_ranap.h>
#include <osmocom/sgsn/gprs_gmm_attach.h>
#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+#include <osmocom/sgsn/gprs_routing_area.h>
#include <osmocom/sgsn/gtp_ggsn.h>
#include <osmocom/sgsn/gtp.h>
#include <osmocom/sgsn/pdpctx.h>
@@ -202,12 +203,24 @@
int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type,
void *data)
{
+ struct ranap_iu_event_new_area *new_area;
+
switch (type) {
case RANAP_IU_EVENT_RAB_ASSIGN:
case RANAP_IU_EVENT_IU_RELEASE:
case RANAP_IU_EVENT_LINK_INVALIDATED:
case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
return sgsn_ranap_iu_event_mmctx(ctx, type, data);
+ case RANAP_IU_EVENT_NEW_AREA:
+ /* inform the Routing Area code about a new RA for Iu */
+ new_area = data;
+
+ /* Only interesting in Routing Area changes, but not Location Area */
+ if (new_area->cell_type != RANAP_IU_NEW_RAC) {
+ return 0;
+ }
+
+ return sgsn_ra_utran_register(new_area->u.rai, new_area->rnc_id);
default:
LOGP(DRANAP, LOGL_NOTICE, "Iu: Unknown event received: type: %d\n", type);
return -1;
diff --git a/src/sgsn/gprs_routing_area.c b/src/sgsn/gprs_routing_area.c
index 40bee05..9a84c02 100644
--- a/src/sgsn/gprs_routing_area.c
+++ b/src/sgsn/gprs_routing_area.c
@@ -24,6 +24,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsm23003.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gprs_bssgp.h>
@@ -150,6 +151,19 @@
return NULL;
}
+struct sgsn_ra *sgsn_ra_get_ra_utran(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_UTRAN_Iu)
+ return ra;
+
+ return NULL;
+}
+
struct sgsn_ra_cell *sgsn_ra_get_cell_by_gb(uint16_t nsei, uint16_t bvci)
{
struct sgsn_ra *ra;
@@ -390,6 +404,42 @@
sgsn_ra_nsei_failure_ind(nsei);
}
+/* Register a new UTRAN Routing Area if possible.
+ * Return 0 on success and < 0 on failure. */
+int sgsn_ra_utran_register(const struct osmo_routing_area_id *rai, const struct
osmo_rnc_id *rnc_id)
+{
+ struct sgsn_ra *ra = sgsn_ra_get_ra(rai);
+ if (!ra) {
+ ra = sgsn_ra_alloc(rai, RA_TYPE_UTRAN_Iu);
+ if (!ra) {
+ LOGP(DRA, LOGL_ERROR, "Couldn't create new RA for %s ran type %s\n",
+ osmo_rai_name2(rai), get_value_string(sgsn_ra_ran_type_names, ra->ran_type));
+ return -ENOMEM;
+ }
+ ra->u.utran.rnc_id = *rnc_id;
+ }
+
+ if (ra->ran_type == RA_TYPE_UTRAN_Iu) {
+ if (osmo_rnc_id_cmp(&ra->u.utran.rnc_id, rnc_id) == 0)
+ return 0;
+
+ char new_rnc_id_name[32];
+ osmo_rnc_id_name_buf(new_rnc_id_name, sizeof(new_rnc_id_name), rnc_id);
+ LOGRA(LOGL_INFO, ra, "RNC Id changed from %s to %s\n",
+ osmo_rnc_id_name(&ra->u.utran.rnc_id), new_rnc_id_name);
+
+ ra->u.utran.rnc_id = *rnc_id;
+ return 0;
+ } else {
+ LOGRA(LOGL_ERROR, ra, "rejecting new RA of type %s, because already present RA has
ran type %s\n",
+ get_value_string(sgsn_ra_ran_type_names, RA_TYPE_UTRAN_Iu),
+ get_value_string(sgsn_ra_ran_type_names, ra->ran_type));
+ return -ENOENT;
+ }
+
+ return -ENOENT;
+}
+
int sgsn_ra_geran_page_ra(const struct osmo_routing_area_id *rai, struct sgsn_mm_ctx
*mmctx)
{
struct sgsn_ra *ra;
@@ -413,6 +463,23 @@
return ret;
}
+int sgsn_ra_utran_page_ra(const struct osmo_routing_area_id *ra_id, const struct
sgsn_mm_ctx *mmctx)
+{
+ struct sgsn_ra *ra;
+ rate_ctr_inc(rate_ctr_group_get_ctr(mmctx->ctrg, GMM_CTR_PAGING_PS));
+
+ ra = sgsn_ra_get_ra_utran(ra_id);
+ if (!ra)
+ return -ENOENT;
+
+ if (mmctx->p_tmsi != GSM_RESERVED_TMSI)
+ return ranap_iu_page_ps2(mmctx->imsi, &mmctx->p_tmsi, ra_id);
+ else if (mmctx->p_tmsi_old != GSM_RESERVED_TMSI)
+ return ranap_iu_page_ps2(mmctx->imsi, &mmctx->p_tmsi_old, ra_id);
+ else
+ return ranap_iu_page_ps2(mmctx->imsi, NULL, ra_id);
+}
+
void sgsn_ra_init(struct sgsn_instance *inst)
{
inst->routing_area = talloc_zero(inst, struct sgsn_ra_global);
--
To view, visit
https://gerrit.osmocom.org/c/osmo-sgsn/+/40813?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: I1b1aedd2a7c358bd388aa3d8a9f3c6a0011b4889
Gerrit-Change-Number: 40813
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis(a)fe80.eu>