aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/bts.h1
-rw-r--r--include/osmo-bts/bts_trx.h1
-rw-r--r--src/common/bts.c1
-rw-r--r--src/common/rsl.c4
-rw-r--r--src/common/sysinfo.c20
-rw-r--r--tests/paging/paging_test.c1
6 files changed, 28 insertions, 0 deletions
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index 191a9f4e..eb0c6637 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -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;
diff --git a/include/osmo-bts/bts_trx.h b/include/osmo-bts/bts_trx.h
index ab90cc51..72522eb1 100644
--- a/include/osmo-bts/bts_trx.h
+++ b/include/osmo-bts/bts_trx.h
@@ -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)
diff --git a/src/common/bts.c b/src/common/bts.c
index a611a9d0..b4a5f804 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -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);
diff --git a/src/common/rsl.c b/src/common/rsl.c
index e0720223..c7450c57 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -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);
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
index b0f1ebfd..f1aee10a 100644
--- a/src/common/sysinfo.c
+++ b/src/common/sysinfo.c
@@ -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)
{
diff --git a/tests/paging/paging_test.c b/tests/paging/paging_test.c
index 05013d09..26f5728a 100644
--- a/tests/paging/paging_test.c
+++ b/tests/paging/paging_test.c
@@ -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;
}