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
This commit is contained in:
Pau Espin Pedrol 2021-02-02 13:11:30 +01:00 committed by laforge
parent 952cb3d5d7
commit 44768f2127
2 changed files with 55 additions and 9 deletions

View File

@ -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.

View File

@ -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) {