aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-06-26 10:10:28 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2023-07-21 13:20:12 +0200
commit467d63e387646f26ee6d8b697b667b312418c656 (patch)
tree676407e88a9f29b31c30a605b711c957ecdf00ac
parentbe93b87a64067e3f023ab5ddf029a5daaa46fbe4 (diff)
Add test cases for rest octets of Paging Requests
The abstract representation of the rest octets are moved to the header file, so that the test case can include it. append_p*_rest_octets() function become externally available for test. Change-Id: Ifa5be8998b671160e38af1be707e040b00d407b8 Related: OS#5781
-rw-r--r--include/osmo-bts/paging.h55
-rw-r--r--src/common/paging.c56
-rw-r--r--tests/paging/paging_test.c165
3 files changed, 224 insertions, 52 deletions
diff --git a/include/osmo-bts/paging.h b/include/osmo-bts/paging.h
index d6045369..93e7b380 100644
--- a/include/osmo-bts/paging.h
+++ b/include/osmo-bts/paging.h
@@ -7,6 +7,55 @@
struct paging_state;
struct gsm_bts;
+struct asci_notification;
+
+/* abstract representation of P1 rest octets; we only implement those parts we need for now */
+struct p1_rest_octets {
+ struct {
+ bool present;
+ uint8_t nln;
+ uint8_t nln_status;
+ } nln_pch;
+ bool packet_page_ind[2];
+ bool r8_present;
+ struct {
+ bool prio_ul_access;
+ bool etws_present;
+ struct {
+ bool is_first;
+ uint8_t page_nr;
+ const uint8_t *page;
+ size_t page_bytes;
+ } etws;
+ } r8;
+};
+
+/* abstract representation of P2 rest octets; we only implement those parts we need for now */
+struct p2_rest_octets {
+ struct {
+ bool present;
+ uint8_t cn3;
+ } cneed;
+ struct {
+ bool present;
+ uint8_t nln;
+ uint8_t nln_status;
+ } nln_pch;
+};
+
+/* abstract representation of P3 rest octets; we only implement those parts we need for now */
+struct p3_rest_octets {
+ struct {
+ bool present;
+ uint8_t cn3;
+ uint8_t cn4;
+ } cneed;
+ struct {
+ bool present;
+ uint8_t nln;
+ uint8_t nln_status;
+ } nln_pch;
+};
/* initialize paging code */
struct paging_state *paging_init(struct gsm_bts *bts,
@@ -39,6 +88,12 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
* PAGING COMMAND (from the PCU) */
int paging_add_macblock(struct paging_state *ps, uint32_t tlli, const char *imsi, bool confirm, const uint8_t *macblock);
+/* Paging rest octests */
+void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
+ const struct asci_notification *notif);
+void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro);
+void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro);
+
/* generate paging message for given gsm time */
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
int *is_empty);
diff --git a/src/common/paging.c b/src/common/paging.c
index d4a3aedb..914a4b5e 100644
--- a/src/common/paging.c
+++ b/src/common/paging.c
@@ -332,54 +332,6 @@ int paging_add_macblock(struct paging_state *ps, uint32_t tlli, const char *imsi
#define L2_PLEN(len) (((len - 1) << 2) | 0x01)
-/* abstract representation of P1 rest octets; we only implement those parts we need for now */
-struct p1_rest_octets {
- struct {
- bool present;
- uint8_t nln;
- uint8_t nln_status;
- } nln_pch;
- bool packet_page_ind[2];
- bool r8_present;
- struct {
- bool prio_ul_access;
- bool etws_present;
- struct {
- bool is_first;
- uint8_t page_nr;
- const uint8_t *page;
- size_t page_bytes;
- } etws;
- } r8;
-};
-
-/* abstract representation of P2 rest octets; we only implement those parts we need for now */
-struct p2_rest_octets {
- struct {
- bool present;
- uint8_t cn3;
- } cneed;
- struct {
- bool present;
- uint8_t nln;
- uint8_t nln_status;
- } nln_pch;
-};
-
-/* abstract representation of P3 rest octets; we only implement those parts we need for now */
-struct p3_rest_octets {
- struct {
- bool present;
- uint8_t cn3;
- uint8_t cn4;
- } cneed;
- struct {
- bool present;
- uint8_t nln;
- uint8_t nln_status;
- } nln_pch;
-};
-
/* 3GPP TS 44.018 10.5.2.23 append a segment/page of an ETWS primary notification to given bitvec */
static void append_etws_prim_notif(struct bitvec *bv, bool is_first, uint8_t page_nr,
const uint8_t *etws, ssize_t etws_len)
@@ -406,8 +358,8 @@ static void append_etws_prim_notif(struct bitvec *bv, bool is_first, uint8_t pag
}
/* 3GPP TS 44.018 10.5.2.23 append P1 Rest Octets to given bit-vector */
-static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
- const struct asci_notification *notif)
+void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
+ const struct asci_notification *notif)
{
/* Paging 1 RO (at least 10 bits before ETWS struct) */
if (p1ro->nln_pch.present) {
@@ -452,7 +404,7 @@ static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets
}
/* 3GPP TS 44.018 10.5.2.24 append P2 Rest Octets to given bit-vector */
-static void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro)
+void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro)
{
/* {L | H <CN3: bit (2)>} */
if (p2ro->cneed.present) {
@@ -473,7 +425,7 @@ static void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets
}
/* 3GPP TS 44.018 10.5.2.25 append P3 Rest Octets to given bit-vector */
-static void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro)
+void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro)
{
/* {L | H <CN3: bit (2)> <CN3: bit (2)>} */
if (p3ro->cneed.present) {
diff --git a/tests/paging/paging_test.c b/tests/paging/paging_test.c
index d48932bb..1bccc85a 100644
--- a/tests/paging/paging_test.c
+++ b/tests/paging/paging_test.c
@@ -27,6 +27,7 @@
#include <osmo-bts/paging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/l1sap.h>
+#include <osmo-bts/notification.h>
#include <unistd.h>
@@ -179,6 +180,167 @@ static void test_is_ccch_for_agch(void)
}
}
+static void test_paging_rest_octets1(void)
+{
+ uint8_t out_buf[17];
+ struct p1_rest_octets p1ro = {};
+ struct asci_notification notif = {};
+
+ struct bitvec bv = {
+ .data_len = sizeof(out_buf),
+ .data = out_buf,
+ };
+
+ /* no rest */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ append_p1_rest_octets(&bv, &p1ro, NULL);
+ ASSERT_TRUE(out_buf[0] == 0x2b);
+
+ /* add NLN */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p1ro.nln_pch.present = true;
+ p1ro.nln_pch.nln = 3;
+ p1ro.nln_pch.nln_status = 1;
+ append_p1_rest_octets(&bv, &p1ro, NULL);
+ ASSERT_TRUE(out_buf[0] == 0xfb); /* H 1 11 1 */
+ p1ro.nln_pch.present = 0;
+
+ /* add group callref */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ notif.group_call_ref[0] = 0x12;
+ notif.group_call_ref[1] = 0x34;
+ notif.group_call_ref[2] = 0x56;
+ notif.group_call_ref[3] = 0x78;
+ notif.group_call_ref[4] = 0x90;
+ notif.chan_desc.present = true;
+ notif.chan_desc.len = 3;
+ notif.chan_desc.value[0] = 0x20;
+ notif.chan_desc.value[1] = 0x40;
+ notif.chan_desc.value[2] = 0x80;
+ append_p1_rest_octets(&bv, &p1ro, &notif);
+ ASSERT_TRUE(out_buf[0] == 0x31); /* L L L H 0x123456789 */
+ ASSERT_TRUE(out_buf[1] == 0x23);
+ ASSERT_TRUE(out_buf[2] == 0x45);
+ ASSERT_TRUE(out_buf[3] == 0x67);
+ ASSERT_TRUE(out_buf[4] == 0x89);
+ ASSERT_TRUE(out_buf[5] == 0x90); /* H 0x204080 0 */
+ ASSERT_TRUE(out_buf[6] == 0x20);
+ ASSERT_TRUE(out_buf[7] == 0x40);
+ ASSERT_TRUE(out_buf[8] == 0x2b);
+
+ /* add Packet Page Indication 1 */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p1ro.packet_page_ind[0] = true;
+ append_p1_rest_octets(&bv, &p1ro, NULL);
+ ASSERT_TRUE(out_buf[0] == 0x23); /* L L L L H L L L */
+ p1ro.packet_page_ind[0] = false;
+
+ /* add Packet Page Indication 2 */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p1ro.packet_page_ind[1] = true;
+ append_p1_rest_octets(&bv, &p1ro, NULL);
+ ASSERT_TRUE(out_buf[0] == 0x2f); /* L L L L L H L L */
+ p1ro.packet_page_ind[1] = false;
+
+ /* add ETWS */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p1ro.r8_present = true;
+ p1ro.r8.prio_ul_access = true;
+ p1ro.r8.etws_present = true;
+ p1ro.r8.etws.is_first = true;
+ p1ro.r8.etws.page_nr = 0x5;
+ uint8_t page[] = { 0x22, 0x44, 0x66 };
+ p1ro.r8.etws.page_bytes = sizeof(page);
+ p1ro.r8.etws.page = page;
+ append_p1_rest_octets(&bv, &p1ro, NULL);
+ ASSERT_TRUE(out_buf[0] == 0x2b); /* L L L L L L L L */
+ ASSERT_TRUE(out_buf[1] == 0xe5); /* H 1 1 0 0x5 */
+ ASSERT_TRUE(out_buf[2] == 0x18); /* 0 len=24=0x18 */
+ ASSERT_TRUE(out_buf[3] == 0x22); /* 0x224488 */
+ ASSERT_TRUE(out_buf[4] == 0x44);
+ ASSERT_TRUE(out_buf[5] == 0x66);
+ p1ro.r8_present = false;
+}
+
+static void test_paging_rest_octets2(void)
+{
+ uint8_t out_buf[11];
+ struct p2_rest_octets p2ro = {};
+
+ struct bitvec bv = {
+ .data_len = sizeof(out_buf),
+ .data = out_buf,
+ };
+
+ /* nothing added */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ append_p2_rest_octets(&bv, &p2ro);
+ ASSERT_TRUE(out_buf[0] == 0x2b); /* L L */
+
+ /* add cneed */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p2ro.cneed.present = true;
+ p2ro.cneed.cn3 = 3;
+ append_p2_rest_octets(&bv, &p2ro);
+ ASSERT_TRUE(out_buf[0] == 0xeb); /* H 1 1 L */
+ p2ro.cneed.present = false;
+
+ /* add NLN */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p2ro.nln_pch.present = true;
+ p2ro.nln_pch.nln = 3;
+ p2ro.nln_pch.nln_status = 1;
+ append_p2_rest_octets(&bv, &p2ro);
+ ASSERT_TRUE(out_buf[0] == 0x7b); /* L H 1 11 1 */
+ p2ro.nln_pch.present = 0;
+}
+
+static void test_paging_rest_octets3(void)
+{
+ uint8_t out_buf[3];
+ struct p3_rest_octets p3ro = {};
+
+ struct bitvec bv = {
+ .data_len = sizeof(out_buf),
+ .data = out_buf,
+ };
+
+ /* nothing added */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ append_p3_rest_octets(&bv, &p3ro);
+ ASSERT_TRUE(out_buf[0] == 0x2b); /* L L */
+
+ /* add cneed */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p3ro.cneed.present = true;
+ p3ro.cneed.cn3 = 3;
+ p3ro.cneed.cn4 = 3;
+ append_p3_rest_octets(&bv, &p3ro);
+ ASSERT_TRUE(out_buf[0] == 0xfb); /* H 1 1 1 1 L */
+ p3ro.cneed.present = false;
+
+ /* add NLN */
+ memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf));
+ bv.cur_bit = 0;
+ p3ro.nln_pch.present = true;
+ p3ro.nln_pch.nln = 3;
+ p3ro.nln_pch.nln_status = 1;
+ append_p3_rest_octets(&bv, &p3ro);
+ ASSERT_TRUE(out_buf[0] == 0x7b); /* L H 1 11 1 */
+ p3ro.nln_pch.present = 0;
+}
+
int main(int argc, char **argv)
{
tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context");
@@ -200,6 +362,9 @@ int main(int argc, char **argv)
test_paging_smoke();
test_paging_sleep();
test_is_ccch_for_agch();
+ test_paging_rest_octets1();
+ test_paging_rest_octets2();
+ test_paging_rest_octets3();
printf("Success\n");
return 0;