|
|
|
@ -186,6 +186,7 @@ static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
|
|
|
|
|
const struct gprs_ra_id *bssgp_raid,
|
|
|
|
|
const uint8_t *data, size_t data_len)
|
|
|
|
|
{
|
|
|
|
|
struct msgb *msg;
|
|
|
|
@ -195,6 +196,7 @@ static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
|
|
|
|
|
|
|
|
|
|
msg = create_msg(data, data_len);
|
|
|
|
|
msgb_tlli(msg) = tlli;
|
|
|
|
|
bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
|
|
|
|
|
gsm0408_gprs_rcvmsg(msg, llme);
|
|
|
|
|
msgb_free(msg);
|
|
|
|
|
}
|
|
|
|
@ -203,11 +205,9 @@ static void test_llme(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_llc_lle *lle, *lle_copy;
|
|
|
|
|
uint32_t local_tlli;
|
|
|
|
|
uint32_t foreign_tlli;
|
|
|
|
|
|
|
|
|
|
printf("Testing LLME allocations\n");
|
|
|
|
|
local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
|
|
|
|
|
foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
|
|
|
|
|
|
|
|
|
|
/* initial state */
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 0);
|
|
|
|
@ -221,9 +221,6 @@ static void test_llme(void)
|
|
|
|
|
lle_copy = gprs_lle_get_or_create(local_tlli, 3);
|
|
|
|
|
OSMO_ASSERT(lle == lle_copy);
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
|
|
|
|
|
OSMO_ASSERT(lle == lle_copy);
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* unassign which should delete it*/
|
|
|
|
|
gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
|
|
|
|
@ -733,7 +730,7 @@ static void test_gmm_detach(void)
|
|
|
|
|
ctx = alloc_mm_ctx(local_tlli, &raid);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that a single message (hopefully the Detach Accept) has been
|
|
|
|
@ -774,7 +771,7 @@ static void test_gmm_detach_power_off(void)
|
|
|
|
|
ctx = alloc_mm_ctx(local_tlli, &raid);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that no message (and therefore no Detach Accept) has been
|
|
|
|
@ -794,6 +791,7 @@ static void test_gmm_detach_power_off(void)
|
|
|
|
|
*/
|
|
|
|
|
static void test_gmm_detach_no_mmctx(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_ra_id raid = { 0, };
|
|
|
|
|
struct gprs_llc_lle *lle;
|
|
|
|
|
uint32_t local_tlli;
|
|
|
|
|
|
|
|
|
@ -814,7 +812,7 @@ static void test_gmm_detach_no_mmctx(void)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(lle->llme, local_tlli,
|
|
|
|
|
send_0408_message(lle->llme, local_tlli, &raid,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that the LLME is gone */
|
|
|
|
@ -829,6 +827,7 @@ static void test_gmm_detach_no_mmctx(void)
|
|
|
|
|
*/
|
|
|
|
|
static void test_gmm_detach_accept_unexpected(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_ra_id raid = { 0, };
|
|
|
|
|
struct gprs_llc_lle *lle;
|
|
|
|
|
uint32_t local_tlli;
|
|
|
|
|
|
|
|
|
@ -846,7 +845,7 @@ static void test_gmm_detach_accept_unexpected(void)
|
|
|
|
|
lle = gprs_lle_get_or_create(local_tlli, 3);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(lle->llme, local_tlli,
|
|
|
|
|
send_0408_message(lle->llme, local_tlli, &raid,
|
|
|
|
|
detach_acc, ARRAY_SIZE(detach_acc));
|
|
|
|
|
|
|
|
|
|
/* verify that no message (and therefore no Status or XID reset) has been
|
|
|
|
@ -864,6 +863,7 @@ static void test_gmm_detach_accept_unexpected(void)
|
|
|
|
|
*/
|
|
|
|
|
static void test_gmm_status_no_mmctx(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_ra_id raid = { 0, };
|
|
|
|
|
struct gprs_llc_lle *lle;
|
|
|
|
|
uint32_t local_tlli;
|
|
|
|
|
|
|
|
|
@ -882,7 +882,7 @@ static void test_gmm_status_no_mmctx(void)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(lle->llme, local_tlli,
|
|
|
|
|
send_0408_message(lle->llme, local_tlli, &raid,
|
|
|
|
|
gmm_status, ARRAY_SIZE(gmm_status));
|
|
|
|
|
|
|
|
|
|
/* verify that no message has been sent by the SGSN */
|
|
|
|
@ -957,7 +957,7 @@ static void test_gmm_attach(int retry)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
|
|
|
|
|
ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
|
|
|
|
@ -968,14 +968,14 @@ static void test_gmm_attach(int retry)
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMEI) */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
|
|
|
|
|
|
|
|
|
|
/* we expect an identity request (IMSI) */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMSI) */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
|
|
|
|
|
|
|
|
|
|
/* check that the MM context has not been removed due to a failed
|
|
|
|
@ -989,7 +989,7 @@ retry_attach_req:
|
|
|
|
|
if (retry && sgsn_tx_counter == 0) {
|
|
|
|
|
fprintf(stderr, "Retrying attach request\n");
|
|
|
|
|
/* re-inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -997,7 +997,7 @@ retry_attach_req:
|
|
|
|
|
/* we got an auth & ciph request */
|
|
|
|
|
|
|
|
|
|
/* inject the auth & ciph response */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
|
|
|
|
|
|
|
|
|
|
/* check that the MM context has not been removed due to a
|
|
|
|
@ -1019,7 +1019,7 @@ retry_attach_req:
|
|
|
|
|
local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
|
|
|
|
|
/* inject the attach complete */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
attach_compl, ARRAY_SIZE(attach_compl));
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
@ -1028,7 +1028,7 @@ retry_attach_req:
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that things are gone */
|
|
|
|
@ -1475,7 +1475,7 @@ static void test_gmm_reject(void)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* Inject the Request message */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
test->msg, test->msg_len);
|
|
|
|
|
|
|
|
|
|
/* We expect a Reject message */
|
|
|
|
@ -1545,7 +1545,7 @@ static void test_gmm_cancel(void)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
|
|
|
|
|
ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
|
|
|
|
@ -1556,14 +1556,14 @@ static void test_gmm_cancel(void)
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMEI) */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
|
|
|
|
|
|
|
|
|
|
/* we expect an identity request (IMSI) */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMSI) */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
|
|
|
|
|
|
|
|
|
|
/* check that the MM context has not been removed due to a failed
|
|
|
|
@ -1581,7 +1581,7 @@ static void test_gmm_cancel(void)
|
|
|
|
|
local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
|
|
|
|
|
/* inject the attach complete */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
attach_compl, ARRAY_SIZE(attach_compl));
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
@ -1607,7 +1607,7 @@ static void test_gmm_cancel(void)
|
|
|
|
|
*/
|
|
|
|
|
static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_ra_id raid = { 0, };
|
|
|
|
|
struct gprs_ra_id raid = {332, 112, 16464, 96};
|
|
|
|
|
struct sgsn_mm_ctx *ctx = NULL;
|
|
|
|
|
struct sgsn_mm_ctx *ictx;
|
|
|
|
|
uint32_t foreign_tlli;
|
|
|
|
@ -1693,7 +1693,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
|
|
|
|
|
ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
|
|
|
|
@ -1708,7 +1708,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMEI) */
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, foreign_tlli, &raid,
|
|
|
|
|
ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
|
|
|
|
|
|
|
|
|
|
/* check that the MM context has not been removed due to a failed
|
|
|
|
@ -1724,7 +1724,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
OSMO_ASSERT(received_ptmsi == ptmsi1);
|
|
|
|
|
|
|
|
|
|
/* we ignore this and send the attach again */
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli,
|
|
|
|
|
send_0408_message(lle->llme, foreign_tlli, &raid,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
|
|
|
|
|
/* the allocated P-TMSI should be the same */
|
|
|
|
@ -1741,7 +1741,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
|
|
|
|
|
/* inject the attach complete */
|
|
|
|
|
local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
attach_compl, ARRAY_SIZE(attach_compl));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
@ -1754,7 +1754,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
printf(" - Repeated RA Update Request\n");
|
|
|
|
|
|
|
|
|
|
/* inject the RA update request */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
ra_upd_req, ARRAY_SIZE(ra_upd_req));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update accept */
|
|
|
|
@ -1767,7 +1767,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
ptmsi2 = ctx->p_tmsi;
|
|
|
|
|
|
|
|
|
|
/* repeat the RA update request */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
ra_upd_req, ARRAY_SIZE(ra_upd_req));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update accept */
|
|
|
|
@ -1781,7 +1781,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
|
|
|
|
|
/* inject the RA update complete */
|
|
|
|
|
local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
@ -1792,7 +1792,7 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli,
|
|
|
|
|
send_0408_message(ctx->llme, local_tlli, &raid,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that things are gone */
|
|
|
|
@ -1805,6 +1805,310 @@ static void test_gmm_ptmsi_allocation(void)
|
|
|
|
|
cleanup_test();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test changing of routing areas
|
|
|
|
|
*/
|
|
|
|
|
static void test_gmm_routing_areas(void)
|
|
|
|
|
{
|
|
|
|
|
struct gprs_ra_id raid1 = {332, 112, 16464, 96};
|
|
|
|
|
struct gprs_ra_id raid2 = {332, 112, 16464, 97};
|
|
|
|
|
struct sgsn_mm_ctx *ctx = NULL;
|
|
|
|
|
struct sgsn_mm_ctx *ictx;
|
|
|
|
|
uint32_t ptmsi1;
|
|
|
|
|
uint32_t received_ptmsi;
|
|
|
|
|
uint32_t ms_tlli = 0;
|
|
|
|
|
struct gprs_llc_lle *lle;
|
|
|
|
|
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
|
|
|
|
|
|
|
|
|
|
/* DTAP - Attach Request (IMSI 12131415161718) */
|
|
|
|
|
static const unsigned char attach_req[] = {
|
|
|
|
|
0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
|
|
|
|
|
0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
|
|
|
0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
|
|
|
|
|
0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
|
|
|
|
|
0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
|
|
|
|
|
0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
|
|
|
|
|
0x00,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
|
|
|
|
|
static const unsigned char attach_req2[] = {
|
|
|
|
|
0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
|
|
|
|
|
0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
|
|
|
0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
|
|
|
|
|
0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
|
|
|
|
|
0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
|
|
|
|
|
0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
|
|
|
|
|
0x00,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Identity Response IMEI */
|
|
|
|
|
static const unsigned char ident_resp_imei[] = {
|
|
|
|
|
0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
|
|
|
|
|
0x56
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Attach Complete */
|
|
|
|
|
static const unsigned char attach_compl[] = {
|
|
|
|
|
0x08, 0x03
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Routing Area Update Request (coming from RA 1) */
|
|
|
|
|
static const unsigned char ra_upd_req1[] = {
|
|
|
|
|
0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
|
|
|
|
|
0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
|
|
|
|
|
0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
|
|
|
|
|
0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
|
|
|
|
|
0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
|
|
|
|
|
0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
|
|
|
|
|
0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Routing Area Update Request (coming from RA 2) */
|
|
|
|
|
static const unsigned char ra_upd_req2[] = {
|
|
|
|
|
0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
|
|
|
|
|
0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
|
|
|
|
|
0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
|
|
|
|
|
0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
|
|
|
|
|
0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
|
|
|
|
|
0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
|
|
|
|
|
0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Routing Area Update Request (coming from RA other) */
|
|
|
|
|
/* raid_other = {443, 223, 16464, 98}; */
|
|
|
|
|
static const unsigned char ra_upd_req_other[] = {
|
|
|
|
|
0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
|
|
|
|
|
0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
|
|
|
|
|
0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
|
|
|
|
|
0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
|
|
|
|
|
0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
|
|
|
|
|
0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
|
|
|
|
|
0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Routing Area Update Complete */
|
|
|
|
|
static const unsigned char ra_upd_complete[] = {
|
|
|
|
|
0x08, 0x0a
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* DTAP - Detach Request (MO) */
|
|
|
|
|
/* normal detach, power_off = 1 */
|
|
|
|
|
static const unsigned char detach_req[] = {
|
|
|
|
|
0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
|
|
|
|
|
0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
|
|
|
|
|
|
|
|
|
|
printf("Testing routing area changes\n");
|
|
|
|
|
|
|
|
|
|
/* reset the PRNG used by sgsn_alloc_ptmsi */
|
|
|
|
|
srand(1);
|
|
|
|
|
|
|
|
|
|
ptmsi1 = GSM_RESERVED_TMSI;
|
|
|
|
|
|
|
|
|
|
printf(" - Attach Request (RA 1)\n");
|
|
|
|
|
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
|
|
|
|
|
|
|
|
|
|
/* Create a LLE/LLME */
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 0);
|
|
|
|
|
lle = gprs_lle_get_or_create(ms_tlli, 3);
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, ms_tlli, &raid1,
|
|
|
|
|
attach_req, ARRAY_SIZE(attach_req));
|
|
|
|
|
|
|
|
|
|
ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
|
|
|
|
|
OSMO_ASSERT(ctx != NULL);
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
|
|
|
|
|
|
|
|
|
|
/* we expect an identity request (IMEI) */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
|
|
|
|
|
|
|
|
|
|
/* inject the identity response (IMEI) */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid1,
|
|
|
|
|
ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
|
|
|
|
|
|
|
|
|
|
/* check that the MM context has not been removed due to a failed
|
|
|
|
|
* authorization */
|
|
|
|
|
OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
|
|
|
|
|
|
|
|
|
/* we expect an attach accept */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
|
|
|
|
|
|
|
|
|
|
received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
|
|
|
|
|
OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
|
|
|
|
|
ptmsi1 = received_ptmsi;
|
|
|
|
|
|
|
|
|
|
/* inject the attach complete */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid1,
|
|
|
|
|
attach_compl, ARRAY_SIZE(attach_compl));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == 0);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
|
|
|
|
|
|
|
|
|
|
printf(" - RA Update Request (RA 1 -> RA 1)\n");
|
|
|
|
|
|
|
|
|
|
/* inject the RA update request */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid1,
|
|
|
|
|
ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update accept */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
|
|
|
|
|
// OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
|
|
|
|
|
|
|
|
|
|
received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
|
|
|
|
|
OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
|
|
|
|
|
ptmsi1 = received_ptmsi;
|
|
|
|
|
|
|
|
|
|
/* inject the RA update complete */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid1,
|
|
|
|
|
ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == 0);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
|
|
|
|
|
OSMO_ASSERT(ctx->tlli == ms_tlli);
|
|
|
|
|
|
|
|
|
|
printf(" - RA Update Request (RA 1 -> RA 2)\n");
|
|
|
|
|
|
|
|
|
|
/* inject the RA update request */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
|
|
|
|
|
|
|
|
|
|
/* It is coming from RA 1 => ra_upd_req1 */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update accept */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
|
|
|
|
|
|
|
|
|
|
printf(" - RA Update Request (RA other -> RA 2)\n");
|
|
|
|
|
|
|
|
|
|
/* inject the RA update request */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
|
|
|
|
|
|
|
|
|
|
/* It is coming from RA 1 => ra_upd_req1 */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update reject (and a LLC XID RESET) */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 2);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
|
|
|
|
|
/* this has killed the LLE/LLME */
|
|
|
|
|
|
|
|
|
|
printf(" - Attach Request (RA 2)\n");
|
|
|
|
|
|
|
|
|
|
/* Create a LLE/LLME */
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
lle = gprs_lle_get_or_create(ms_tlli, 3);
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
|
|
|
|
|
|
|
|
|
/* inject the attach request */
|
|
|
|
|
send_0408_message(lle->llme, ms_tlli, &raid2,
|
|
|
|
|
attach_req2, ARRAY_SIZE(attach_req2));
|
|
|
|
|
|
|
|
|
|
ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
|
|
|
|
|
OSMO_ASSERT(ctx != NULL);
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
|
|
|
|
|
|
|
|
|
|
/* we expect an attach accept */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
|
|
|
|
|
|
|
|
|
|
received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
|
|
|
|
|
OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
|
|
|
|
|
ptmsi1 = received_ptmsi;
|
|
|
|
|
|
|
|
|
|
/* inject the attach complete */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
|
|
|
|
|
OSMO_ASSERT(ictx != NULL);
|
|
|
|
|
OSMO_ASSERT(ictx == ctx);
|
|
|
|
|
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
attach_compl, ARRAY_SIZE(attach_compl));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == 0);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
|
|
|
|
|
|
|
|
|
|
printf(" - RA Update Request (RA 2 -> RA 2)\n");
|
|
|
|
|
|
|
|
|
|
/* inject the RA update request */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
|
|
|
|
|
|
|
|
|
|
/* we expect an RA update accept */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
|
|
|
|
OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
|
|
|
|
|
|
|
|
|
|
received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
|
|
|
|
|
OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
|
|
|
|
|
ptmsi1 = received_ptmsi;
|
|
|
|
|
|
|
|
|
|
/* inject the RA update complete */
|
|
|
|
|
ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
|
|
|
|
|
|
|
|
|
|
/* we don't expect a response */
|
|
|
|
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
|
|
|
|
|
|
|
|
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi_old == 0);
|
|
|
|
|
OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
|
|
|
|
|
OSMO_ASSERT(ctx->tlli == ms_tlli);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* inject the detach */
|
|
|
|
|
send_0408_message(ctx->llme, ms_tlli, &raid2,
|
|
|
|
|
detach_req, ARRAY_SIZE(detach_req));
|
|
|
|
|
|
|
|
|
|
/* verify that things are gone */
|
|
|
|
|
OSMO_ASSERT(count(gprs_llme_list()) == 0);
|
|
|
|
|
ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
|
|
|
|
|
OSMO_ASSERT(!ictx);
|
|
|
|
|
|
|
|
|
|
sgsn->cfg.auth_policy = saved_auth_policy;
|
|
|
|
|
|
|
|
|
|
cleanup_test();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_apn_matching(void)
|
|
|
|
|
{
|
|
|
|
|
struct apn_ctx *actx, *actxs[9];
|
|
|
|
@ -2129,6 +2433,7 @@ int main(int argc, char **argv)
|
|
|
|
|
test_gmm_reject();
|
|
|
|
|
test_gmm_cancel();
|
|
|
|
|
test_gmm_ptmsi_allocation();
|
|
|
|
|
test_gmm_routing_areas();
|
|
|
|
|
test_apn_matching();
|
|
|
|
|
test_ggsn_selection();
|
|
|
|
|
printf("Done\n");
|
|
|
|
|