ASCI: Retrieve NCH position from System Information 1

When BCCH INFO is received via RSL message, the rest octet of the System
Information 1 message is parsed to get the position of the NCH. The
position is stored in the gsm_bts structure. If the position is not
present int the rest octet, the stored value is set to negative.

Change-Id: I799a27179d478d4ff577d8bc47ae524834851e85
Related: OS#5781
This commit is contained in:
Andreas Eversberg
2023-05-31 12:02:22 +02:00
parent 98e5d6f7c6
commit 65c8f0de94
6 changed files with 28 additions and 0 deletions

View File

@@ -295,6 +295,7 @@ struct gsm_bts {
/* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */
struct {
int pos_nch; /* position of the NCH or < 0, if not available */
struct llist_head notifications;
} asci;

View File

@@ -58,6 +58,7 @@ int trx_link_estab(struct gsm_bts_trx *trx);
void trx_operability_update(struct gsm_bts_trx *trx);
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
int pos_nch(const struct gsm_bts_trx *trx, const char *arg);
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)

View File

@@ -404,6 +404,7 @@ int bts_init(struct gsm_bts *bts)
bts->smscb_queue_tgt_len = 2;
bts->smscb_queue_hyst = 2;
bts->asci.pos_nch = -ENOTSUP;
INIT_LLIST_HEAD(&bts->asci.notifications);
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);

View File

@@ -640,6 +640,10 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg)
}
break;
case SYSINFO_TYPE_1:
/* Get the position of the NCH, if enabled. */
trx->bts->asci.pos_nch = pos_nch(trx, "BCCH INFO");
pcu_tx_si(trx->bts, SYSINFO_TYPE_1, true);
break;
case SYSINFO_TYPE_2:
case SYSINFO_TYPE_13:
pcu_tx_si(trx->bts, osmo_si, true);

View File

@@ -164,6 +164,26 @@ uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg)
return 1;
}
/* Returns position of the NCH accroding to SI1 rest octets. See Table 10.5.2.32.1 of TS 44.018.
* Returns < 0, if not present. */
int pos_nch(const struct gsm_bts_trx *trx, const char *arg)
{
const struct gsm_bts *b = trx->bts;
const struct gsm48_system_information_type_1 *si1;
if (GSM_BTS_HAS_SI(b, SYSINFO_TYPE_1)) {
si1 = GSM_BTS_SI(b, SYSINFO_TYPE_1);
if (si1->rest_octets[0] & 0x80) {
/* H <NCH Position : bit (5)> */
return (si1->rest_octets[0] >> 2) & 0x1f;
}
return -ENOTSUP;
}
LOGP(DL1P, LOGL_NOTICE, "%s: Unable to determine actual NCH Position "
"value as SI1 is not available yet.\n", arg);
return -EINVAL;
}
/* re-generate SI3 restoctets with GPRS indicator depending on the PCU socket connection state */
void regenerate_si3_restoctets(struct gsm_bts *bts)
{

View File

@@ -134,6 +134,7 @@ static struct gsm_bts_trx *test_is_ccch_for_agch_setup(uint8_t bs_ag_blks_res)
si3.control_channel_desc.bs_ag_blks_res = bs_ag_blks_res;
trx.bts = &bts;
bts.si_valid |= 0x8;
bts.asci.pos_nch = -1;
memcpy(&bts.si_buf[SYSINFO_TYPE_3][0], &si3, sizeof(si3));
return &trx;
}