Fix RadioCarrier OML Operative State Change report not sent on some scenarios

Operative state is mainly maintained based on 2 requirements:
* phy_link being in CONNECTED state
* RSL connection being up and ready

However, state change report triggered over OMl towards BSC was only
done upon the first event of the two. That means that if for whatever
reason the RSL connection was established AFTER the phy_link became
CONNECTED (ie receiving RSP POWERON in osmo-bts-trx), then the status
towards the BSC would not be updated and hence the BSC would still see
the Radio Carrier object as DISABLED.

The trx_set_available() function is renamed to trx_operability_update()
to keep the logic conditions in one place, and different events
triggering a change in state simply call the function and let it handle
the new state.

Related: SYS#5063
Change-Id: Ic00df9e7278d42bc10c1e1a1c0edde7e13199299
This commit is contained in:
Pau Espin 2020-09-15 13:36:02 +02:00
parent 3d085dc6a7
commit 2ff4592ffc
4 changed files with 24 additions and 34 deletions

View File

@ -57,7 +57,7 @@ char *gsm_trx_name(const struct gsm_bts_trx *trx);
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx);
int trx_link_estab(struct gsm_bts_trx *trx);
int trx_set_available(struct gsm_bts_trx *trx, int avail);
void trx_operability_update(struct gsm_bts_trx *trx);
uint8_t num_agch(struct gsm_bts_trx *trx, const char * arg);
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);

View File

@ -17,12 +17,15 @@
*
*/
#include <osmocom/gsm/abis_nm.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/bts_trx.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/phy_link.h>
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
{
@ -158,6 +161,8 @@ int trx_link_estab(struct gsm_bts_trx *trx)
LOGPTRX(trx, DSUM, LOGL_INFO, "RSL link %s\n",
link ? "up" : "down");
trx_operability_update(trx);
if (link)
rc = rsl_tx_rf_res(trx);
else
@ -172,27 +177,23 @@ int trx_link_estab(struct gsm_bts_trx *trx)
return 0;
}
/* set the availability of the TRX (used by PHY driver) */
int trx_set_available(struct gsm_bts_trx *trx, int avail)
/* set the availability of the TRX based on internal state (RSL + phy link) */
void trx_operability_update(struct gsm_bts_trx *trx)
{
int tn;
enum abis_nm_op_state op_st;
enum abis_nm_avail_state avail_st;
struct phy_instance *pinst = trx_phy_instance(trx);
LOGP(DSUM, LOGL_INFO, "TRX(%d): Setting available = %d\n",
trx->nr, avail);
if (avail) {
int op_state = trx->rsl_link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
oml_mo_state_chg(&trx->mo, op_state, NM_AVSTATE_OK);
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
oml_mo_state_chg(&trx->ts[tn].mo, op_state, NM_AVSTATE_OK);
} else {
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_NOT_INSTALLED);
op_st = (trx->rsl_link && phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED) ?
NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
avail_st = (op_st == NM_OPSTATE_ENABLED) ? NM_AVSTATE_OK : NM_AVSTATE_NOT_INSTALLED;
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
}
return 0;
LOGPTRX(trx, DSUM, LOGL_INFO, "Setting operative = %s\n", abis_nm_opstate_name(op_st));
oml_mo_state_chg(&trx->mo, op_st, avail_st);
oml_mo_state_chg(&trx->bb_transc.mo, -1, avail_st);
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
oml_mo_state_chg(&trx->ts[tn].mo, op_st, avail_st);
}

View File

@ -57,28 +57,16 @@ void phy_link_state_set(struct phy_link *plink, enum phy_link_state state)
get_value_string(phy_link_state_vals, plink->state),
get_value_string(phy_link_state_vals, state));
plink->state = state;
/* notify all TRX associated with this phy */
llist_for_each_entry(pinst, &plink->instances, list) {
struct gsm_bts_trx *trx = pinst->trx;
if (!trx)
continue;
switch (state) {
case PHY_LINK_CONNECTED:
LOGPPHI(pinst, DL1C, LOGL_INFO, "trx_set_avail(1)\n");
trx_set_available(trx, 1);
break;
case PHY_LINK_SHUTDOWN:
LOGPPHI(pinst, DL1C, LOGL_INFO, "trx_set_avail(0)\n");
trx_set_available(trx, 0);
break;
case PHY_LINK_CONNECTING:
/* nothing to do */
break;
}
trx_operability_update(trx);
}
plink->state = state;
}
enum phy_link_state phy_link_state_get(struct phy_link *plink)

View File

@ -52,7 +52,8 @@ int osmo_amr_rtp_dec(const uint8_t *rtppayload, int payload_len, uint8_t *cmr,
void bts_model_trx_close(struct gsm_bts_trx *trx)
{
trx_set_available(trx, 0);
struct phy_instance *pinst = trx_phy_instance(trx);
phy_link_state_set(pinst->phy_link, PHY_LINK_SHUTDOWN);
bts_model_trx_close_cb(trx, 0);
}