aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gsm/lapdm.c20
-rw-r--r--tests/lapd/lapd_test.c43
-rw-r--r--tests/lapd/lapd_test.ok1
3 files changed, 62 insertions, 2 deletions
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index 1c08113e..2bda48ae 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -1069,8 +1069,24 @@ static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
return -EINVAL;
}
- LOGP(DLLAPD, LOGL_INFO, "(%p) RLL Message '%s' received. (sapi %d)\n",
- lc->name, rsl_msg_name(msg_type), sapi);
+ switch (msg_type) {
+ case RSL_MT_UNIT_DATA_REQ:
+ case RSL_MT_DATA_REQ:
+ case RSL_MT_SUSP_REQ:
+ case RSL_MT_REL_REQ:
+ /* This is triggered in abnormal error conditions where
+ * set_lapdm_context() was not called for the channel earlier. */
+ if (!dl->dl.lctx.dl) {
+ LOGP(DLLAPD, LOGL_NOTICE, "(%p) RLL Message '%s' received without LAPDm context. (sapi %d)\n",
+ lc->name, rsl_msg_name(msg_type), sapi);
+ msgb_free(msg);
+ return -EINVAL;
+ }
+ break;
+ default:
+ LOGP(DLLAPD, LOGL_INFO, "(%p) RLL Message '%s' received. (sapi %d)\n",
+ lc->name, rsl_msg_name(msg_type), sapi);
+ }
switch (msg_type) {
case RSL_MT_UNIT_DATA_REQ:
diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c
index d58bec65..2dabbc6d 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 d67a0a80..f1b990ea 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.