aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
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
Diffstat (limited to 'src')
-rw-r--r--src/nacc_fsm.c41
1 files changed, 41 insertions, 0 deletions
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) {