aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lapd
diff options
context:
space:
mode:
authorDaniel Willmann <daniel@totalueberwachung.de>2012-12-25 23:15:50 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-12-26 10:48:01 +0100
commite523392c2c091f53c18edf2086d6966eec38561f (patch)
treec74facf8897c5513adfa95e710d8388cfe170bad /tests/lapd
parent0167596c2bf19102eac8a69f5066eedbae72a167 (diff)
lapd: Check in rslms_rx_rll() if lapdm context was initialized earlier
This was found while implementing handover on a sysmobts. When we receive a channel release request for a channel that was never really activated (set_lapdm_context() was not called) we segfault in lapd_recv_dlsap(). We now return early with -EINVAL in rslms_rx_rll() if we receive a message that assumes set_lapdm_context() was already called. These are: * RSL_MT_UNIT_DATA_REQ * RSL_MT_DATA_REQ * RSL_MT_SUSP_REQ * RSL_MT_REL_REQ A test case was added to trigger the issue.
Diffstat (limited to 'tests/lapd')
-rw-r--r--tests/lapd/lapd_test.c43
-rw-r--r--tests/lapd/lapd_test.ok1
2 files changed, 44 insertions, 0 deletions
diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c
index d58bec6..2dabbc6 100644
--- a/tests/lapd/lapd_test.c
+++ b/tests/lapd/lapd_test.c
@@ -81,6 +81,10 @@ static const uint8_t dummy1[] = {
0xab, 0x03, 0x30, 0x60, 0x06,
};
+static const uint8_t rel_req[] = {
+ 0x02, 0x07, 0x01, 0x0a, 0x02, 0x40, 0x14, 0x01
+};
+
static struct msgb *create_cm_serv_req(void)
{
struct msgb *msg;
@@ -122,6 +126,16 @@ static struct msgb *create_dummy_data_req(void)
return msg;
}
+static struct msgb *create_rel_req(void)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_array(rel_req, sizeof(rel_req));
+ msg->l2h = msg->data;
+ msg->l3h = msg->l2h + sizeof(struct abis_rsl_rll_hdr);
+ return msg;
+}
+
static int send(struct msgb *in_msg, struct lapdm_channel *chan)
{
struct osmo_phsap_prim pp;
@@ -308,11 +322,40 @@ static void test_lapdm_polling()
lapdm_channel_exit(&ms_to_bts_channel);
}
+static void test_lapdm_early_release()
+{
+ printf("I test RF channel release of an unestablished channel.\n");
+
+ int rc;
+ struct lapdm_polling_state test_state;
+
+ /* Configure LAPDm on both sides */
+ struct lapdm_channel bts_to_ms_channel;
+ memset(&bts_to_ms_channel, 0, sizeof(bts_to_ms_channel));
+
+ memset(&test_state, 0, sizeof(test_state));
+ test_state.bts = &bts_to_ms_channel;
+
+ /* BTS to MS in polling mode */
+ lapdm_channel_init(&bts_to_ms_channel, LAPDM_MODE_BTS);
+ lapdm_channel_set_flags(&bts_to_ms_channel, LAPDM_ENT_F_POLLING_ONLY);
+ lapdm_channel_set_l1(&bts_to_ms_channel, NULL, &test_state);
+ lapdm_channel_set_l3(&bts_to_ms_channel, bts_to_ms_tx_cb, &test_state);
+
+ /* Send the release request */
+ rc = lapdm_rslms_recvmsg(create_rel_req(), &bts_to_ms_channel);
+ ASSERT(rc == -EINVAL);
+
+ /* clean up */
+ lapdm_channel_exit(&bts_to_ms_channel);
+}
+
int main(int argc, char **argv)
{
osmo_init_logging(&info);
test_lapdm_polling();
+ test_lapdm_early_release();
printf("Success.\n");
return 0;
diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok
index d67a0a8..f1b990e 100644
--- a/tests/lapd/lapd_test.ok
+++ b/tests/lapd/lapd_test.ok
@@ -17,4 +17,5 @@ Sending back to BTS
ms_to_bts_l1_cb: MS(us) -> BTS prim message
bts_to_ms_tx_cb: MS->BTS(us) message 14
BTS: Verifying dummy message.
+I test RF channel release of an unestablished channel.
Success.