diff options
| -rw-r--r-- | src/gsm/lapd_core.c | 10 | ||||
| -rw-r--r-- | tests/lapd/lapd_test.c | 76 | ||||
| -rw-r--r-- | tests/lapd/lapd_test.ok | 3 | 
3 files changed, 87 insertions, 2 deletions
diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c index b33cf6eb..f351308d 100644 --- a/src/gsm/lapd_core.c +++ b/src/gsm/lapd_core.c @@ -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"); diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index a60c45d4..49b7eefa 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -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; diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index f1b990ea..aa927088 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -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.  | 
