aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@espeweb.net>2021-02-02 13:11:30 +0100
committerlaforge <laforge@osmocom.org>2021-02-03 08:34:12 +0000
commit44768f21273cf56919850ed8c3197b174bce65ef (patch)
tree6f94699e84f2006df2af8a27a1acffb5b8fef589
parent952cb3d5d7e07c3e22aac080a3d3ddc7925093c3 (diff)
nacc: Avoid RIM procedures targeting cells under same PCU
Now that we have the required System Information in osmo-pcu to craft the Packet Neigbour Cell Change packet for cells it controls, let's avoid starting a RIM procedure to gather the SI info, since the SGSN would end up routing the RIM request back at us and we'd answer back to ourselves. This same optimization cannot be done on the first step (CTRL Neighbor Resolution against BSC), because the PCU cannot know if the target ARFCN+BSIC requested by the MS is actually managed by a cell under the PCU or it's another cell managed by another external PCU, because ARFCN+BSIC keys can be resued among non-neighbor cells. Hence, it shall always ask the BSC since only it holds the information about neighboring cells. Related: OS#4909 Change-Id: I928875b6b66dff55fc12f51b6b1ad919fef7d03b
-rw-r--r--doc/manuals/chapters/configuration.adoc23
-rw-r--r--src/nacc_fsm.c41
2 files changed, 55 insertions, 9 deletions
diff --git a/doc/manuals/chapters/configuration.adoc b/doc/manuals/chapters/configuration.adoc
index 7371e728..01e4d652 100644
--- a/doc/manuals/chapters/configuration.adoc
+++ b/doc/manuals/chapters/configuration.adoc
@@ -236,9 +236,8 @@ OsmoPCU instance, since it already has the System Information of all BTS under
their control, obtained through PCUIF when the BTS registers against OsmoPCU, so
no specific user configuration is required here.
-However, for remote neighbors (cells managed by another OsmoPCU instance),
-OsmoPCU requires to gather the information from somewhere else before being able
-to provide it to the MS requesting the NACC.
+In general, OsmoPCU requires to gather the information from somewhere else
+before being able to provide it to the MS requesting the NACC.
If OsmoPCU fails to gather the System Information, it will simply answer the MS
allowing the proposed changed but without previously providing the System
@@ -280,13 +279,19 @@ pcu
==== System Information Resolution
Once OsmoPCU gains knowledge of the target cell's address in the Core Network,
-it can query its System Information. The query is done using RIM procedures
-(NACC RAN-INFO application) over the Gb interface against the SGSN that OsmoPCU
-is connected to. In its turn, the SGSN will potentially forward this query to
-the PCU serving the target cell, which will provide back the System Information
-of that cell.
+it can query its System Information.
-The System Information received from remote neighbors are by default
+OsmoPCU will gather the requested System Information of target cells under its
+control without need for any external query, since the System Information of all
+BTSs it manages are received over PCUIF and stored internally in OsmoPCU.
+
+For those targets cells not managed by the OsmoPCU instance, the query is
+accomplished by using RIM procedures (NACC RAN-INFO application) over the Gb
+interface against the SGSN that OsmoPCU is connected to. In its turn, the SGSN
+will potentially forward this query to the PCU serving the target cell, which
+will provide back the System Information of that cell.
+
+The System Information received from external PCUs over RIM are by default
cached for a while in order to avoid querying the SGSN frequently and, as a
result, optimizing the resolution time too.
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index b479f9c6..6a92f83c 100644
--- a/src/nacc_fsm.c
+++ b/src/nacc_fsm.c
@@ -268,6 +268,27 @@ static int fill_rim_ran_info_req(const struct nacc_fsm_ctx *ctx, struct bssgp_ra
return 0;
}
+#define SI_HDR_LEN 2
+static void bts_fill_si_cache_value(const struct gprs_rlcmac_bts *bts, struct si_cache_value *val)
+{
+ val->type_psi = false;
+ val->si_len = 0;
+ if (bts->si1_is_set) {
+ osmo_static_assert(sizeof(bts->si1) - SI_HDR_LEN == BSSGP_RIM_SI_LEN, _si1_header_size);
+ memcpy(&val->si_buf[val->si_len], bts->si1 + SI_HDR_LEN, BSSGP_RIM_SI_LEN);
+ val->si_len += BSSGP_RIM_SI_LEN;
+ }
+ if (bts->si3_is_set) {
+ osmo_static_assert(sizeof(bts->si3) - SI_HDR_LEN == BSSGP_RIM_SI_LEN, _si3_header_size);
+ memcpy(&val->si_buf[val->si_len], bts->si3 + SI_HDR_LEN, BSSGP_RIM_SI_LEN);
+ val->si_len += BSSGP_RIM_SI_LEN;
+ }
+ if (bts->si13_is_set) {
+ osmo_static_assert(sizeof(bts->si13) - SI_HDR_LEN == BSSGP_RIM_SI_LEN, _si13_header_size);
+ memcpy(&val->si_buf[val->si_len], bts->si13 + SI_HDR_LEN, BSSGP_RIM_SI_LEN);
+ val->si_len += BSSGP_RIM_SI_LEN;
+ }
+}
////////////////
// FSM states //
@@ -382,8 +403,28 @@ static void st_wait_request_si_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_
struct gprs_pcu *pcu = bts->pcu;
struct bssgp_ran_information_pdu pdu;
const struct si_cache_value *si;
+ struct gprs_rlcmac_bts *bts_i;
int rc;
+ /* First check if the CGI-PS addresses a cell managed by this PCU. If
+ * that's the case, we already have the info and there's no need to go
+ * the RIM way since we'd end up to this same PCU on the other end anyway.
+ */
+ llist_for_each_entry(bts_i, &the_pcu->bts_list, list) {
+ if (bts_i == bts) /* Makes no sense targeting the same cell */
+ continue;
+ if (osmo_cgi_ps_cmp(&ctx->cgi_ps, &bts_i->cgi_ps) != 0)
+ continue;
+
+ LOGPFSML(fi, LOGL_DEBUG, "neighbor CGI-PS %s addresses local BTS %d\n",
+ osmo_cgi_ps_name(&ctx->cgi_ps), bts_i->nr);
+ bts_fill_si_cache_value(bts, &ctx->si_info);
+ /* Tell the PCU scheduler we are ready to go, from here one we
+ * are polled/driven by the scheduler */
+ nacc_fsm_state_chg(fi, NACC_ST_TX_NEIGHBOUR_DATA);
+ return;
+ }
+
/* First check if we have SI info for the target cell in cache */
si = si_cache_lookup_value(pcu->si_cache, &ctx->cgi_ps);
if (si) {