aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/l1sap.h3
-rw-r--r--src/common/l1sap.c15
-rw-r--r--tests/paging/paging_test.c55
-rw-r--r--tests/paging/paging_test.ok21
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