diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-09-30 14:50:39 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-09-30 15:50:01 +0200 |
commit | 173555dab71d2bcd1e1984a2608e1dd7f0e77dc5 (patch) | |
tree | 7bddedb01c0b788ffda8132b42ce51a9898b8787 /src/common/l1sap.c | |
parent | 2c1a46a2ddd306f0f6758d5d5af67534adf74c28 (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.c | 39 |
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 */ |