aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gsm/gsm0808.h3
-rw-r--r--src/gsm/gsm0808.c52
-rw-r--r--src/gsm/libosmogsm.map1
-rw-r--r--tests/gsm0808/gsm0808_test.c42
-rw-r--r--tests/gsm0808/gsm0808_test.ok1
5 files changed, 99 insertions, 0 deletions
diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h
index 9738a554..990fd74d 100644
--- a/include/osmocom/gsm/gsm0808.h
+++ b/include/osmocom/gsm/gsm0808.h
@@ -57,6 +57,9 @@ struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause,
*scl);
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
struct msgb *gsm0808_create_clear_rqst(uint8_t cause);
+struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi,
+ const struct gsm0808_cell_id_list *cil,
+ const uint8_t *chan_needed);
struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id);
void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id);
diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c
index c952a9f8..2721a1b1 100644
--- a/src/gsm/gsm0808.c
+++ b/src/gsm/gsm0808.c
@@ -347,6 +347,58 @@ struct msgb *gsm0808_create_clear_rqst(uint8_t cause)
return msg;
}
+struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi,
+ const struct gsm0808_cell_id_list *cil,
+ const uint8_t *chan_needed)
+{
+ struct msgb *msg;
+ uint8_t mid_buf[GSM48_MI_SIZE + 2];
+ int mid_len;
+ uint32_t tmsi_sw;
+
+ /* Mandatory emelents! */
+ OSMO_ASSERT(imsi);
+ OSMO_ASSERT(cil);
+
+ /* Malformed IMSI */
+ OSMO_ASSERT(strlen(imsi) <= GSM48_MI_SIZE);
+
+ msg =
+ msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "paging");
+ if (!msg)
+ return NULL;
+
+ /* Message Type 3.2.2.1 */
+ msgb_v_put(msg, BSS_MAP_MSG_PAGING);
+
+ /* IMSI 3.2.2.6 */
+ mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi);
+ msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2);
+
+ /* TMSI 3.2.2.7 */
+ if (tmsi) {
+ tmsi_sw = htonl(*tmsi);
+ msgb_tlv_put(msg, GSM0808_IE_TMSI, sizeof(*tmsi),
+ (uint8_t *) & tmsi_sw);
+ }
+
+ /* Cell Identifier List 3.2.2.27 */
+ if (cil)
+ gsm0808_enc_cell_id_list(msg, cil);
+
+ /* Channel Needed 3.2.2.36 */
+ if (chan_needed) {
+ msgb_tv_put(msg, GSM0808_IE_CHANNEL_NEEDED,
+ (*chan_needed) & 0x03);
+ }
+
+ /* pre-pend the header */
+ msg->l3h =
+ msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+
+ return msg;
+}
+
void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id)
{
uint8_t *hh = msgb_push(msg, 3);
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 786bf08b..ec234189 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -135,6 +135,7 @@ gsm0808_create_classmark_update;
gsm0808_create_clear_command;
gsm0808_create_clear_complete;
gsm0808_create_clear_rqst;
+gsm0808_create_paging;
gsm0808_create_dtap;
gsm0808_create_layer3;
gsm0808_create_layer3_aoip;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index f33e0bd1..b0dad7d8 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -21,6 +21,7 @@
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/gsm0808_utils.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <stdio.h>
#include <stdlib.h>
@@ -370,6 +371,46 @@ static void test_create_clear_rqst()
msgb_free(msg);
}
+static void test_create_paging()
+{
+ static const uint8_t res[] =
+ { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
+ 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
+ static const uint8_t res2[] =
+ { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
+ 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
+ 0x03, 0x05, 0x23, 0x42 };
+ static const uint8_t res3[] =
+ { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
+ 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
+ 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
+ RSL_CHANNEED_TCH_ForH };
+
+ struct msgb *msg;
+ struct gsm0808_cell_id_list cil;
+ uint32_t tmsi = 0x12345678;
+ uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
+
+ char imsi[] = "001010000001234";
+
+ cil.id_discr = CELL_IDENT_LAC;
+ cil.id_list_lac[0] = 0x2342;
+ cil.id_list_len = 1;
+
+ printf("Testing creating Paging Request\n");
+ msg = gsm0808_create_paging(imsi, NULL, &cil, NULL);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+
+ msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+
+ msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed);
+ VERIFY(msg, res3, ARRAY_SIZE(res3));
+ msgb_free(msg);
+}
+
static void test_create_dtap()
{
static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
@@ -750,6 +791,7 @@ int main(int argc, char **argv)
test_create_ass_fail();
test_create_ass_fail_aoip();
test_create_clear_rqst();
+ test_create_paging();
test_create_dtap();
test_prepend_dtap();
test_enc_dec_aoip_trasp_addr_v4();
diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok
index 8e2087d8..6170a7ab 100644
--- a/tests/gsm0808/gsm0808_test.ok
+++ b/tests/gsm0808/gsm0808_test.ok
@@ -14,6 +14,7 @@ Testing creating Assignment Complete (AoIP)
Testing creating Assignment Failure
Testing creating Assignment Failure (AoIP)
Testing creating Clear Request
+Testing creating Paging Request
Testing creating DTAP
Testing prepend DTAP
Done