diff options
-rw-r--r-- | include/osmo-bts/l1sap.h | 3 | ||||
-rw-r--r-- | src/common/l1sap.c | 15 | ||||
-rw-r--r-- | tests/paging/paging_test.c | 55 | ||||
-rw-r--r-- | tests/paging/paging_test.ok | 21 |
4 files changed, 91 insertions, 3 deletions
diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index ad13145b..4568b7ed 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -93,4 +93,7 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, uint8_t *data, int len); + +int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn); + #endif /* L1SAP_H */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index b8cec0e7..55b4a4bb 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -666,6 +666,15 @@ static int lchan_pdtch_ph_rts_ind_loop(struct gsm_lchan *lchan, return 0; } +/* Check if given CCCH frame number is for a PCH or for an AGCH (this function is + * only used internally, it is public to call it from unit-tests) */ +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"); +} + /* PH-RTS-IND prim received from bts model */ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind) @@ -681,6 +690,7 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim pp; bool dtxd_facch = false; int rc; + int is_ag_res; chan_nr = rts_ind->chan_nr; link_id = rts_ind->link_id; @@ -783,9 +793,8 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, } } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { p = msgb_put(msg, GSM_MACBLOCK_LEN); - rc = bts_ccch_copy_msg(trx->bts, p, &g_time, - (L1SAP_FN2CCCHBLOCK(fn) < - num_agch(trx, "PH-RTS-IND"))); + is_ag_res = is_ccch_for_agch(trx, fn); + rc = bts_ccch_copy_msg(trx->bts, p, &g_time, is_ag_res); if (rc <= 0) memcpy(p, fill_frame, GSM_MACBLOCK_LEN); } diff --git a/tests/paging/paging_test.c b/tests/paging/paging_test.c index 0accd0fb..1fc7d928 100644 --- a/tests/paging/paging_test.c +++ b/tests/paging/paging_test.c @@ -25,6 +25,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/paging.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/l1sap.h> #include <unistd.h> @@ -110,6 +111,59 @@ static void test_paging_sleep(void) ASSERT_TRUE(paging_queue_length(bts->paging_state) == 0); } +/* Set up a dummy trx with a valid setting for bs_ag_blks_res in SI3 */ +static struct gsm_bts_trx *test_is_ccch_for_agch_setup(uint8_t bs_ag_blks_res) +{ + static struct gsm_bts_trx trx; + static struct gsm_bts bts; + struct gsm48_system_information_type_3 si3; + si3.control_channel_desc.bs_ag_blks_res = bs_ag_blks_res; + trx.bts = &bts; + bts.si_valid |= 0x8; + memcpy(&bts.si_buf[SYSINFO_TYPE_3][0], &si3, sizeof(si3)); + return &trx; +} + +/* Walk through all possible settings for bs_ag_blks_res for two + * multiframe 51. The patterns shown in 3GPP TS 05.02 Clause 7 + * Table 5 of 9 must occur. */ +static void test_is_ccch_for_agch(void) +{ + int is_ag_res; + int fn; + uint8_t bs_ag_blks_res; + struct gsm_bts_trx *trx; + + printf("Fn: AGCH: (bs_ag_blks_res=[0:7]\n"); + for (fn = 0; fn < 102; fn++) { + + /* Note: the formula that computes the CCCH block number for a + * given frame number is optimized to work on block boarders, + * for frame numbers that do not fall at the beginning of the + * related block this formula would produce wrong results, so + * we only check with frame numbers that mark the beginning + * of a new block. See also L1SAP_FN2CCCHBLOCK() in l1sap.h */ + + if (fn % 10 != 2 && fn % 10 != 6) + continue; + + printf("%03u: ", fn); + + if (fn % 50 == 2) { + printf(" . . . . . . . . (BCCH)\n"); + continue; + } + + /* Try allo possible settings for bs_ag_blks_res */ + for (bs_ag_blks_res = 0; bs_ag_blks_res <= 7; bs_ag_blks_res++) { + trx = test_is_ccch_for_agch_setup(bs_ag_blks_res); + is_ag_res = is_ccch_for_agch(trx, fn); + printf(" %u", is_ag_res); + } + printf("\n"); + } +} + int main(int argc, char **argv) { tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); @@ -125,6 +179,7 @@ int main(int argc, char **argv) test_paging_smoke(); test_paging_sleep(); + test_is_ccch_for_agch(); printf("Success\n"); return 0; diff --git a/tests/paging/paging_test.ok b/tests/paging/paging_test.ok index 57565e24..50006ec9 100644 --- a/tests/paging/paging_test.ok +++ b/tests/paging/paging_test.ok @@ -1,3 +1,24 @@ Testing that paging messages expire. Testing that paging messages expire with sleep. +Fn: AGCH: (bs_ag_blks_res=[0:7] +002: . . . . . . . . (BCCH) +006: 0 1 1 1 1 1 1 1 +012: 0 0 1 1 1 1 1 1 +016: 0 0 0 1 1 1 1 1 +022: 0 0 0 0 1 1 1 1 +026: 0 0 0 0 0 1 1 1 +032: 0 0 0 0 0 0 1 1 +036: 0 0 0 0 0 0 0 1 +042: 0 0 0 0 0 0 0 0 +046: 0 0 0 0 0 0 0 0 +052: . . . . . . . . (BCCH) +056: 0 1 1 1 1 1 1 1 +062: 0 0 1 1 1 1 1 1 +066: 0 0 0 1 1 1 1 1 +072: 0 0 0 0 1 1 1 1 +076: 0 0 0 0 0 1 1 1 +082: 0 0 0 0 0 0 1 1 +086: 0 0 0 0 0 0 0 1 +092: 0 0 0 0 0 0 0 0 +096: 0 0 0 0 0 0 0 0 Success |