blob: 26d81a7f17a50daf55383ee0b448e02029c378d0 [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020027
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010028#include <osmocom/gprs/gprs_bssgp.h>
29
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020030#include <osmocom/gsm/gsm_utils.h>
31
32#include <osmocom/core/application.h>
33#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010034#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020035
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020036#include <stdio.h>
37
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020038extern void *tall_msgb_ctx;
39
40void *tall_bsc_ctx;
41static struct sgsn_instance sgsn_inst = {
42 .config_file = "osmo_sgsn.cfg",
43 .cfg = {
44 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010045 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020046 },
47};
48struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010049unsigned sgsn_tx_counter = 0;
50
51/* override */
52int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
53 struct bssgp_dl_ud_par *dup)
54{
55 sgsn_tx_counter += 1;
56 return 0;
57}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020058
Jacob Erlbecke8b69682014-11-12 10:12:11 +010059/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
60void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
61void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
62 &__real_sgsn_update_subscriber_data;
63
64void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
65 struct gsm_subscriber *subscr)
66{
67 (*update_subscriber_data_cb)(mmctx, subscr);
68}
69
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010070/* override, requires '-Wl,--wrap=gprs_subscr_request_update' */
71int __real_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx);
72int (*subscr_request_update_cb)(struct sgsn_mm_ctx *mmctx) =
73 &__real_gprs_subscr_request_update;
74
75int __wrap_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
76 return (*subscr_request_update_cb)(mmctx);
77};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010078
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020079static int count(struct llist_head *head)
80{
81 struct llist_head *cur;
82 int count = 0;
83
84 llist_for_each(cur, head)
85 count += 1;
86
87 return count;
88}
89
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020090static struct msgb *create_msg(const uint8_t *data, size_t len)
91{
92 struct msgb *msg = msgb_alloc(len + 8, "test message");
93 msg->l1h = msgb_put(msg, 8);
94 msg->l2h = msgb_put(msg, len);
95 memcpy(msg->l2h, data, len);
96
97 msgb_bcid(msg) = msg->l1h;
98 msgb_gmmh(msg) = msg->l2h;
99 return msg;
100}
101
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100102/*
103 * Create a context and search for it
104 */
105static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
106{
107 struct sgsn_mm_ctx *ctx, *ictx;
108 struct gprs_llc_lle *lle;
109 int old_count = count(gprs_llme_list());
110
111 lle = gprs_lle_get_or_create(tlli, 3);
112 ctx = sgsn_mm_ctx_alloc(tlli, raid);
113 ctx->mm_state = GMM_REGISTERED_NORMAL;
114 ctx->llme = lle->llme;
115
116 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
117 OSMO_ASSERT(ictx == ctx);
118
119 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
120
121 return ctx;
122}
123
Jacob Erlbeck75488292014-10-29 10:31:18 +0100124static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
125 const uint8_t *data, size_t data_len)
126{
127 struct msgb *msg;
128
129 sgsn_tx_counter = 0;
130
131 msg = create_msg(data, data_len);
132 msgb_tlli(msg) = tlli;
133 gsm0408_gprs_rcvmsg(msg, llme);
134 msgb_free(msg);
135}
136
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200137static void test_llme(void)
138{
139 struct gprs_llc_lle *lle, *lle_copy;
140 uint32_t local_tlli;
141 uint32_t foreign_tlli;
142
143 printf("Testing LLME allocations\n");
144 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
145 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
146
147 /* initial state */
148 OSMO_ASSERT(count(gprs_llme_list()) == 0);
149
150 /* Create a new entry */
151 lle = gprs_lle_get_or_create(local_tlli, 3);
152 OSMO_ASSERT(lle);
153 OSMO_ASSERT(count(gprs_llme_list()) == 1);
154
155 /* No new entry is created */
156 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
157 OSMO_ASSERT(lle == lle_copy);
158 OSMO_ASSERT(count(gprs_llme_list()) == 1);
159 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
160 OSMO_ASSERT(lle == lle_copy);
161 OSMO_ASSERT(count(gprs_llme_list()) == 1);
162
163 /* unassign which should delete it*/
164 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
165
166 /* Check that everything was cleaned up */
167 OSMO_ASSERT(count(gprs_llme_list()) == 0);
168}
169
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100170struct gsm_subscriber *last_updated_subscr = NULL;
171void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
172 struct gsm_subscriber *subscr)
173{
174 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
175 __func__, mmctx, subscr);
176 last_updated_subscr = subscr;
177}
178
179static void test_subscriber(void)
180{
181 struct gsm_subscriber *s1, *s2, *s1found, *s2found;
182 const char *imsi1 = "1234567890";
183 const char *imsi2 = "9876543210";
184
185 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
186
187 printf("Testing core subscriber data API\n");
188
189 /* Check for emptiness */
190 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
191 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
192
193 /* Allocate entry 1 */
194 s1 = gprs_subscr_get_or_create(imsi1);
195 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
196 s1found = gprs_subscr_get_by_imsi(imsi1);
197 OSMO_ASSERT(s1found == s1);
198 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
199 subscr_put(s1found);
200
201 /* Allocate entry 2 */
202 s2 = gprs_subscr_get_or_create(imsi2);
203 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
204 s1found = gprs_subscr_get_by_imsi(imsi1);
205 s2found = gprs_subscr_get_by_imsi(imsi2);
206 OSMO_ASSERT(s1found == s1);
207 OSMO_ASSERT(s2found == s2);
208 subscr_put(s1found);
209 subscr_put(s2found);
210
211 /* Update entry 1 */
212 last_updated_subscr = NULL;
213 gprs_subscr_update(s1);
214 OSMO_ASSERT(last_updated_subscr == s1);
215
216 /* Because of the update, it won't be freed on delete now */
217 gprs_subscr_delete(s1);
218 s1found = gprs_subscr_get_by_imsi(imsi1);
219 OSMO_ASSERT(s1found != NULL);
220 s1 = s1found;
221
222 /* Cancel it, so that delete will free it.
223 * Refcount it to make sure s1 won't be freed here */
224 last_updated_subscr = NULL;
225 gprs_subscr_put_and_cancel(subscr_get(s1));
226 OSMO_ASSERT(last_updated_subscr == s1);
227
228 /* Cancelled entries are still being found */
229 s1found = gprs_subscr_get_by_imsi(imsi1);
230 OSMO_ASSERT(s1found != NULL);
231 subscr_put(s1found);
232
233 /* Free entry 1 */
234 gprs_subscr_delete(s1);
235 s1 = NULL;
236 s2found = gprs_subscr_get_by_imsi(imsi2);
237 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
238 OSMO_ASSERT(s2found == s2);
239 subscr_put(s2found);
240
241 /* Free entry 2 */
242 gprs_subscr_delete(s2);
243 s2 = NULL;
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
246
247 OSMO_ASSERT(llist_empty(&active_subscribers));
248
249 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
250}
251
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200252/*
253 * Test that a GMM Detach will remove the MMCTX and the
254 * associated LLME.
255 */
256static void test_gmm_detach(void)
257{
258 struct gprs_ra_id raid = { 0, };
259 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200260 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200261
262 printf("Testing GMM detach\n");
263
264 /* DTAP - Detach Request (MO) */
265 /* normal detach, power_off = 0 */
266 static const unsigned char detach_req[] = {
267 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
268 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
269 };
270
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200271 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200272
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100273 /* Create a context */
274 OSMO_ASSERT(count(gprs_llme_list()) == 0);
275 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200276
277 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100278 send_0408_message(ctx->llme, local_tlli,
279 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200280
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100281 /* verify that a single message (hopefully the Detach Accept) has been
282 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100283 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100284
285 /* verify that things are gone */
286 OSMO_ASSERT(count(gprs_llme_list()) == 0);
287 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
288 OSMO_ASSERT(!ictx);
289}
290
291/*
292 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
293 * will not sent a Detach Accept message (power_off = 1)
294 */
295static void test_gmm_detach_power_off(void)
296{
297 struct gprs_ra_id raid = { 0, };
298 struct sgsn_mm_ctx *ctx, *ictx;
299 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100300
301 printf("Testing GMM detach (power off)\n");
302
303 /* DTAP - Detach Request (MO) */
304 /* normal detach, power_off = 1 */
305 static const unsigned char detach_req[] = {
306 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
307 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
308 };
309
310 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
311
312 /* Create a context */
313 OSMO_ASSERT(count(gprs_llme_list()) == 0);
314 ctx = alloc_mm_ctx(local_tlli, &raid);
315
316 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100317 send_0408_message(ctx->llme, local_tlli,
318 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100319
320 /* verify that no message (and therefore no Detach Accept) has been
321 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100322 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100323
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200324 /* verify that things are gone */
325 OSMO_ASSERT(count(gprs_llme_list()) == 0);
326 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200327 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200328}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200329
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200330/*
331 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
332 */
333static void test_gmm_detach_no_mmctx(void)
334{
335 struct gprs_llc_lle *lle;
336 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200337
338 printf("Testing GMM detach (no MMCTX)\n");
339
340 /* DTAP - Detach Request (MO) */
341 /* normal detach, power_off = 0 */
342 static const unsigned char detach_req[] = {
343 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
344 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
345 };
346
347 /* Create an LLME */
348 OSMO_ASSERT(count(gprs_llme_list()) == 0);
349 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
350 lle = gprs_lle_get_or_create(local_tlli, 3);
351
352 OSMO_ASSERT(count(gprs_llme_list()) == 1);
353
354 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100355 send_0408_message(lle->llme, local_tlli,
356 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200357
358 /* verify that the LLME is gone */
359 OSMO_ASSERT(count(gprs_llme_list()) == 0);
360}
361
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100362/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100363 * Test that a single GMM Detach Accept message will not cause the SGSN to send
364 * any message or leave an MM context at the SGSN.
365 */
366static void test_gmm_detach_accept_unexpected(void)
367{
368 struct gprs_llc_lle *lle;
369 uint32_t local_tlli;
370
371 printf("Testing GMM detach accept (unexpected)\n");
372
373 /* DTAP - Detach Accept (MT) */
374 /* normal detach */
375 static const unsigned char detach_acc[] = {
376 0x08, 0x06
377 };
378
379 /* Create an LLME */
380 OSMO_ASSERT(count(gprs_llme_list()) == 0);
381 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
382 lle = gprs_lle_get_or_create(local_tlli, 3);
383
384 /* inject the detach */
385 send_0408_message(lle->llme, local_tlli,
386 detach_acc, ARRAY_SIZE(detach_acc));
387
388 /* verify that no message (and therefore no Status or XID reset) has been
389 * sent by the SGSN */
390 OSMO_ASSERT(sgsn_tx_counter == 0);
391
392 /* verify that things are gone */
393 OSMO_ASSERT(count(gprs_llme_list()) == 0);
394}
395
396/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100397 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
398 */
399static void test_gmm_status_no_mmctx(void)
400{
401 struct gprs_llc_lle *lle;
402 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100403
404 printf("Testing GMM Status (no MMCTX)\n");
405
406 /* DTAP - GMM Status, protocol error */
407 static const unsigned char gmm_status[] = {
408 0x08, 0x20, 0x6f
409 };
410
411 /* Create an LLME */
412 OSMO_ASSERT(count(gprs_llme_list()) == 0);
413 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
414 lle = gprs_lle_get_or_create(local_tlli, 3);
415
416 OSMO_ASSERT(count(gprs_llme_list()) == 1);
417
418 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100419 send_0408_message(lle->llme, local_tlli,
420 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100421
422 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100423 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100424
425 /* verify that the LLME is gone */
426 OSMO_ASSERT(count(gprs_llme_list()) == 0);
427}
428
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100429/*
430 * Test the GMM Attach procedure
431 */
432static void test_gmm_attach(void)
433{
434 struct gprs_ra_id raid = { 0, };
435 struct sgsn_mm_ctx *ctx = NULL;
436 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100437 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100438 uint32_t foreign_tlli;
439 uint32_t local_tlli = 0;
440 struct gprs_llc_lle *lle;
441
442 /* DTAP - Attach Request */
443 /* The P-TMSI is not known by the SGSN */
444 static const unsigned char attach_req[] = {
445 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
446 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
447 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
448 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
449 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
450 };
451
452 /* DTAP - Identity Response IMEI */
453 static const unsigned char ident_resp_imei[] = {
454 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
455 0x56
456 };
457
458 /* DTAP - Identity Response IMSI */
459 static const unsigned char ident_resp_imsi[] = {
460 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
461 0x54
462 };
463
464 /* DTAP - Attach Complete */
465 static const unsigned char attach_compl[] = {
466 0x08, 0x03
467 };
468
469 /* DTAP - Detach Request (MO) */
470 /* normal detach, power_off = 0 */
471 static const unsigned char detach_req[] = {
472 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
473 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
474 };
475
476 printf("Testing GMM attach\n");
477
478 /* reset the PRNG used by sgsn_alloc_ptmsi */
479 srand(1);
480
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100481 ptmsi1 = sgsn_alloc_ptmsi();
482 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
483
484 /* reset the PRNG, so that the same P-TMSI sequence will be generated
485 * again */
486 srand(1);
487
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100488 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
489
490 /* Create a LLE/LLME */
491 OSMO_ASSERT(count(gprs_llme_list()) == 0);
492 lle = gprs_lle_get_or_create(foreign_tlli, 3);
493 OSMO_ASSERT(count(gprs_llme_list()) == 1);
494
495 /* inject the attach request */
496 send_0408_message(lle->llme, foreign_tlli,
497 attach_req, ARRAY_SIZE(attach_req));
498
499 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
500 OSMO_ASSERT(ctx != NULL);
501 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
502
503 /* we expect an identity request (IMEI) */
504 OSMO_ASSERT(sgsn_tx_counter == 1);
505
506 /* inject the identity response (IMEI) */
507 send_0408_message(ctx->llme, foreign_tlli,
508 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
509
510 /* we expect an identity request (IMSI) */
511 OSMO_ASSERT(sgsn_tx_counter == 1);
512
513 /* inject the identity response (IMSI) */
514 send_0408_message(ctx->llme, foreign_tlli,
515 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
516
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100517 /* check that the MM context has not been removed due to a failed
518 * authorization */
519 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
520
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100521 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100522
523 /* we expect an attach accept/reject */
524 OSMO_ASSERT(sgsn_tx_counter == 1);
525
526 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100527 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100528
529 /* inject the attach complete */
530 send_0408_message(ctx->llme, local_tlli,
531 attach_compl, ARRAY_SIZE(attach_compl));
532
533 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
534
535 /* we don't expect a response */
536 OSMO_ASSERT(sgsn_tx_counter == 0);
537
538 /* inject the detach */
539 send_0408_message(ctx->llme, local_tlli,
540 detach_req, ARRAY_SIZE(detach_req));
541
542 /* verify that things are gone */
543 OSMO_ASSERT(count(gprs_llme_list()) == 0);
544 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
545 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100546}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100547
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100548static void test_gmm_attach_acl(void)
549{
550 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
551
552 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
553 sgsn_acl_add("123456789012345", &sgsn->cfg);
554 printf("Auth policy 'closed': ");
555 test_gmm_attach();
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100556 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100557
558 sgsn->cfg.auth_policy = saved_auth_policy;
559}
560
561int my_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
562 int rc;
563 rc = __real_gprs_subscr_request_update(mmctx);
564 if (rc == -ENOTSUP) {
565 OSMO_ASSERT(mmctx->subscr);
566 gprs_subscr_update(mmctx->subscr);
567 }
568 return rc;
569};
570
571static void test_gmm_attach_subscr(void)
572{
573 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
574 struct gsm_subscriber *subscr;
575
576 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
577 subscr_request_update_cb = my_subscr_request_update;
578
579 subscr = gprs_subscr_get_or_create("123456789012345");
580 subscr->authorized = 1;
581 subscr_put(subscr);
582
583 printf("Auth policy 'remote': ");
584 test_gmm_attach();
585
586 subscr = gprs_subscr_get_by_imsi("123456789012345");
587 OSMO_ASSERT(subscr != NULL);
588 gprs_subscr_delete(subscr);
589
590 sgsn->cfg.auth_policy = saved_auth_policy;
591 subscr_request_update_cb = __real_gprs_subscr_request_update;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100592}
593
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +0100594/*
595 * Test the GMM Rejects
596 */
597static void test_gmm_reject(void)
598{
599 struct gprs_ra_id raid = { 0, };
600 struct sgsn_mm_ctx *ctx = NULL;
601 uint32_t foreign_tlli;
602 struct gprs_llc_lle *lle;
603 int idx;
604
605 /* DTAP - Attach Request */
606 /* Invalid MI length */
607 static const unsigned char attach_req_inv_mi_len[] = {
608 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
609 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
610 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
611 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
612 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
613 };
614
615 /* DTAP - Attach Request */
616 /* Invalid MI type (IMEI) */
617 static const unsigned char attach_req_inv_mi_type[] = {
618 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
619 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
620 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
621 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
622 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
623 };
624
625 /* DTAP - Routing Area Update Request */
626 static const unsigned char dtap_ra_upd_req[] = {
627 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
628 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
629 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
630 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
631 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
632 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
633 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
634 };
635
636 /* DTAP - Routing Area Update Request */
637 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
638 static const unsigned char dtap_ra_upd_req_inv_type[] = {
639 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
640 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
641 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
642 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
643 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
644 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
645 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
646 };
647
648 /* DTAP - Routing Area Update Request */
649 /* Invalid cap length */
650 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
651 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
652 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
653 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
654 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
655 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
656 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
657 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
658 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
659 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
660 };
661
662 struct test {
663 const char *title;
664 const unsigned char *msg;
665 unsigned msg_len;
666 unsigned num_resp;
667
668 };
669 static struct test tests[] = {
670 {
671 .title = "Attach Request (invalid MI length)",
672 .msg = attach_req_inv_mi_len,
673 .msg_len = sizeof(attach_req_inv_mi_len),
674 .num_resp = 1 /* Reject */
675
676 },
677 {
678 .title = "Attach Request (invalid MI type)",
679 .msg = attach_req_inv_mi_type,
680 .msg_len = sizeof(attach_req_inv_mi_type),
681 .num_resp = 1 /* Reject */
682 },
683 {
684 .title = "Routing Area Update Request (valid)",
685 .msg = dtap_ra_upd_req,
686 .msg_len = sizeof(dtap_ra_upd_req),
687 .num_resp = 2 /* XID Reset + Reject */
688 },
689 {
690 .title = "Routing Area Update Request (invalid type)",
691 .msg = dtap_ra_upd_req_inv_type,
692 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
693 .num_resp = 1 /* Reject */
694 },
695 {
696 .title = "Routing Area Update Request (invalid CAP length)",
697 .msg = dtap_ra_upd_req_inv_cap_len,
698 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
699 .num_resp = 1 /* Reject */
700 },
701 };
702
703 printf("Testing GMM reject\n");
704
705 /* reset the PRNG used by sgsn_alloc_ptmsi */
706 srand(1);
707
708 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
709
710 OSMO_ASSERT(count(gprs_llme_list()) == 0);
711
712 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
713 const struct test *test = &tests[idx];
714 printf(" - %s\n", test->title);
715
716 /* Create a LLE/LLME */
717 lle = gprs_lle_get_or_create(foreign_tlli, 3);
718 OSMO_ASSERT(count(gprs_llme_list()) == 1);
719
720 /* Inject the Request message */
721 send_0408_message(lle->llme, foreign_tlli,
722 test->msg, test->msg_len);
723
724 /* We expect a Reject message */
725 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
726 sgsn_tx_counter, test->num_resp);
727 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
728
729 /* verify that LLME/MM are removed */
730 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
731 OSMO_ASSERT(ctx == NULL);
732 OSMO_ASSERT(count(gprs_llme_list()) == 0);
733 }
734}
735
Jacob Erlbecke06476a2014-11-06 15:43:10 +0100736/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +0100737 * Test cancellation of attached MM contexts
738 */
739static void test_gmm_cancel(void)
740{
741 struct gprs_ra_id raid = { 0, };
742 struct sgsn_mm_ctx *ctx = NULL;
743 struct sgsn_mm_ctx *ictx;
744 uint32_t ptmsi1;
745 uint32_t foreign_tlli;
746 uint32_t local_tlli = 0;
747 struct gprs_llc_lle *lle;
748 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
749
750 /* DTAP - Attach Request */
751 /* The P-TMSI is not known by the SGSN */
752 static const unsigned char attach_req[] = {
753 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
754 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
755 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
756 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
757 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
758 };
759
760 /* DTAP - Identity Response IMEI */
761 static const unsigned char ident_resp_imei[] = {
762 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
763 0x56
764 };
765
766 /* DTAP - Identity Response IMSI */
767 static const unsigned char ident_resp_imsi[] = {
768 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
769 0x54
770 };
771
772 /* DTAP - Attach Complete */
773 static const unsigned char attach_compl[] = {
774 0x08, 0x03
775 };
776
777 printf("Testing cancellation\n");
778
779 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
780
781 /* reset the PRNG used by sgsn_alloc_ptmsi */
782 srand(1);
783
784 ptmsi1 = sgsn_alloc_ptmsi();
785 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
786
787 /* reset the PRNG, so that the same P-TMSI sequence will be generated
788 * again */
789 srand(1);
790
791 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
792
793 /* Create a LLE/LLME */
794 OSMO_ASSERT(count(gprs_llme_list()) == 0);
795 lle = gprs_lle_get_or_create(foreign_tlli, 3);
796 OSMO_ASSERT(count(gprs_llme_list()) == 1);
797
798 /* inject the attach request */
799 send_0408_message(lle->llme, foreign_tlli,
800 attach_req, ARRAY_SIZE(attach_req));
801
802 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
803 OSMO_ASSERT(ctx != NULL);
804 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
805
806 /* we expect an identity request (IMEI) */
807 OSMO_ASSERT(sgsn_tx_counter == 1);
808
809 /* inject the identity response (IMEI) */
810 send_0408_message(ctx->llme, foreign_tlli,
811 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
812
813 /* we expect an identity request (IMSI) */
814 OSMO_ASSERT(sgsn_tx_counter == 1);
815
816 /* inject the identity response (IMSI) */
817 send_0408_message(ctx->llme, foreign_tlli,
818 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
819
820 /* check that the MM context has not been removed due to a failed
821 * authorization */
822 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
823
824 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
825
826 /* we expect an attach accept/reject */
827 OSMO_ASSERT(sgsn_tx_counter == 1);
828
829 /* this has been randomly assigned by the SGSN */
830 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
831
832 /* inject the attach complete */
833 send_0408_message(ctx->llme, local_tlli,
834 attach_compl, ARRAY_SIZE(attach_compl));
835
836 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
837
838 /* we don't expect a response */
839 OSMO_ASSERT(sgsn_tx_counter == 0);
840
841 /* cancel */
842 gsm0408_gprs_access_cancelled(ctx);
843
844 /* verify that things are gone */
845 OSMO_ASSERT(count(gprs_llme_list()) == 0);
846 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
847 OSMO_ASSERT(!ictx);
848
849 sgsn->cfg.auth_policy = saved_auth_policy;
850}
851
852/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +0100853 * Test the dynamic allocation of P-TMSIs
854 */
855static void test_gmm_ptmsi_allocation(void)
856{
857 struct gprs_ra_id raid = { 0, };
858 struct sgsn_mm_ctx *ctx = NULL;
859 struct sgsn_mm_ctx *ictx;
860 uint32_t foreign_tlli;
861 uint32_t ptmsi1;
862 uint32_t ptmsi2;
863 uint32_t old_ptmsi;
864 uint32_t local_tlli = 0;
865 struct gprs_llc_lle *lle;
866 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
867
868 /* DTAP - Attach Request (IMSI 12131415161718) */
869 static const unsigned char attach_req[] = {
870 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
871 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
872 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
873 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
874 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
875 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
876 0x00,
877 };
878
879 /* DTAP - Identity Response IMEI */
880 static const unsigned char ident_resp_imei[] = {
881 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
882 0x56
883 };
884
885 /* DTAP - Attach Complete */
886 static const unsigned char attach_compl[] = {
887 0x08, 0x03
888 };
889
890 /* DTAP - Routing Area Update Request */
891 static const unsigned char ra_upd_req[] = {
892 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
893 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
894 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
895 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
896 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
897 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
898 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
899 };
900
901 /* DTAP - Routing Area Update Complete */
902 static const unsigned char ra_upd_complete[] = {
903 0x08, 0x0a
904 };
905
906 /* DTAP - Detach Request (MO) */
907 /* normal detach, power_off = 1 */
908 static const unsigned char detach_req[] = {
909 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
910 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
911 };
912
913 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
914
915 printf("Testing P-TMSI allocation\n");
916
917 printf(" - sgsn_alloc_ptmsi\n");
918
919 /* reset the PRNG used by sgsn_alloc_ptmsi */
920 srand(1);
921
922 ptmsi1 = sgsn_alloc_ptmsi();
923 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
924
925 ptmsi2 = sgsn_alloc_ptmsi();
926 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
927
928 OSMO_ASSERT(ptmsi1 != ptmsi2);
929
930 printf(" - Repeated Attach Request\n");
931
932 /* reset the PRNG, so that the same P-TMSI will be generated
933 * again */
934 srand(1);
935
936 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
937
938 /* Create a LLE/LLME */
939 OSMO_ASSERT(count(gprs_llme_list()) == 0);
940 lle = gprs_lle_get_or_create(foreign_tlli, 3);
941 OSMO_ASSERT(count(gprs_llme_list()) == 1);
942
943 /* inject the attach request */
944 send_0408_message(lle->llme, foreign_tlli,
945 attach_req, ARRAY_SIZE(attach_req));
946
947 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
948 OSMO_ASSERT(ctx != NULL);
949 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
950 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
951
952 old_ptmsi = ctx->p_tmsi_old;
953
954 /* we expect an identity request (IMEI) */
955 OSMO_ASSERT(sgsn_tx_counter == 1);
956
957 /* inject the identity response (IMEI) */
958 send_0408_message(ctx->llme, foreign_tlli,
959 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
960
961 /* check that the MM context has not been removed due to a failed
962 * authorization */
963 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
964
965 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
966 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
967
968 /* we expect an attach accept */
969 OSMO_ASSERT(sgsn_tx_counter == 1);
970
971 /* we ignore this and send the attach again */
972 send_0408_message(lle->llme, foreign_tlli,
973 attach_req, ARRAY_SIZE(attach_req));
974
975 /* the allocated P-TMSI should be the same */
976 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
977 OSMO_ASSERT(ctx != NULL);
978 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
979 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
980 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
981
982 /* inject the attach complete */
983 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
984 send_0408_message(ctx->llme, local_tlli,
985 attach_compl, ARRAY_SIZE(attach_compl));
986
987 /* we don't expect a response */
988 OSMO_ASSERT(sgsn_tx_counter == 0);
989
990 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
991 OSMO_ASSERT(ctx->p_tmsi_old == 0);
992 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
993
994 printf(" - Repeated RA Update Request\n");
995
996 /* inject the RA update request */
997 send_0408_message(ctx->llme, local_tlli,
998 ra_upd_req, ARRAY_SIZE(ra_upd_req));
999
1000 /* we expect an RA update accept */
1001 OSMO_ASSERT(sgsn_tx_counter == 1);
1002
1003 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1004 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1005 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1006
1007 /* repeat the RA update request */
1008 send_0408_message(ctx->llme, local_tlli,
1009 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1010
1011 /* we expect an RA update accept */
1012 OSMO_ASSERT(sgsn_tx_counter == 1);
1013
1014 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1015 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1016 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1017
1018 /* inject the RA update complete */
1019 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1020 send_0408_message(ctx->llme, local_tlli,
1021 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1022
1023 /* we don't expect a response */
1024 OSMO_ASSERT(sgsn_tx_counter == 0);
1025
1026 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1027 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1028 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1029
1030 /* inject the detach */
1031 send_0408_message(ctx->llme, local_tlli,
1032 detach_req, ARRAY_SIZE(detach_req));
1033
1034 /* verify that things are gone */
1035 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1036 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1037 OSMO_ASSERT(!ictx);
1038
1039 sgsn->cfg.auth_policy = saved_auth_policy;
1040}
1041
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001042static struct log_info_cat gprs_categories[] = {
1043 [DMM] = {
1044 .name = "DMM",
1045 .description = "Layer3 Mobility Management (MM)",
1046 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001047 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001048 },
1049 [DPAG] = {
1050 .name = "DPAG",
1051 .description = "Paging Subsystem",
1052 .color = "\033[1;38m",
1053 .enabled = 1, .loglevel = LOGL_NOTICE,
1054 },
1055 [DMEAS] = {
1056 .name = "DMEAS",
1057 .description = "Radio Measurement Processing",
1058 .enabled = 0, .loglevel = LOGL_NOTICE,
1059 },
1060 [DREF] = {
1061 .name = "DREF",
1062 .description = "Reference Counting",
1063 .enabled = 0, .loglevel = LOGL_NOTICE,
1064 },
1065 [DGPRS] = {
1066 .name = "DGPRS",
1067 .description = "GPRS Packet Service",
1068 .enabled = 1, .loglevel = LOGL_DEBUG,
1069 },
1070 [DNS] = {
1071 .name = "DNS",
1072 .description = "GPRS Network Service (NS)",
1073 .enabled = 1, .loglevel = LOGL_INFO,
1074 },
1075 [DBSSGP] = {
1076 .name = "DBSSGP",
1077 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1078 .enabled = 1, .loglevel = LOGL_DEBUG,
1079 },
1080 [DLLC] = {
1081 .name = "DLLC",
1082 .description = "GPRS Logical Link Control Protocol (LLC)",
1083 .enabled = 1, .loglevel = LOGL_DEBUG,
1084 },
1085 [DSNDCP] = {
1086 .name = "DSNDCP",
1087 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1088 .enabled = 1, .loglevel = LOGL_DEBUG,
1089 },
1090};
1091
1092static struct log_info info = {
1093 .cat = gprs_categories,
1094 .num_cat = ARRAY_SIZE(gprs_categories),
1095};
1096
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001097int main(int argc, char **argv)
1098{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001099 osmo_init_logging(&info);
1100 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1101 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1102
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001103 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001104 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001105
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001106 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001107 test_subscriber();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001108 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001109 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001110 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001111 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001112 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001113 test_gmm_attach_acl();
1114 test_gmm_attach_subscr();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001115 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001116 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001117 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001118 printf("Done\n");
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001119 return 0;
1120}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001121
1122
1123/* stubs */
1124struct osmo_prim_hdr;
1125int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1126{
1127 abort();
1128}