diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2013-02-06 14:13:21 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2013-07-06 23:36:15 +0200 |
commit | a3de4dfb5c24007c4b0c462df93e2015b245a6b7 (patch) | |
tree | 957ac5cc3a286a7b2b53932576bfaf5ac3b77aeb /tests/lapd | |
parent | 8d50600d7d927a5c9f08c2a9573b6a45866dc602 (diff) |
Add LAPDm collision test (contention resolution on network side)
Diffstat (limited to 'tests/lapd')
-rw-r--r-- | tests/lapd/lapd_test.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index 1f986bc8..1a06cb1c 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -179,6 +179,32 @@ static int send_sabm(struct lapdm_channel *chan, int second_ms) return 0; } +static int send_sabm(struct lapdm_channel *chan, int second_ms) +{ + struct osmo_phsap_prim pp; + struct msgb *msg; + int rc; + + msg = msgb_alloc_headroom(128, 64, "PH-DATA.ind"); + osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA, + PRIM_OP_INDICATION, msg); + /* copy over actual MAC block */ + msg->l2h = msgb_put(msg, 23); + msg->l2h[0] = 0x01; + msg->l2h[1] = 0x3f; + msg->l2h[2] = 0x01 | (sizeof(cm) << 2); + memcpy(msg->l2h + 3, cm_padded, sizeof(cm_padded)); + msg->l2h[3] += second_ms; /* alter message, for second mobile */ + + /* LAPDm requires those... */ + pp.u.data.chan_nr = 0; + pp.u.data.link_id = 0; + /* feed into the LAPDm code of libosmogsm */ + rc = lapdm_phsap_up(&pp.oph, &chan->lapdm_dcch); + ASSERT(rc == 0 || rc == -EBUSY); + return 0; +} + /* * I get called from the LAPDm code when something was sent my way... */ @@ -417,6 +443,49 @@ static void test_lapdm_contention_resolution() lapdm_channel_exit(&bts_to_ms_channel); } +static void test_lapdm_contention_resolution() +{ + printf("I test contention resultion by having two mobiles collide and " + "first mobile repeating SABM.\n"); + + int rc; + struct lapdm_polling_state test_state; + struct osmo_phsap_prim pp; + + /* 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 SABM MS 1, we must get UA */ + send_sabm(&bts_to_ms_channel, 0); + rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + CHECK_RC(rc); + ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); + + /* Send SABM MS 2, we must get nothing, due to collision */ + send_sabm(&bts_to_ms_channel, 1); + rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + ASSERT(rc == -ENODEV); + + /* Send SABM MS 1 again, we must get UA gain */ + send_sabm(&bts_to_ms_channel, 0); + rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp); + CHECK_RC(rc); + ASSERT(memcmp(pp.oph.msg->l2h, ua, ARRAY_SIZE(ua)) == 0); + + /* clean up */ + lapdm_channel_exit(&bts_to_ms_channel); +} + int main(int argc, char **argv) { osmo_init_logging(&info); |