aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/l1sap.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-09-30 14:50:39 +0200
committerHarald Welte <laforge@gnumonks.org>2018-09-30 15:50:01 +0200
commit173555dab71d2bcd1e1984a2608e1dd7f0e77dc5 (patch)
tree7bddedb01c0b788ffda8132b42ce51a9898b8787 /src/common/l1sap.c
parent2c1a46a2ddd306f0f6758d5d5af67534adf74c28 (diff)
Fix computing CCCH block number from frame number
The existing implementation used a simplistic macro, which was wrong in many ways: 1) it returned a negative value for "fn % 51 < 5" conditions without raising any error message or asserting 2) it returned a wrong block number for many different input frame numbers, as it didn't account properly for the FCCH/SCH gaps between the blocks Let's replace the simplistic macro with a proper lookup table based on TS 05.02, and let's OSMO_ASSERT() if this is ever called with non-CCCH frame numbers. Change-Id: I11fd6cc558bb61c40c2019e46f56c1fe78ef39f5 Closes: OS#3024
Diffstat (limited to 'src/common/l1sap.c')
-rw-r--r--src/common/l1sap.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index ac4f0bea..0f3cd3a4 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -55,6 +55,41 @@
#include <osmo-bts/pcuif_proto.h>
#include <osmo-bts/cbch.h>
+
+#define CB_FCCH -1
+#define CB_SCH -2
+#define CB_BCCH -3
+#define CB_IDLE -4
+
+/* according to TS 05.02 Clause 7 Table 3 of 9 an Figure 8a */
+static const int ccch_block_table[51] = {
+ CB_FCCH, CB_SCH,/* 0..1 */
+ CB_BCCH, CB_BCCH, CB_BCCH, CB_BCCH, /* 2..5: BCCH */
+ 0, 0, 0, 0, /* 6..9: B0 */
+ CB_FCCH, CB_SCH,/* 10..11 */
+ 1, 1, 1, 1, /* 12..15: B1 */
+ 2, 2, 2, 2, /* 16..19: B2 */
+ CB_FCCH, CB_SCH,/* 20..21 */
+ 3, 3, 3, 3, /* 22..25: B3 */
+ 4, 4, 4, 4, /* 26..29: B4 */
+ CB_FCCH, CB_SCH,/* 30..31 */
+ 5, 5, 5, 5, /* 32..35: B5 */
+ 6, 6, 6, 6, /* 36..39: B6 */
+ CB_FCCH, CB_SCH,/* 40..41 */
+ 7, 7, 7, 7, /* 42..45: B7 */
+ 8, 8, 8, 8, /* 46..49: B8 */
+ -4 /* 50: Idle */
+};
+
+/* determine the CCCH block number based on the frame number */
+unsigned int l1sap_fn2ccch_block(uint32_t fn)
+{
+ int rc = ccch_block_table[fn%51];
+ /* if FN is negative, we were called for something that's not CCCH! */
+ OSMO_ASSERT(rc >= 0);
+ return rc;
+}
+
struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx,
unsigned int chan_nr)
{
@@ -273,7 +308,7 @@ static int gsmtap_ph_data(struct osmo_phsap_prim *l1sap, uint8_t *chan_type,
} else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
/* The sapi depends on DSP configuration, not
* on the actual SYSTEM INFORMATION 3. */
- if (L1SAP_FN2CCCHBLOCK(fn) >= num_agch)
+ if (l1sap_fn2ccch_block(fn) >= num_agch)
*chan_type = GSMTAP_CHANNEL_PCH;
else
*chan_type = GSMTAP_CHANNEL_AGCH;
@@ -686,7 +721,7 @@ int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn) {
/* Note: The number of available access grant channels is set by the
* parameter BS_AG_BLKS_RES via system information type 3. This SI is
* transfered to osmo-bts via RSL */
- return L1SAP_FN2CCCHBLOCK(fn) < num_agch(trx, "PH-RTS-IND");
+ return l1sap_fn2ccch_block(fn) < num_agch(trx, "PH-RTS-IND");
}
/* PH-RTS-IND prim received from bts model */