Merge branch 'zecke/jolly-lapdm-fixes'

* Squashed fix and testcase into one.
This commit is contained in:
Holger Hans Peter Freyther 2013-04-07 20:17:30 +02:00
commit e1f164dd2f
4 changed files with 104 additions and 6 deletions

View File

@ -820,7 +820,12 @@ static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
"frame established state\n");
/* If link is lost on the remote side, we start over
* and send DL-ESTABLISH indication again. */
if (dl->v_send != dl->v_recv) {
/* Additionally, continue in case of content resoltion
* (GSM network). This happens, if the mobile has not
* yet received UA or another mobile (collision) tries
* to establish connection. The mobile must receive
* UA again. */
if (!dl->cont_res && dl->v_send != dl->v_recv) {
LOGP(DLLAPD, LOGL_INFO, "Remote reestablish\n");
mdl_error(MDL_CAUSE_SABM_MF, lctx);
break;
@ -831,7 +836,8 @@ static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
#ifdef TEST_CONTENT_RESOLUTION_NETWORK
dl->cont_res->data[0] ^= 0x01;
#endif
if (memcmp(dl->cont_res, msg->data, length)) {
if (memcmp(dl->cont_res->data, msg->data,
length)) {
LOGP(DLLAPD, LOGL_INFO, "Another SABM "
"with diffrent content - "
"ignoring!\n");

View File

@ -687,7 +687,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->sap != SAP_GSM_PH) {
LOGP(DLLAPD, LOGL_ERROR, "primitive for unknown SAP %u\n",
oph->sap);
return -ENODEV;
rc = -ENODEV;
goto free;
}
switch (oph->primitive) {
@ -695,7 +696,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DLLAPD, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
oph->operation);
return -ENODEV;
rc = -ENODEV;
goto free;
}
rc = l2_ph_data_ind(oph->msg, le, pp->u.data.chan_nr,
pp->u.data.link_id);
@ -704,7 +706,8 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DLLAPD, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
oph->operation);
return -ENODEV;
rc = -ENODEV;
goto free;
}
rc = l2_ph_data_conf(oph->msg, le);
break;
@ -718,12 +721,22 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
rc = l2_ph_chan_conf(oph->msg, le, pp->u.rach_ind.fn);
break;
default:
return -EIO;
rc = -EIO;
goto free;
}
break;
default:
LOGP(DLLAPD, LOGL_ERROR, "Unknown primitive %u\n",
oph->primitive);
rc = -EINVAL;
goto free;
}
return rc;
free:
msgb_free(oph->msg);
return rc;
}

View File

@ -67,6 +67,12 @@ static const uint8_t cm_padded[] = {
0x2b, 0x2b, 0x2b, 0x2b
};
static const uint8_t ua[] = {
0x01, 0x73, 0x41, 0x05, 0x24, 0x31, 0x03, 0x50,
0x18, 0x93, 0x08, 0x29, 0x47, 0x80, 0x00, 0x00,
0x00, 0x00, 0x80, 0x2b, 0x2b, 0x2b, 0x2b
};
static const uint8_t mm[] = {
0x00, 0x0c, 0x00, 0x03, 0x01, 0x01, 0x20, 0x02,
0x00, 0x0b, 0x00, 0x03, 0x05, 0x04, 0x0d
@ -153,6 +159,32 @@ static int send(struct msgb *in_msg, struct lapdm_channel *chan)
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);
OSMO_ASSERT(rc == 0 || rc == -EBUSY);
return 0;
}
/*
* I get called from the LAPDm code when something was sent my way...
*/
@ -348,12 +380,56 @@ static void test_lapdm_early_release()
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);
OSMO_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);
OSMO_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);
OSMO_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);
test_lapdm_polling();
test_lapdm_early_release();
test_lapdm_contention_resolution();
printf("Success.\n");
return 0;

View File

@ -18,4 +18,7 @@ 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.
I test contention resultion by having two mobiles collide and first mobile repeating SABM.
bts_to_ms_tx_cb: MS->BTS(us) message 29
BTS: Verifying CM request.
Success.