1b063a133dc9ce367e74aead5bfa62bd22917f1c
[osmocom-bb.git] / src / host / layer23 / src / mobile / gsm48_mm.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21
22 #include <stdint.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <arpa/inet.h>
28
29 #include <osmocore/msgb.h>
30 #include <osmocore/utils.h>
31 #include <osmocore/gsm48.h>
32 #include <osmocore/talloc.h>
33
34 #include <osmocom/bb/common/logging.h>
35 #include <osmocom/bb/common/osmocom_data.h>
36 #include <osmocom/bb/common/l23_app.h>
37 #include <osmocom/bb/common/networks.h>
38 #include <osmocom/bb/common/l1ctl.h>
39 #include <osmocom/bb/mobile/gsm48_cc.h>
40
41 extern void *l23_ctx;
42
43 void mm_conn_free(struct gsm48_mm_conn *conn);
44 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg);
45 static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg);
46 static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg);
47 static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type);
48 static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms);
49 static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg);
50 static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms);
51 static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg);
52 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg);
53 static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate);
54 static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg);
55 static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg);
56 static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg);
57
58 /*
59  * notes
60  */
61
62 /*
63  * Notes on IMSI detach procedure:
64  *
65  * At the end of the procedure, the state of MM, RR, cell selection: No SIM.
66  *
67  * In MM IDLE state, cell available: RR is establised, IMSI detach specific
68  * procedure is performed.
69  *
70  * In MM IDLE state, no cell: State is silently changed to No SIM.
71  *
72  * During any MM connection state, or Wait for network command: All MM
73  * connections (if any) are released locally, and IMSI detach specific
74  * procedure is performed.
75  *
76  * During IMSI detach processing: Request of IMSI detach is ignored.
77  *
78  * Any other state: The special 'delay_detach' flag is set only. If set, at any
79  * state transition we will clear the flag and restart the procedure again.
80  *
81  * The procedure is not spec conform, but always succeeds.
82  *
83  */
84
85 /* Notes on Service states:
86  *
87  * There are two PLMN search states:
88  *
89  * - PLMN SEARCH NORMAL
90  * - PLMN SEARCH
91  *
92  * They are entered, if: (4.2.1.2)
93  * - ME is switched on
94  * - SIM is inserted
95  * - user has asked PLMN selection in certain Service states
96  * - coverage is lost in certain Service states
97  * - roaming is denied
98  * - (optionally see 4.2.1.2)
99  *
100  * PLMN SEARCH NORMAL state is then entered, if all these conditions are met:
101  *  - SIM is valid
102  *  - SIM state is U1
103  *  - SIM LAI valid
104  *  - cell selected
105  *  - cell == SIM LAI
106  *
107  * Otherwhise PLMN SEARCH is entered.
108  *
109  * During PLMN SEARCH NORMAL state: (4.2.2.5)
110  *  - on expirery of T3211 or T3213: Perform location update, when back
111  *    to NORMAL SERVICE state.
112  *  - on expirery of T3212: Perform periodic location update, when back
113  *    to NORMAL SERVICE state.
114  *  - perform IMSI detach
115  *  - perform MM connections
116  *  - respond to paging (if possible)
117  *
118  * During PLMN SEARCH state: (4.2.2.6)
119  *  - reject MM connection except for emergency calls
120  *
121  *
122  * The NO CELL AVAILABLE state is entered, if:
123  *  - no cell found during PLMN search
124  *
125  * During NO CELL AVAILABLE state:
126  *  - reject any MM connection
127  *
128  *
129  * The NO IMSI state is entered if:
130  *  - SIM is invalid
131  *  - and cell is selected during PLMN SEARCH states
132  *
133  * During NO IMSO state: (4.2.2.4)
134  *  - reject MM connection except for emergency calls
135  *
136  *
137  * The LIMITED SERVICE state is entered if:
138  *  - SIM is valid
139  *  - and SIM state is U3
140  *  - and cell is selected
141  *
142  * During LIMITED SERVICE state: (4.2.2.3)
143  *  - reject MM connection except for emergency calls
144  *  - perform location update, if new LAI is entered
145  *
146  *
147  * The LOCATION UPDATE NEEDED state is entered if:
148  *  - SIM is valid
149  *  - and location update must be performed for any reason
150  *
151  * During LOCATION UPDATE NEEDED state:
152  *  - reject MM connection except for emergency calls
153  *
154  * This state is left if location update is possible and directly enter
155  * state ATTEMPTING TO UPDATE and trigger location update.
156  * The function gsm48_mm_loc_upd_possible() is used to check this on state
157  * change.
158  *
159  *
160  * The ATTEMPTING TO UPDATE state is entered if:
161  *  - SIM is valid
162  *  - and SIM state is U2
163  *  - and cell is selected
164  *
165  * During ATTEMPTING TO UPDATE state: (4.2.2.2)
166  *  - on expirery of T3211 or T3213: Perform location updated
167  *  - on expirery of T3212: Perform location updated
168  *  - on change of LAI: Perform location update
169  *  - (abnormal cases unsupported)
170  *  - accept MM connection for emergency calls
171  *  - trigger location update on any other MM connection
172  *  - respond to paging (with IMSI only, because in U2 TMSI is not valid)
173  *
174  *
175  * The NORMAL SERVICE state is entered if:
176  *  - SIM is valid
177  *  - and SIM state is U1
178  *  - and cell is selected
179  *  - and SIM LAI == cell
180  *
181  * During NORMAL SERVICE state: (4.2.2.1)
182  *  - on expirery of T3211 or T3213: Perform location updated
183  *  - on expirery of T3212: Perform location updated
184  *  - on change of LAI: Perform location update
185  *  - perform IMSI detach
186  *  - perform MM connections
187  *  - respond to paging
188  *
189  *
190  * gsm48_mm_set_plmn_search() is used enter PLMN SEARCH or PLMN SEARCH NORMAL
191  * state. Depending on the conditions above, the appropiate state is selected.
192  *
193  *
194  * gsm48_mm_return_idle() is used to select the Service state when returning
195  * to MM IDLE state after cell reselection.
196  *
197  *
198  * If cell selection process indicates NO_CELL_FOUND:
199  *
200  * - NO CELL AVAILABLE state is entered, if not already.
201  *
202  * gsm48_mm_no_cell_found() is used to select the Service state.
203  *
204  *
205  * If cell selection process indicates CELL_SELECTED:
206  *
207  * - NO IMSI state is entered, if no SIM valid.
208  * - Otherwise NORMAL SERVICES state is entered, if
209  *   SIM state is U1, SIM LAI == cell, IMSI is attached, T3212 not expired.
210  * - Otherwise NORMAL SERVICES state is entered, if
211  *   SIM state is U1, SIM LAI == cell, attach not required, T3212 not expired.
212  * - Otherwise LIMITED SERVICE state is entered, if
213  *   CS mode is automatic, cell is forbidden PLMN or forbidden LA.
214  * - Otherwise LIMITED SERVICE state is entered, if
215  *   CS mode is manual, cell is not the selected one.
216  * - Otherwise LOCATION UPDATE NEEDED state is entered.
217  *
218  * gsm48_mm_cell_selected() is used to select the Service state.
219  *
220  */
221
222 /*
223  * support functions
224  */
225
226 /* decode network name */
227 static int decode_network_name(char *name, int name_len,
228         const uint8_t *lv)
229 {
230         uint8_t in_len = lv[0];
231         int length, padding;
232
233         name[0] = '\0';
234         if (in_len < 1)
235                 return -EINVAL;
236
237         /* must be CB encoded */
238         if ((lv[1] & 0x70) != 0x00)
239                 return -ENOTSUP;
240
241         padding = lv[1] & 0x03;
242         length = ((in_len - 1) * 8 - padding) / 7;
243         if (length <= 0)
244                 return 0;
245         if (length >= name_len)
246                 length = name_len - 1;
247         gsm_7bit_decode(name, lv + 2, length);
248         name[length] = '\0';
249
250         return length;
251 }
252
253 /* encode 'mobile identity' */
254 int gsm48_encode_mi(uint8_t *buf, struct msgb *msg, struct osmocom_ms *ms,
255         uint8_t mi_type)
256 {
257         struct gsm_subscriber *subscr = &ms->subscr;
258         struct gsm_settings *set = &ms->settings;
259         uint8_t *ie;
260
261         switch(mi_type) {
262         case GSM_MI_TYPE_TMSI:
263                 gsm48_generate_mid_from_tmsi(buf, subscr->tmsi);
264                 break;
265         case GSM_MI_TYPE_IMSI:
266                 gsm48_generate_mid_from_imsi(buf, subscr->imsi);
267                 break;
268         case GSM_MI_TYPE_IMEI:
269                 gsm48_generate_mid_from_imsi(buf, set->imei);
270                 break;
271         case GSM_MI_TYPE_IMEISV:
272                 gsm48_generate_mid_from_imsi(buf, set->imeisv);
273                 break;
274         case GSM_MI_TYPE_NONE:
275         default:
276                 buf[0] = GSM48_IE_MOBILE_ID;
277                 buf[1] = 1;
278                 buf[2] = 0xf0;
279                 break;
280         }
281         /* alter MI type */
282         buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | mi_type;
283
284         if (msg) {
285                 /* MI as LV */
286                 ie = msgb_put(msg, 1 + buf[1]);
287                 memcpy(ie, buf + 1, 1 + buf[1]);
288         }
289
290         return 0;
291 }
292
293 /* encode 'classmark 1' */
294 int gsm48_encode_classmark1(struct gsm48_classmark1 *cm, uint8_t rev_lev,
295         uint8_t es_ind, uint8_t a5_1, uint8_t pwr_lev)
296 {
297         memset(cm, 0, sizeof(*cm));
298         cm->rev_lev = rev_lev;
299         cm->es_ind = es_ind;
300         cm->a5_1 = !a5_1;
301         cm->pwr_lev = pwr_lev;
302
303         return 0;
304 }
305
306 /*
307  * timers
308  */
309
310 static void timeout_mm_t3210(void *arg)
311 {
312         struct gsm48_mmlayer *mm = arg;
313
314         LOGP(DMM, LOGL_INFO, "timer T3210 (loc. upd. timeout) has fired\n");
315         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3210, NULL);
316 }
317
318 static void timeout_mm_t3211(void *arg)
319 {
320         struct gsm48_mmlayer *mm = arg;
321
322         LOGP(DSUM, LOGL_INFO, "Location update retry\n");
323         LOGP(DMM, LOGL_INFO, "timer T3211 (loc. upd. retry delay) has fired\n");
324         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3211, NULL);
325 }
326
327 static void timeout_mm_t3212(void *arg)
328 {
329         struct gsm48_mmlayer *mm = arg;
330
331         LOGP(DSUM, LOGL_INFO, "Periodic location update\n");
332         LOGP(DMM, LOGL_INFO, "timer T3212 (periodic loc. upd. delay) has "
333                 "fired\n");
334
335         /* reset attempt counter when attempting to update (4.4.4.5) */
336         if (mm->state == GSM48_MM_ST_MM_IDLE
337          && mm->substate == GSM48_MM_SST_ATTEMPT_UPDATE)
338                 mm->lupd_attempt = 0;
339
340         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3212, NULL);
341 }
342
343 static void timeout_mm_t3213(void *arg)
344 {
345         struct gsm48_mmlayer *mm = arg;
346
347         LOGP(DSUM, LOGL_INFO, "Location update retry\n");
348         LOGP(DMM, LOGL_INFO, "timer T3213 (delay after RA failure) has "
349                 "fired\n");
350         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213, NULL);
351 }
352
353 static void timeout_mm_t3230(void *arg)
354 {
355         struct gsm48_mmlayer *mm = arg;
356
357         LOGP(DMM, LOGL_INFO, "timer T3230 (MM connection timeout) has "
358                 "fired\n");
359         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3230, NULL);
360 }
361
362 static void timeout_mm_t3220(void *arg)
363 {
364         struct gsm48_mmlayer *mm = arg;
365
366         LOGP(DMM, LOGL_INFO, "timer T3220 (IMSI detach keepalive) has "
367                 "fired\n");
368         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3220, NULL);
369 }
370
371 static void timeout_mm_t3240(void *arg)
372 {
373         struct gsm48_mmlayer *mm = arg;
374
375         LOGP(DMM, LOGL_INFO, "timer T3240 (RR release timeout) has fired\n");
376         gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3240, NULL);
377 }
378
379 static void start_mm_t3210(struct gsm48_mmlayer *mm)
380 {
381         LOGP(DMM, LOGL_INFO, "starting T3210 (loc. upd. timeout) with %d.%d "
382                 "seconds\n", GSM_T3210_MS);
383         mm->t3210.cb = timeout_mm_t3210;
384         mm->t3210.data = mm;
385         bsc_schedule_timer(&mm->t3210, GSM_T3210_MS);
386 }
387
388 static void start_mm_t3211(struct gsm48_mmlayer *mm)
389 {
390         LOGP(DMM, LOGL_INFO, "starting T3211 (loc. upd. retry delay) with "
391                 "%d.%d seconds\n", GSM_T3211_MS);
392         mm->t3211.cb = timeout_mm_t3211;
393         mm->t3211.data = mm;
394         bsc_schedule_timer(&mm->t3211, GSM_T3211_MS);
395 }
396
397 static void start_mm_t3212(struct gsm48_mmlayer *mm, int sec)
398 {
399         /* don't start, if is not available */
400         if (!sec)
401                 return;
402
403         LOGP(DMM, LOGL_INFO, "starting T3212 (periodic loc. upd. delay) with "
404                 "%d seconds\n", sec);
405         mm->t3212.cb = timeout_mm_t3212;
406         mm->t3212.data = mm;
407         bsc_schedule_timer(&mm->t3212, sec, 0);
408 }
409
410 static void start_mm_t3213(struct gsm48_mmlayer *mm)
411 {
412         LOGP(DMM, LOGL_INFO, "starting T3213 (delay after RA failure) with "
413                 "%d.%d seconds\n", GSM_T3213_MS);
414         mm->t3213.cb = timeout_mm_t3213;
415         mm->t3213.data = mm;
416         bsc_schedule_timer(&mm->t3213, GSM_T3213_MS);
417 }
418
419 static void start_mm_t3220(struct gsm48_mmlayer *mm)
420 {
421         LOGP(DMM, LOGL_INFO, "starting T3220 (IMSI detach keepalive) with "
422                 "%d.%d seconds\n", GSM_T3220_MS);
423         mm->t3220.cb = timeout_mm_t3220;
424         mm->t3220.data = mm;
425         bsc_schedule_timer(&mm->t3220, GSM_T3220_MS);
426 }
427
428 static void start_mm_t3230(struct gsm48_mmlayer *mm)
429 {
430         LOGP(DMM, LOGL_INFO, "starting T3230 (MM connection timeout) with "
431                 "%d.%d seconds\n", GSM_T3230_MS);
432         mm->t3230.cb = timeout_mm_t3230;
433         mm->t3230.data = mm;
434         bsc_schedule_timer(&mm->t3230, GSM_T3230_MS);
435 }
436
437 static void start_mm_t3240(struct gsm48_mmlayer *mm)
438 {
439         LOGP(DMM, LOGL_INFO, "starting T3240 (RR release timeout) with %d.%d "
440                 "seconds\n", GSM_T3240_MS);
441         mm->t3240.cb = timeout_mm_t3240;
442         mm->t3240.data = mm;
443         bsc_schedule_timer(&mm->t3240, GSM_T3240_MS);
444 }
445
446 static void stop_mm_t3210(struct gsm48_mmlayer *mm)
447 {
448         if (bsc_timer_pending(&mm->t3210)) {
449                 LOGP(DMM, LOGL_INFO, "stopping pending (loc. upd. timeout) "
450                         "timer T3210\n");
451                 bsc_del_timer(&mm->t3210);
452         }
453 }
454
455 static void stop_mm_t3211(struct gsm48_mmlayer *mm)
456 {
457         if (bsc_timer_pending(&mm->t3211)) {
458                 LOGP(DMM, LOGL_INFO, "stopping pending (loc. upd. retry "
459                         "delay) timer T3211\n");
460                 bsc_del_timer(&mm->t3211);
461         }
462 }
463
464 static void stop_mm_t3212(struct gsm48_mmlayer *mm)
465 {
466         if (bsc_timer_pending(&mm->t3212)) {
467                 LOGP(DMM, LOGL_INFO, "stopping pending (periodic loc. upd. "
468                         "delay) timer T3212\n");
469                 bsc_del_timer(&mm->t3212);
470         }
471 }
472
473 static void stop_mm_t3213(struct gsm48_mmlayer *mm)
474 {
475         if (bsc_timer_pending(&mm->t3213)) {
476                 LOGP(DMM, LOGL_INFO, "stopping pending (delay after RA "
477                         "failure) timer T3213\n");
478                 bsc_del_timer(&mm->t3213);
479         }
480 }
481
482 static void stop_mm_t3220(struct gsm48_mmlayer *mm)
483 {
484         if (bsc_timer_pending(&mm->t3220)) {
485                 LOGP(DMM, LOGL_INFO, "stopping pending (IMSI detach keepalive) "
486                         "timer T3220\n");
487                 bsc_del_timer(&mm->t3220);
488         }
489 }
490
491 static void stop_mm_t3230(struct gsm48_mmlayer *mm)
492 {
493         if (bsc_timer_pending(&mm->t3230)) {
494                 LOGP(DMM, LOGL_INFO, "stopping pending (MM connection timeout) "
495                         "timer T3230\n");
496                 bsc_del_timer(&mm->t3230);
497         }
498 }
499
500 static void stop_mm_t3240(struct gsm48_mmlayer *mm)
501 {
502         if (bsc_timer_pending(&mm->t3240)) {
503                 LOGP(DMM, LOGL_INFO, "stopping pending (RR release timeout) "
504                         "timer T3240\n");
505                 bsc_del_timer(&mm->t3240);
506         }
507 }
508
509 static void stop_mm_t3241(struct gsm48_mmlayer *mm)
510 {
511         /* not implemented, not required */
512 }
513
514 /*
515  * messages
516  */
517
518 /* names of MM events */
519 static const struct value_string gsm48_mmevent_names[] = {
520         { GSM48_MM_EVENT_CELL_SELECTED, "MM_EVENT_CELL_SELECTED" },
521         { GSM48_MM_EVENT_NO_CELL_FOUND, "MM_EVENT_NO_CELL_FOUND" },
522         { GSM48_MM_EVENT_TIMEOUT_T3210, "MM_EVENT_TIMEOUT_T3210" },
523         { GSM48_MM_EVENT_TIMEOUT_T3211, "MM_EVENT_TIMEOUT_T3211" },
524         { GSM48_MM_EVENT_TIMEOUT_T3212, "MM_EVENT_TIMEOUT_T3212" },
525         { GSM48_MM_EVENT_TIMEOUT_T3213, "MM_EVENT_TIMEOUT_T3213" },
526         { GSM48_MM_EVENT_TIMEOUT_T3220, "MM_EVENT_TIMEOUT_T3220" },
527         { GSM48_MM_EVENT_TIMEOUT_T3230, "MM_EVENT_TIMEOUT_T3230" },
528         { GSM48_MM_EVENT_TIMEOUT_T3240, "MM_EVENT_TIMEOUT_T3240" },
529         { GSM48_MM_EVENT_IMSI_DETACH,   "MM_EVENT_IMSI_DETACH" },
530         { GSM48_MM_EVENT_PAGING,        "MM_EVENT_PAGING" },
531         { GSM48_MM_EVENT_AUTH_RESPONSE, "MM_EVENT_AUTH_RESPONSE" },
532         { GSM48_MM_EVENT_SYSINFO,       "MM_EVENT_SYSINFO" },
533         { GSM48_MM_EVENT_USER_PLMN_SEL, "MM_EVENT_USER_PLMN_SEL" },
534         { 0,                            NULL }
535 };
536
537 const char *get_mmevent_name(int value)
538 {
539         return get_value_string(gsm48_mmevent_names, value);
540 }
541
542 /* names of MM-SAP */
543 static const struct value_string gsm48_mm_msg_names[] = {
544         { GSM48_MT_MM_IMSI_DETACH_IND,  "MT_MM_IMSI_DETACH_IND" },
545         { GSM48_MT_MM_LOC_UPD_ACCEPT,   "MT_MM_LOC_UPD_ACCEPT" },
546         { GSM48_MT_MM_LOC_UPD_REJECT,   "MT_MM_LOC_UPD_REJECT" },
547         { GSM48_MT_MM_LOC_UPD_REQUEST,  "MT_MM_LOC_UPD_REQUEST" },
548         { GSM48_MT_MM_AUTH_REJ,         "MT_MM_AUTH_REJ" },
549         { GSM48_MT_MM_AUTH_REQ,         "MT_MM_AUTH_REQ" },
550         { GSM48_MT_MM_AUTH_RESP,        "MT_MM_AUTH_RESP" },
551         { GSM48_MT_MM_ID_REQ,           "MT_MM_ID_REQ" },
552         { GSM48_MT_MM_ID_RESP,          "MT_MM_ID_RESP" },
553         { GSM48_MT_MM_TMSI_REALL_CMD,   "MT_MM_TMSI_REALL_CMD" },
554         { GSM48_MT_MM_TMSI_REALL_COMPL, "MT_MM_TMSI_REALL_COMPL" },
555         { GSM48_MT_MM_CM_SERV_ACC,      "MT_MM_CM_SERV_ACC" },
556         { GSM48_MT_MM_CM_SERV_REJ,      "MT_MM_CM_SERV_REJ" },
557         { GSM48_MT_MM_CM_SERV_ABORT,    "MT_MM_CM_SERV_ABORT" },
558         { GSM48_MT_MM_CM_SERV_REQ,      "MT_MM_CM_SERV_REQ" },
559         { GSM48_MT_MM_CM_SERV_PROMPT,   "MT_MM_CM_SERV_PROMPT" },
560         { GSM48_MT_MM_CM_REEST_REQ,     "MT_MM_CM_REEST_REQ" },
561         { GSM48_MT_MM_ABORT,            "MT_MM_ABORT" },
562         { GSM48_MT_MM_NULL,             "MT_MM_NULL" },
563         { GSM48_MT_MM_STATUS,           "MT_MM_STATUS" },
564         { GSM48_MT_MM_INFO,             "MT_MM_INFO" },
565         { 0,                            NULL }
566 };
567
568 const char *get_mm_name(int value)
569 {
570         return get_value_string(gsm48_mm_msg_names, value);
571 }
572
573 /* names of MMxx-SAP */
574 static const struct value_string gsm48_mmxx_msg_names[] = {
575         { GSM48_MMCC_EST_REQ,           "MMCC_EST_REQ" },
576         { GSM48_MMCC_EST_IND,           "MMCC_EST_IND" },
577         { GSM48_MMCC_EST_CNF,           "MMCC_EST_CNF" },
578         { GSM48_MMCC_REL_REQ,           "MMCC_REL_REQ" },
579         { GSM48_MMCC_REL_IND,           "MMCC_REL_IND" },
580         { GSM48_MMCC_DATA_REQ,          "MMCC_DATA_REQ" },
581         { GSM48_MMCC_DATA_IND,          "MMCC_DATA_IND" },
582         { GSM48_MMCC_UNIT_DATA_REQ,     "MMCC_UNIT_DATA_REQ" },
583         { GSM48_MMCC_UNIT_DATA_IND,     "MMCC_UNIT_DATA_IND" },
584         { GSM48_MMCC_SYNC_IND,          "MMCC_SYNC_IND" },
585         { GSM48_MMCC_REEST_REQ,         "MMCC_REEST_REQ" },
586         { GSM48_MMCC_REEST_CNF,         "MMCC_REEST_CNF" },
587         { GSM48_MMCC_ERR_IND,           "MMCC_ERR_IND" },
588         { GSM48_MMCC_PROMPT_IND,        "MMCC_PROMPT_IND" },
589         { GSM48_MMCC_PROMPT_REJ,        "MMCC_PROMPT_REJ" },
590         { GSM48_MMSS_EST_REQ,           "MMSS_EST_REQ" },
591         { GSM48_MMSS_EST_IND,           "MMSS_EST_IND" },
592         { GSM48_MMSS_EST_CNF,           "MMSS_EST_CNF" },
593         { GSM48_MMSS_REL_REQ,           "MMSS_REL_REQ" },
594         { GSM48_MMSS_REL_IND,           "MMSS_REL_IND" },
595         { GSM48_MMSS_DATA_REQ,          "MMSS_DATA_REQ" },
596         { GSM48_MMSS_DATA_IND,          "MMSS_DATA_IND" },
597         { GSM48_MMSS_UNIT_DATA_REQ,     "MMSS_UNIT_DATA_REQ" },
598         { GSM48_MMSS_UNIT_DATA_IND,     "MMSS_UNIT_DATA_IND" },
599         { GSM48_MMSS_REEST_REQ,         "MMSS_REEST_REQ" },
600         { GSM48_MMSS_REEST_CNF,         "MMSS_REEST_CNF" },
601         { GSM48_MMSS_ERR_IND,           "MMSS_ERR_IND" },
602         { GSM48_MMSS_PROMPT_IND,        "MMSS_PROMPT_IND" },
603         { GSM48_MMSS_PROMPT_REJ,        "MMSS_PROMPT_REJ" },
604         { GSM48_MMSMS_EST_REQ,          "MMSMS_EST_REQ" },
605         { GSM48_MMSMS_EST_IND,          "MMSMS_EST_IND" },
606         { GSM48_MMSMS_EST_CNF,          "MMSMS_EST_CNF" },
607         { GSM48_MMSMS_REL_REQ,          "MMSMS_REL_REQ" },
608         { GSM48_MMSMS_REL_IND,          "MMSMS_REL_IND" },
609         { GSM48_MMSMS_DATA_REQ,         "MMSMS_DATA_REQ" },
610         { GSM48_MMSMS_DATA_IND,         "MMSMS_DATA_IND" },
611         { GSM48_MMSMS_UNIT_DATA_REQ,    "MMSMS_UNIT_DATA_REQ" },
612         { GSM48_MMSMS_UNIT_DATA_IND,    "MMSMS_UNIT_DATA_IND" },
613         { GSM48_MMSMS_REEST_REQ,        "MMSMS_REEST_REQ" },
614         { GSM48_MMSMS_REEST_CNF,        "MMSMS_REEST_CNF" },
615         { GSM48_MMSMS_ERR_IND,          "MMSMS_ERR_IND" },
616         { GSM48_MMSMS_PROMPT_IND,       "MMSMS_PROMPT_IND" },
617         { GSM48_MMSMS_PROMPT_REJ,       "MMSMS_PROMPT_REJ" },
618         { 0,                            NULL }
619 };
620
621 const char *get_mmxx_name(int value)
622 {
623         return get_value_string(gsm48_mmxx_msg_names, value);
624 }
625
626 /* names of MMR-SAP */
627 static const struct value_string gsm48_mmr_msg_names[] = {
628         { GSM48_MMR_REG_REQ,            "MMR_REG_REQ" },
629         { GSM48_MMR_REG_CNF,            "MMR_REG_CNF" },
630         { GSM48_MMR_NREG_REQ,           "MMR_NREG_REQ" },
631         { GSM48_MMR_NREG_IND,           "MMR_NREG_IND" },
632         { 0,                            NULL }
633 };
634
635 const char *get_mmr_name(int value)
636 {
637         return get_value_string(gsm48_mmr_msg_names, value);
638 }
639
640 /* allocate GSM 04.08 message (MMxx-SAP) */
641 struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
642         uint8_t transaction_id)
643 {
644         struct msgb *msg;
645         struct gsm48_mmxx_hdr *mmh;
646
647         msg = msgb_alloc_headroom(MMXX_ALLOC_SIZE+MMXX_ALLOC_HEADROOM,
648                 MMXX_ALLOC_HEADROOM, "GSM 04.08 MMxx");
649         if (!msg)
650                 return NULL;
651
652         mmh = (struct gsm48_mmxx_hdr *)msgb_put(msg, sizeof(*mmh));
653         mmh->msg_type = msg_type;
654         mmh->ref = ref;
655         mmh->transaction_id = transaction_id;
656
657         return msg;
658 }
659
660 /* allocate MM event message */
661 struct msgb *gsm48_mmevent_msgb_alloc(int msg_type)
662 {
663         struct msgb *msg;
664         struct gsm48_mm_event *mme;
665
666         msg = msgb_alloc_headroom(sizeof(*mme), 0, "GSM 04.08 MM event");
667         if (!msg)
668                 return NULL;
669
670         mme = (struct gsm48_mm_event *)msgb_put(msg, sizeof(*mme));
671         mme->msg_type = msg_type;
672
673         return msg;
674 }
675
676 /* allocate MMR message */
677 struct msgb *gsm48_mmr_msgb_alloc(int msg_type)
678 {
679         struct msgb *msg;
680         struct gsm48_mmr *mmr;
681
682         msg = msgb_alloc_headroom(sizeof(*mmr), 0, "GSM 04.08 MMR");
683         if (!msg)
684                 return NULL;
685
686         mmr = (struct gsm48_mmr *)msgb_put(msg, sizeof(*mmr));
687         mmr->msg_type = msg_type;
688
689         return msg;
690 }
691
692 /* queue message (MMxx-SAP) */
693 int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg)
694 {
695         struct gsm48_mmlayer *mm = &ms->mmlayer;
696
697         msgb_enqueue(&mm->mmxx_upqueue, msg);
698
699         return 0;
700 }
701
702 /* queue message (MMR-SAP) */
703 int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
704 {
705         struct gsm48_mmlayer *mm = &ms->mmlayer;
706
707         msgb_enqueue(&mm->mmr_downqueue, msg);
708
709         return 0;
710 }
711
712 /* queue MM event message */
713 int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg)
714 {
715         struct gsm48_mmlayer *mm = &ms->mmlayer;
716
717         msgb_enqueue(&mm->event_queue, msg);
718
719         return 0;
720 }
721
722 /* dequeue messages (MMxx-SAP) */
723 int gsm48_mmxx_dequeue(struct osmocom_ms *ms)
724 {
725         struct gsm48_mmlayer *mm = &ms->mmlayer;
726         struct msgb *msg;
727         struct gsm48_mmxx_hdr *mmh;
728         int work = 0;
729         
730         while ((msg = msgb_dequeue(&mm->mmxx_upqueue))) {
731                 mmh = (struct gsm48_mmxx_hdr *) msg->data;
732                 switch (mmh->msg_type & GSM48_MMXX_MASK) {
733                 case GSM48_MMCC_CLASS:
734                         gsm48_rcv_cc(ms, msg);
735                         break;
736 #if 0
737                 case GSM48_MMSS_CLASS:
738                         gsm48_rcv_ss(ms, msg);
739                         break;
740                 case GSM48_MMSMS_CLASS:
741                         gsm48_rcv_sms(ms, msg);
742                         break;
743 #endif
744                 }
745                 msgb_free(msg);
746                 work = 1; /* work done */
747         }
748         
749         return work;
750 }
751
752 /* dequeue messages (MMR-SAP) */
753 int gsm48_mmr_dequeue(struct osmocom_ms *ms)
754 {
755         struct gsm48_mmlayer *mm = &ms->mmlayer;
756         struct msgb *msg;
757         struct gsm48_mmr *mmr;
758         int work = 0;
759         
760         while ((msg = msgb_dequeue(&mm->mmr_downqueue))) {
761                 mmr = (struct gsm48_mmr *) msg->data;
762                 gsm48_rcv_mmr(ms, msg);
763                 msgb_free(msg);
764                 work = 1; /* work done */
765         }
766         
767         return work;
768 }
769
770 /* dequeue messages (RR-SAP) */
771 int gsm48_rr_dequeue(struct osmocom_ms *ms)
772 {
773         struct gsm48_mmlayer *mm = &ms->mmlayer;
774         struct msgb *msg;
775         int work = 0;
776         
777         while ((msg = msgb_dequeue(&mm->rr_upqueue))) {
778                 /* msg is freed there */
779                 gsm48_rcv_rr(ms, msg);
780                 work = 1; /* work done */
781         }
782         
783         return work;
784 }
785
786 /* dequeue MM event messages */
787 int gsm48_mmevent_dequeue(struct osmocom_ms *ms)
788 {
789         struct gsm48_mmlayer *mm = &ms->mmlayer;
790         struct gsm48_mm_event *mme;
791         struct msgb *msg;
792         int work = 0;
793         
794         while ((msg = msgb_dequeue(&mm->event_queue))) {
795                 mme = (struct gsm48_mm_event *) msg->data;
796                 gsm48_mm_ev(ms, mme->msg_type, msg);
797                 msgb_free(msg);
798                 work = 1; /* work done */
799         }
800         
801         return work;
802 }
803
804 /* push RR header and send to RR */
805 static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg,
806         int msg_type, uint8_t cause)
807 {
808         struct gsm48_rr_hdr *rrh;
809
810         /* push RR header */
811         msgb_push(msg, sizeof(struct gsm48_rr_hdr));
812         rrh = (struct gsm48_rr_hdr *) msg->data;
813         rrh->msg_type = msg_type;
814         rrh->cause = cause;
815
816         /* send message to RR */
817         return gsm48_rr_downmsg(ms, msg);
818 }
819
820 /*
821  * state transition
822  */
823
824 const char *gsm48_mm_state_names[] = {
825         "NULL",
826         "undefined 1",
827         "undefined 2",
828         "location updating initiated",
829         "undefined 4",
830         "wait for outgoing MM connection",
831         "MM connection active",
832         "IMSI detach initiated",
833         "process CM service prompt",
834         "wait for network command",
835         "location updating reject",
836         "undefined 11",
837         "undefined 12",
838         "wait for RR connection (location updating)",
839         "wait for RR connection (MM connection)",
840         "wait for RR connection (IMSI detach)",
841         "undefined 16",
842         "wait for re-establishment",
843         "wait for RR connection active",
844         "MM idle",
845         "wait for additional outgoing MM connection",
846         "MM_CONN_ACTIVE_VGCS",
847         "WAIT_RR_CONN_VGCS",
848         "location updating pending",
849         "IMSI detach pending",
850         "RR connection release not allowed"
851 };
852
853 const char *gsm48_mm_substate_names[] = {
854         "NULL",
855         "normal service",
856         "attempting to update",
857         "limited service",
858         "no IMSI",
859         "no cell available",
860         "location updating needed",
861         "PLMN search",
862         "PLMN search (normal)",
863         "RX_VGCS_NORMAL",
864         "RX_VGCS_LIMITED"
865 };
866
867 /* change state from LOCATION UPDATE NEEDED to ATTEMPTING TO UPDATE */
868 static int gsm48_mm_loc_upd_possible(struct gsm48_mmlayer *mm)
869 {
870         // TODO: check if really possible
871         new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_ATTEMPT_UPDATE);
872         return gsm48_mm_loc_upd_normal(mm->ms, NULL);
873 }
874
875 /* Set new MM state, also new substate in case of MM IDLE state. */
876 static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate)
877 {
878         /* IDLE -> IDLE */
879         if (mm->state == GSM48_MM_ST_MM_IDLE && state == mm->state)
880                 LOGP(DMM, LOGL_INFO, "new MM IDLE state %s -> %s\n",
881                         gsm48_mm_substate_names[mm->substate],
882                         gsm48_mm_substate_names[substate]);
883         /* IDLE -> non-IDLE */
884         else if (mm->state == GSM48_MM_ST_MM_IDLE)
885                 LOGP(DMM, LOGL_INFO, "new state MM IDLE, %s -> %s\n",
886                         gsm48_mm_substate_names[mm->substate],
887                         gsm48_mm_state_names[state]);
888         /* non-IDLE -> IDLE */
889         else if (state == GSM48_MM_ST_MM_IDLE)
890                 LOGP(DMM, LOGL_INFO, "new state %s -> MM IDLE, %s\n",
891                         gsm48_mm_state_names[mm->state],
892                         gsm48_mm_substate_names[substate]);
893         /* non-IDLE -> non-IDLE */
894         else
895                 LOGP(DMM, LOGL_INFO, "new state %s -> %s\n",
896                         gsm48_mm_state_names[mm->state],
897                         gsm48_mm_state_names[state]);
898
899         /* remember most recent substate */
900         if (mm->state == GSM48_MM_ST_MM_IDLE)
901                 mm->mr_substate = mm->substate;
902
903         mm->state = state;
904         mm->substate = substate;
905
906         /* resend detach event, if flag is set */
907         if (state == GSM48_MM_ST_MM_IDLE && mm->delay_detach) {
908                 struct msgb *nmsg;
909
910                 mm->delay_detach = 0;
911
912                 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
913                 if (!nmsg)
914                         return;
915                 gsm48_mmevent_msg(mm->ms, nmsg);
916         }
917
918         /* 4.4.2 start T3212 in MM IDLE mode if not started or has expired */
919         if (state == GSM48_MM_ST_MM_IDLE
920          && (substate == GSM48_MM_SST_NORMAL_SERVICE
921           || substate == GSM48_MM_SST_ATTEMPT_UPDATE)) {
922                 /* start periodic location update timer */
923                 if (!bsc_timer_pending(&mm->t3212))
924                         start_mm_t3212(mm, mm->t3212_value);
925                 /* perform pending location update */
926                 if (mm->lupd_retry) {
927                         LOGP(DMM, LOGL_INFO, "Loc. upd. pending (type %d)\n",
928                                 mm->lupd_type);
929                         mm->lupd_retry = 0;
930                         gsm48_mm_loc_upd(mm->ms, NULL);
931                         /* must exit, because this function can be called
932                          * recursively
933                          */
934                         return;
935                 }
936                 if (mm->lupd_periodic) {
937                         struct gsm48_sysinfo *s = &mm->ms->cellsel.sel_si;
938
939                         LOGP(DMM, LOGL_INFO, "Periodic loc. upd. pending "
940                                 "(type %d)\n", mm->lupd_type);
941                         mm->lupd_periodic = 0;
942                         if (s->t3212)
943                                 gsm48_mm_loc_upd_periodic(mm->ms, NULL);
944                         else
945                                 LOGP(DMM, LOGL_INFO, "but not requred\n");
946                         /* must exit, because this function can be called
947                          * recursively
948                          */
949                         return;
950                 }
951         }
952
953         /* check if location update is possible */
954         if (state == GSM48_MM_ST_MM_IDLE
955          && substate == GSM48_MM_SST_LOC_UPD_NEEDED) {
956                 gsm48_mm_loc_upd_possible(mm);
957                 /* must exit, because this function can be called recursively */
958                 return;
959         }
960 }
961
962 /* return PLMN SEARCH or PLMN SEARCH NORMAL state */
963 static int gsm48_mm_set_plmn_search(struct osmocom_ms *ms)
964 {
965         struct gsm_subscriber *subscr = &ms->subscr;
966         struct gsm322_cellsel *cs = &ms->cellsel;
967
968         /* SIM not inserted */
969         if (!subscr->sim_valid) {
970                 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
971                         "no SIM.\n");
972                 return GSM48_MM_SST_PLMN_SEARCH;
973         }
974
975         /* SIM not updated */
976         if (subscr->ustate != GSM_SIM_U1_UPDATED) {
977                 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
978                         "SIM not updated.\n");
979                 return GSM48_MM_SST_PLMN_SEARCH;
980         }
981         if (subscr->lac == 0x0000 || subscr->lac >= 0xfffe) {
982                 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
983                         "LAI in SIM not valid.\n");
984                 return GSM48_MM_SST_PLMN_SEARCH;
985         }
986
987         /* no cell selected */
988         if (!cs->selected) {
989                 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
990                         "no cell selected.\n");
991                 return GSM48_MM_SST_PLMN_SEARCH;
992         }
993
994         /* selected cell's LAI not equal to LAI stored on the sim */
995         if (cs->sel_mcc != subscr->mcc
996          || cs->sel_mnc != subscr->mnc
997          || cs->sel_lac != subscr->lac) {
998                 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
999                         "LAI of selected cell (MCC %s MNC %s LAC 0x%04x) "
1000                         "!= LAI in SIM (MCC %s MNC %s LAC 0x%04x).\n",
1001                         gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc),
1002                         cs->sel_lac, gsm_print_mcc(subscr->mcc),
1003                         gsm_print_mnc(subscr->mnc), subscr->lac);
1004                 return GSM48_MM_SST_PLMN_SEARCH;
1005         }
1006
1007         /* SIM is updated in this LA */
1008         LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH NORMAL state.\n");
1009         return GSM48_MM_SST_PLMN_SEARCH_NORMAL;
1010 }
1011
1012 /* 4.2.3 when returning to MM IDLE state, this function is called */
1013 static int gsm48_mm_return_idle(struct osmocom_ms *ms, struct msgb *msg)
1014 {
1015         struct gsm_subscriber *subscr = &ms->subscr;
1016         struct gsm48_mmlayer *mm = &ms->mmlayer;
1017         struct gsm322_cellsel *cs = &ms->cellsel;
1018
1019         /* 4.4.4.9 start T3211 when RR is released */
1020         if (mm->start_t3211) {
1021                 LOGP(DMM, LOGL_INFO, "Starting T3211 after RR release.\n");
1022                 mm->start_t3211 = 0;
1023                 start_mm_t3211(mm);
1024         }
1025
1026         /* return from location update with "Roaming not allowed" */
1027         if (mm->state == GSM48_MM_ST_LOC_UPD_REJ && mm->lupd_rej_cause == 13) {
1028                 LOGP(DMM, LOGL_INFO, "Roaming not allowed as returning to "
1029                         "MM IDLE\n");
1030                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1031                         gsm48_mm_set_plmn_search(ms));
1032
1033                 return 0;
1034         }
1035
1036         /* no SIM present or invalid */
1037         if (!subscr->sim_valid) {
1038                 LOGP(DMM, LOGL_INFO, "SIM invalid as returning to MM IDLE\n");
1039
1040                 /* stop periodic location updating */
1041                 mm->lupd_pending = 0;
1042                 stop_mm_t3212(mm); /* 4.4.2 */
1043
1044                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_IMSI);
1045
1046                 return 0;
1047         }
1048
1049         /* selected cell equals the registered LAI */
1050         if (subscr->lac /* valid */
1051          && cs->sel_mcc == subscr->mcc
1052          && cs->sel_mnc == subscr->mnc
1053          && cs->sel_lac == subscr->lac) {
1054                 LOGP(DMM, LOGL_INFO, "We are in registered LAI as returning "
1055                         "to MM IDLE\n");
1056                 /* if SIM not updated (abnormal case as described in 4.4.4.9) */
1057                 if (subscr->ustate != GSM_SIM_U1_UPDATED)
1058                         new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1059                                 GSM48_MM_SST_ATTEMPT_UPDATE);
1060                 else
1061                         new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1062                                 GSM48_MM_SST_NORMAL_SERVICE);
1063
1064                 return 0;
1065         }
1066
1067         /* location update allowed */
1068         if (cs->state == GSM322_C3_CAMPED_NORMALLY) {
1069                 LOGP(DMM, LOGL_INFO, "We are camping normally as returning to "
1070                         "MM IDLE\n");
1071                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1072                         GSM48_MM_SST_LOC_UPD_NEEDED);
1073         } else { /* location update not allowed */
1074                 LOGP(DMM, LOGL_INFO, "We are camping on any cell as returning "
1075                         "to MM IDLE\n");
1076                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1077                         GSM48_MM_SST_LIMITED_SERVICE);
1078         }
1079
1080         return 0;
1081 }
1082
1083 /* 4.2.1.1 Service state PLMN SEARCH (NORMAL) is left if no cell found */
1084 static int gsm48_mm_no_cell_found(struct osmocom_ms *ms, struct msgb *msg)
1085 {
1086         struct gsm48_mmlayer *mm = &ms->mmlayer;
1087
1088         new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_CELL_AVAIL);
1089
1090         return 0;
1091 }
1092
1093 /* 4.2.1.1 Service state PLMN SEARCH (NORMAL) / NO CELL AVAILABLE is left
1094  * if cell selected
1095  */
1096 static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg)
1097 {
1098         struct gsm_subscriber *subscr = &ms->subscr;
1099         struct gsm48_mmlayer *mm = &ms->mmlayer;
1100         struct gsm322_plmn *plmn = &ms->plmn;
1101         struct gsm322_cellsel *cs = &ms->cellsel;
1102         struct gsm48_sysinfo *s = &cs->sel_si;
1103         struct gsm_settings *set = &ms->settings;
1104
1105         /* no SIM is inserted */
1106         if (!subscr->sim_valid) {
1107                 LOGP(DMM, LOGL_INFO, "SIM invalid as cell is selected.\n");
1108                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_IMSI);
1109
1110                 return 0;
1111         }
1112
1113         /* SIM not updated in this LA */
1114         if (subscr->ustate == GSM_SIM_U1_UPDATED
1115          && subscr->lac /* valid */
1116          && cs->sel_mcc == subscr->mcc
1117          && cs->sel_mnc == subscr->mnc
1118          && cs->sel_lac == subscr->lac
1119          && !mm->lupd_periodic) {
1120                 if (subscr->imsi_attached) {
1121                         struct msgb *nmsg;
1122
1123                         LOGP(DMM, LOGL_INFO, "Valid in location area.\n");
1124                         new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1125                                 GSM48_MM_SST_NORMAL_SERVICE);
1126
1127                         /* send message to PLMN search process */
1128                         nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
1129                         if (!nmsg)
1130                                 return -ENOMEM;
1131                         gsm322_plmn_sendmsg(ms, nmsg);
1132
1133                         return 0;
1134                 }
1135                 if (!s->att_allowed) {
1136                         struct msgb *nmsg;
1137
1138                         LOGP(DMM, LOGL_INFO, "Attachment not required.\n");
1139                         new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1140                                 GSM48_MM_SST_NORMAL_SERVICE);
1141
1142                         /* send message to PLMN search process */
1143                         nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
1144                         if (!nmsg)
1145                                 return -ENOMEM;
1146                         gsm322_plmn_sendmsg(ms, nmsg);
1147
1148                         return 0;
1149                 }
1150                 /* else, continue */
1151         }
1152
1153         /* PLMN mode auto and selected cell is forbidden */
1154         if (set->plmn_mode == PLMN_MODE_AUTO
1155          && (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)
1156           || gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc,
1157                 cs->sel_lac))) {
1158                 struct msgb *nmsg;
1159
1160                 LOGP(DMM, LOGL_INFO, "Selected cell is forbidden.\n");
1161                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1162                         GSM48_MM_SST_LIMITED_SERVICE);
1163
1164                 /* send message to PLMN search process */
1165                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
1166                 if (!nmsg)
1167                         return -ENOMEM;
1168                 gsm322_plmn_sendmsg(ms, nmsg);
1169
1170                 return 0;
1171         }
1172
1173         /* PLMN mode manual and selected cell not selected PLMN */
1174         if (set->plmn_mode == PLMN_MODE_MANUAL
1175          && (plmn->mcc != cs->sel_mcc
1176           || plmn->mnc != cs->sel_mnc)) {
1177                 struct msgb *nmsg;
1178
1179                 LOGP(DMM, LOGL_INFO, "Selected cell not found.\n");
1180                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1181                         GSM48_MM_SST_LIMITED_SERVICE);
1182
1183                 /* send message to PLMN search process */
1184                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
1185                 if (!nmsg)
1186                         return -ENOMEM;
1187                 gsm322_plmn_sendmsg(ms, nmsg);
1188
1189                 return 0;
1190         }
1191
1192         /* other cases */
1193         new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LOC_UPD_NEEDED);
1194
1195         return 0;
1196 }
1197
1198 /* 4.2.1.2 Service state PLMN SEARCH (NORMAL) is entered */
1199 static int gsm48_mm_plmn_search(struct osmocom_ms *ms, struct msgb *msg)
1200 {
1201         struct gsm48_mmlayer *mm = &ms->mmlayer;
1202
1203         new_mm_state(mm, GSM48_MM_ST_MM_IDLE, gsm48_mm_set_plmn_search(ms));
1204
1205         return 0;
1206 }
1207
1208 /*
1209  * init and exit
1210  */
1211
1212 /* initialize Mobility Management process */
1213 int gsm48_mm_init(struct osmocom_ms *ms)
1214 {
1215         struct gsm48_mmlayer *mm = &ms->mmlayer;
1216
1217         memset(mm, 0, sizeof(*mm));
1218         mm->ms = ms;
1219
1220         LOGP(DMM, LOGL_INFO, "init Mobility Management process\n");
1221
1222         /* 4.2.1.1 */
1223         mm->state = GSM48_MM_ST_MM_IDLE;
1224         mm->substate = gsm48_mm_set_plmn_search(ms);
1225
1226         /* init lists */
1227         INIT_LLIST_HEAD(&mm->mm_conn);
1228         INIT_LLIST_HEAD(&mm->rr_upqueue);
1229         INIT_LLIST_HEAD(&mm->mmxx_upqueue);
1230         INIT_LLIST_HEAD(&mm->mmr_downqueue);
1231         INIT_LLIST_HEAD(&mm->event_queue);
1232
1233         return 0;
1234 }
1235
1236 /* exit MM process */
1237 int gsm48_mm_exit(struct osmocom_ms *ms)
1238 {
1239         struct gsm48_mmlayer *mm = &ms->mmlayer;
1240         struct gsm48_mm_conn *conn;
1241         struct msgb *msg;
1242
1243         LOGP(DMM, LOGL_INFO, "exit Mobility Management process\n");
1244
1245         /* flush lists */
1246         while (!llist_empty(&mm->mm_conn)) {
1247                 conn = llist_entry(mm->mm_conn.next, 
1248                         struct gsm48_mm_conn, list);
1249                 mm_conn_free(conn);
1250         }
1251         while ((msg = msgb_dequeue(&mm->rr_upqueue)))
1252                 msgb_free(msg);
1253         while ((msg = msgb_dequeue(&mm->mmxx_upqueue)))
1254                 msgb_free(msg);
1255         while ((msg = msgb_dequeue(&mm->mmr_downqueue)))
1256                 msgb_free(msg);
1257         while ((msg = msgb_dequeue(&mm->event_queue)))
1258                 msgb_free(msg);
1259                 
1260         /* stop timers */
1261         stop_mm_t3210(mm);
1262         stop_mm_t3211(mm);
1263         stop_mm_t3212(mm);
1264         stop_mm_t3213(mm);
1265         stop_mm_t3220(mm);
1266         stop_mm_t3230(mm);
1267         stop_mm_t3240(mm);
1268
1269         return 0;
1270 }
1271
1272 /*
1273  * MM connection management
1274  */
1275
1276 static const char *gsm48_mmxx_state_names[] = {
1277         "IDLE",
1278         "CONN_PEND",
1279         "DEDICATED",
1280         "CONN_SUSP",
1281         "REESTPEND"
1282 };
1283
1284 uint32_t mm_conn_new_ref = 0x80000001;
1285
1286 /* new MM connection state */
1287 static void new_conn_state(struct gsm48_mm_conn *conn, int state)
1288 {
1289         LOGP(DMM, LOGL_INFO, "(ref %x) new state %s -> %s\n", conn->ref,
1290                 gsm48_mmxx_state_names[conn->state],
1291                 gsm48_mmxx_state_names[state]);
1292         conn->state = state;
1293 }
1294
1295 /* find MM connection by protocol+ID */
1296 struct gsm48_mm_conn *mm_conn_by_id(struct gsm48_mmlayer *mm,
1297                                    uint8_t proto, uint8_t transaction_id)
1298 {
1299         struct gsm48_mm_conn *conn;
1300
1301         llist_for_each_entry(conn, &mm->mm_conn, list) {
1302                 if (conn->protocol == proto &&
1303                     conn->transaction_id == transaction_id)
1304                         return conn;
1305         }
1306         return NULL;
1307 }
1308
1309 /* find MM connection by reference */
1310 struct gsm48_mm_conn *mm_conn_by_ref(struct gsm48_mmlayer *mm,
1311                                         uint32_t ref)
1312 {
1313         struct gsm48_mm_conn *conn;
1314
1315         llist_for_each_entry(conn, &mm->mm_conn, list) {
1316                 if (conn->ref == ref)
1317                         return conn;
1318         }
1319         return NULL;
1320 }
1321
1322 /* create MM connection instance */
1323 static struct gsm48_mm_conn* mm_conn_new(struct gsm48_mmlayer *mm,
1324         int proto, uint8_t transaction_id, uint32_t ref)
1325 {
1326         struct gsm48_mm_conn *conn = talloc_zero(l23_ctx, struct gsm48_mm_conn);
1327
1328         if (!conn)
1329                 return NULL;
1330
1331         LOGP(DMM, LOGL_INFO, "New MM Connection (proto 0x%02x trans_id %d "
1332                 "ref %d)\n", proto, transaction_id, ref);
1333
1334         conn->mm = mm;
1335         conn->state = GSM48_MMXX_ST_IDLE;
1336         conn->transaction_id = transaction_id;
1337         conn->protocol = proto;
1338         conn->ref = ref;
1339
1340         llist_add(&conn->list, &mm->mm_conn);
1341
1342         return conn;
1343 }
1344
1345 /* destroy MM connection instance */
1346 void mm_conn_free(struct gsm48_mm_conn *conn)
1347 {
1348         LOGP(DMM, LOGL_INFO, "Freeing MM Connection\n");
1349
1350         new_conn_state(conn, GSM48_MMXX_ST_IDLE);
1351
1352         llist_del(&conn->list);
1353
1354         talloc_free(conn);
1355 }
1356
1357 /* support function to release pending/all ongoing MM connections */
1358 static int gsm48_mm_release_mm_conn(struct osmocom_ms *ms, int abort_any,
1359                                     uint8_t cause, int error)
1360 {
1361         struct gsm48_mmlayer *mm = &ms->mmlayer;
1362         struct gsm48_mm_conn *conn, *conn2;
1363         struct msgb *nmsg;
1364         struct gsm48_mmxx_hdr *nmmh;
1365
1366         if (abort_any)
1367                 LOGP(DMM, LOGL_INFO, "Release any MM Connection\n");
1368         else
1369                 LOGP(DMM, LOGL_INFO, "Release pending MM Connections\n");
1370
1371         /* release MM connection(s) */
1372         llist_for_each_entry_safe(conn, conn2, &mm->mm_conn, list) {
1373                 /* abort any OR the pending connection */
1374                 if (abort_any || conn->state == GSM48_MMXX_ST_CONN_PEND) {
1375                         /* send MMxx-REL-IND */
1376                         nmsg = NULL;
1377                         switch(conn->protocol) {
1378                         case GSM48_PDISC_CC:
1379                                 nmsg = gsm48_mmxx_msgb_alloc(
1380                                         error ? GSM48_MMCC_ERR_IND
1381                                         : GSM48_MMCC_REL_IND, conn->ref,
1382                                                 conn->transaction_id);
1383                                 break;
1384                         case GSM48_PDISC_NC_SS:
1385                                 nmsg = gsm48_mmxx_msgb_alloc(
1386                                         error ? GSM48_MMSS_ERR_IND
1387                                         : GSM48_MMSS_REL_IND, conn->ref,
1388                                                 conn->transaction_id);
1389                                 break;
1390                         case GSM48_PDISC_SMS:
1391                                 nmsg = gsm48_mmxx_msgb_alloc(
1392                                         error ? GSM48_MMSMS_ERR_IND
1393                                         : GSM48_MMSMS_REL_IND, conn->ref,
1394                                                 conn->transaction_id);
1395                                 break;
1396                         }
1397                         if (!nmsg) {
1398                                 /* this should not happen */
1399                                 mm_conn_free(conn);
1400                                 continue; /* skip if not of CC type */
1401                         }
1402                         nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
1403                         nmmh->cause = cause;
1404                         gsm48_mmxx_upmsg(ms, nmsg);
1405
1406                         mm_conn_free(conn);
1407                 }
1408         }
1409         return 0;
1410 }
1411
1412 /*
1413  * process handlers (Common procedures)
1414  */
1415
1416 /* sending MM STATUS message */
1417 static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, uint8_t cause)
1418 {
1419         struct msgb *nmsg;
1420         struct gsm48_hdr *ngh;
1421         uint8_t *reject_cause;
1422
1423         LOGP(DMM, LOGL_INFO, "MM STATUS (cause #%d)\n", cause);
1424
1425         nmsg = gsm48_l3_msgb_alloc();
1426         if (!nmsg)
1427                 return -ENOMEM;
1428         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1429         reject_cause = msgb_put(nmsg, 1);
1430
1431         ngh->proto_discr = GSM48_PDISC_MM;
1432         ngh->msg_type = GSM48_MT_MM_STATUS;
1433         *reject_cause = cause;
1434
1435         /* push RR header and send down */
1436         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1437 }
1438
1439 /* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
1440 static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
1441 {
1442         struct msgb *nmsg;
1443         struct gsm48_hdr *ngh;
1444
1445         LOGP(DMM, LOGL_INFO, "TMSI REALLOCATION COMPLETE\n");
1446
1447         nmsg = gsm48_l3_msgb_alloc();
1448         if (!nmsg)
1449                 return -ENOMEM;
1450         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1451
1452         ngh->proto_discr = GSM48_PDISC_MM;
1453         ngh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
1454
1455         /* push RR header and send down */
1456         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1457 }
1458
1459 /* 4.3.1 TMSI REALLOCATION COMMAND is received */
1460 static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg)
1461 {
1462         struct gsm_subscriber *subscr = &ms->subscr;
1463         struct gsm48_hdr *gh = msgb_l3(msg);
1464         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1465         struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
1466         uint8_t mi_type, *mi;
1467         uint32_t tmsi;
1468
1469         if (payload_len < sizeof(struct gsm48_loc_area_id) + 2) {
1470                 short_read:
1471                 LOGP(DMM, LOGL_NOTICE, "Short read of TMSI REALLOCATION "
1472                         "COMMAND message error.\n");
1473                 return -EINVAL;
1474         }
1475         /* LAI */
1476         gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
1477         /* MI */
1478         mi = gh->data + sizeof(struct gsm48_loc_area_id);
1479         mi_type = mi[1] & GSM_MI_TYPE_MASK;
1480         switch (mi_type) {
1481         case GSM_MI_TYPE_TMSI:
1482                 if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
1483                  || mi[0] < 5)
1484                         goto short_read;
1485                 memcpy(&tmsi, mi+2, 4);
1486                 subscr->tmsi = ntohl(tmsi);
1487                 LOGP(DMM, LOGL_INFO, "TMSI 0x%08x (%u) assigned.\n",
1488                         subscr->tmsi, subscr->tmsi);
1489                 gsm48_mm_tx_tmsi_reall_cpl(ms);
1490                 break;
1491         case GSM_MI_TYPE_IMSI:
1492                 subscr->tmsi = 0x00000000;
1493                 LOGP(DMM, LOGL_INFO, "TMSI removed.\n");
1494                 gsm48_mm_tx_tmsi_reall_cpl(ms);
1495                 break;
1496         default:
1497                 subscr->tmsi = 0x00000000;
1498                 LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown MI "
1499                         "type %d.\n", mi_type);
1500                 gsm48_mm_tx_mm_status(ms, GSM48_REJECT_INCORRECT_MESSAGE);
1501         }
1502
1503         /* store LOCI on sim */
1504         gsm_subscr_write_loci(ms);
1505
1506         return 0;
1507 }
1508
1509 /* 4.3.2.2 AUTHENTICATION REQUEST is received */
1510 static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
1511 {
1512         struct gsm_subscriber *subscr = &ms->subscr;
1513         struct gsm_settings *set = &ms->settings;
1514         struct gsm48_mmlayer *mm = &ms->mmlayer;
1515         struct gsm48_hdr *gh = msgb_l3(msg);
1516         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1517         struct gsm48_auth_req *ar = (struct gsm48_auth_req *) gh->data;
1518         uint8_t no_sim = 0;
1519
1520         if (payload_len < sizeof(struct gsm48_auth_req)) {
1521                 LOGP(DMM, LOGL_NOTICE, "Short read of AUTHENTICATION REQUEST "
1522                         "message error.\n");
1523                 return -EINVAL;
1524         }
1525
1526         /* SIM is not available */
1527         if (!subscr->sim_valid) {
1528                 LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST without SIM\n");
1529                 return gsm48_mm_tx_mm_status(ms,
1530                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
1531         }
1532
1533         LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST (seq %d)\n", ar->key_seq);
1534
1535         /* key_seq and random
1536          * in case of test card, there is a dummy response.
1537          * authentication request is possible during emergency call, if
1538          * IMSI is known to the network. in case of emergency IMSI, we need to
1539          * send a dummy response also.
1540          */
1541         if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0])
1542                 no_sim = 1;
1543         gsm_subscr_generate_kc(ms, ar->key_seq, ar->rand, no_sim);
1544
1545         /* wait for auth response event from SIM */
1546         return 0;
1547 }
1548
1549 /* 4.3.2.2 sending AUTHENTICATION RESPONSE */
1550 static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct msgb *msg)
1551 {
1552         struct gsm48_mm_event *mme = (struct gsm48_mm_event *) msg->data;
1553         struct msgb *nmsg;
1554         struct gsm48_hdr *ngh;
1555         uint8_t *sres;
1556
1557         LOGP(DMM, LOGL_INFO, "AUTHENTICATION RESPONSE\n");
1558
1559         nmsg = gsm48_l3_msgb_alloc();
1560         if (!nmsg)
1561                 return -ENOMEM;
1562         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1563
1564         ngh->proto_discr = GSM48_PDISC_MM;
1565         ngh->msg_type = GSM48_MT_MM_AUTH_RESP;
1566
1567         /* SRES */
1568         sres = msgb_put(nmsg, 4);
1569         memcpy(sres, mme->sres, 4);
1570
1571         /* push RR header and send down */
1572         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1573 }
1574
1575 /* 4.3.2.5 AUTHENTICATION REJECT is received */
1576 static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg)
1577 {
1578         struct gsm_subscriber *subscr = &ms->subscr;
1579         struct gsm48_mmlayer *mm = &ms->mmlayer;
1580
1581         LOGP(DMM, LOGL_INFO, "AUTHENTICATION REJECT\n");
1582
1583         stop_mm_t3212(mm); /* 4.4.2 */
1584
1585         /* SIM invalid */
1586         subscr->sim_valid = 0;
1587
1588         /* TMSI and LAI invalid */
1589         subscr->tmsi = 0xffffffff;
1590         subscr->lac = 0x0000;
1591
1592         /* key is invalid */
1593         subscr->key_seq = 7;
1594
1595         /* update status */
1596         new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
1597
1598         /* store LOCI on sim */
1599         gsm_subscr_write_loci(ms);
1600
1601         /* abort IMSI detach procedure */
1602         if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
1603                 struct msgb *nmsg;
1604                 struct gsm48_rr_hdr *nrrh;
1605
1606                 /* abort RR connection */
1607                 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
1608                 if (!nmsg)
1609                         return -ENOMEM;
1610                 nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
1611                 nrrh->cause = GSM48_RR_CAUSE_NORMAL;
1612                 gsm48_rr_downmsg(ms, nmsg);
1613
1614                 /* CS process will trigger: return to MM IDLE / No SIM */
1615                 return 0;
1616         }
1617
1618         return 0;
1619 }
1620
1621 /* 4.3.3.1 IDENTITY REQUEST is received */
1622 static int gsm48_mm_rx_id_req(struct osmocom_ms *ms, struct msgb *msg)
1623 {
1624         struct gsm_subscriber *subscr = &ms->subscr;
1625         struct gsm48_hdr *gh = msgb_l3(msg);
1626         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1627         uint8_t mi_type;
1628
1629         if (payload_len < 1) {
1630                 LOGP(DMM, LOGL_NOTICE, "Short read of IDENTITY REQUEST message "
1631                         "error.\n");
1632                 return -EINVAL;
1633         }
1634
1635         /* id type */
1636         mi_type = *gh->data;
1637         LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST (mi_type %d)\n", mi_type);
1638
1639         /* check if request can be fulfilled */
1640         if (!subscr->sim_valid && mi_type != GSM_MI_TYPE_IMEI
1641          && mi_type != GSM_MI_TYPE_IMEISV) {
1642                 LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST without SIM\n");
1643                 return gsm48_mm_tx_mm_status(ms,
1644                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
1645         }
1646         if (mi_type == GSM_MI_TYPE_TMSI && subscr->tmsi == 0xffffffff) {
1647                 LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST of TMSI, but we have no "
1648                         "TMSI\n");
1649                 return gsm48_mm_tx_mm_status(ms,
1650                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
1651         }
1652
1653         return gsm48_mm_tx_id_rsp(ms, mi_type);
1654 }
1655
1656 /* send IDENTITY RESPONSE message */
1657 static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type)
1658 {
1659         struct msgb *nmsg;
1660         struct gsm48_hdr *ngh;
1661         uint8_t buf[11];
1662
1663         LOGP(DMM, LOGL_INFO, "IDENTITY RESPONSE\n");
1664
1665         nmsg = gsm48_l3_msgb_alloc();
1666         if (!nmsg)
1667                 return -ENOMEM;
1668         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1669
1670         ngh->proto_discr = GSM48_PDISC_MM;
1671         ngh->msg_type = GSM48_MT_MM_ID_RESP;
1672
1673         /* MI */
1674         gsm48_encode_mi(buf, nmsg, ms, mi_type);
1675
1676         /* push RR header and send down */
1677         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1678 }
1679
1680 /* 4.3.4.1 sending IMSI DETACH INDICATION message */
1681 static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
1682 {
1683         struct gsm_subscriber *subscr = &ms->subscr;
1684         struct gsm48_mmlayer *mm = &ms->mmlayer;
1685         struct gsm_support *sup = &ms->support;
1686         struct gsm48_rrlayer *rr = &ms->rrlayer;
1687         struct msgb *nmsg;
1688         struct gsm48_hdr *ngh;
1689         uint8_t pwr_lev;
1690         uint8_t buf[11];
1691         struct gsm48_classmark1 cm;
1692
1693
1694         LOGP(DMM, LOGL_INFO, "IMSI DETACH INDICATION\n");
1695
1696         nmsg = gsm48_l3_msgb_alloc();
1697         if (!nmsg)
1698                 return -ENOMEM;
1699         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1700
1701         ngh->proto_discr = GSM48_PDISC_MM;
1702         ngh->msg_type = GSM48_MT_MM_IMSI_DETACH_IND;
1703
1704         /* classmark 1 */
1705         if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
1706                 pwr_lev = sup->pwr_lev_1800;
1707         else
1708                 pwr_lev = sup->pwr_lev_900;
1709         gsm48_encode_classmark1(&cm, sup->rev_lev, sup->es_ind, sup->a5_1,
1710                 pwr_lev);
1711         msgb_v_put(nmsg, *((uint8_t *)&cm));
1712         /* MI */
1713         if (subscr->tmsi != 0xffffffff) /* have TMSI ? */
1714                 gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_TMSI);
1715         else
1716                 gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_IMSI);
1717
1718         /* push RR header and send down */
1719         mm->est_cause = RR_EST_CAUSE_OTHER_SDCCH;
1720         return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
1721 }
1722
1723 /* detach has ended */
1724 static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
1725 {
1726         struct gsm48_mmlayer *mm = &ms->mmlayer;
1727         struct gsm_subscriber *subscr = &ms->subscr;
1728         struct msgb *nmsg;
1729
1730         LOGP(DMM, LOGL_INFO, "IMSI has been detached.\n");
1731
1732         /* stop IMSI detach timer (if running) */
1733         stop_mm_t3220(mm);
1734
1735
1736         /* SIM invalid */
1737         subscr->sim_valid = 0;
1738
1739         /* wait for RR idle and then power off when IMSI is detached */
1740         if (mm->power_off) {
1741                 if (mm->state == GSM48_MM_ST_MM_IDLE) {
1742                         l23_app_exit(ms);
1743                         exit(0);
1744                 }
1745                 mm->power_off_idle = 1;
1746
1747                 return 0;
1748         }
1749
1750         /* send SIM remove event to gsm322 */
1751         nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
1752         if (!nmsg)
1753                 return -ENOMEM;
1754         gsm322_plmn_sendmsg(ms, nmsg);
1755
1756         /* CS process will trigger return to MM IDLE / No SIM */
1757         return 0;
1758 }
1759
1760 /* start an IMSI detach in MM IDLE */
1761 static int gsm48_mm_imsi_detach_start(struct osmocom_ms *ms, struct msgb *msg)
1762 {
1763         struct gsm_subscriber *subscr = &ms->subscr;
1764         struct gsm48_mmlayer *mm = &ms->mmlayer;
1765         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1766
1767         /* we may silently finish IMSI detach */
1768         if (!s->att_allowed || !subscr->imsi_attached) {
1769                 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1770
1771                 return gsm48_mm_imsi_detach_end(ms, msg);
1772         }
1773         LOGP(DMM, LOGL_INFO, "IMSI detach started (MM IDLE)\n");
1774
1775         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
1776
1777         /* establish RR and send IMSI detach */
1778         return gsm48_mm_tx_imsi_detach(ms, GSM48_RR_EST_REQ);
1779 }
1780
1781 /* IMSI detach has been sent, wait for RR release */
1782 static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, struct msgb *msg)
1783 {
1784         struct gsm48_mmlayer *mm = &ms->mmlayer;
1785
1786         /* start T3220 (4.3.4.1) */
1787         start_mm_t3220(mm);
1788
1789         LOGP(DMM, LOGL_INFO, "IMSI detach started (Wait for RR release)\n");
1790
1791         new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
1792
1793         return 0;
1794 }
1795         
1796 /* release MM connection and proceed with IMSI detach */
1797 static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
1798 {
1799         struct gsm_subscriber *subscr = &ms->subscr;
1800         struct gsm48_mmlayer *mm = &ms->mmlayer;
1801         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1802
1803         /* stop MM connection timer */
1804         stop_mm_t3230(mm);
1805
1806         /* release all connections */
1807         gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1808
1809         /* wait for release of RR */
1810         if (!s->att_allowed || !subscr->imsi_attached) {
1811                 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1812                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
1813
1814                 /* power off */
1815                 if (mm->power_off) {
1816                         l23_app_exit(ms);
1817                         exit(0);
1818                 }
1819
1820                 return 0;
1821         }
1822
1823         /* send IMSI detach */
1824         gsm48_mm_tx_imsi_detach(ms, GSM48_RR_DATA_REQ);
1825
1826         /* go to sent state */
1827         return gsm48_mm_imsi_detach_sent(ms, msg);
1828 }
1829
1830 /* ignore ongoing IMSI detach */
1831 static int gsm48_mm_imsi_detach_ignore(struct osmocom_ms *ms, struct msgb *msg)
1832 {
1833         return 0;
1834 }
1835
1836 /* delay until state change (and then retry) */
1837 static int gsm48_mm_imsi_detach_delay(struct osmocom_ms *ms, struct msgb *msg)
1838 {
1839         struct gsm48_mmlayer *mm = &ms->mmlayer;
1840
1841         LOGP(DMM, LOGL_INFO, "IMSI detach delayed.\n");
1842
1843         /* remember to detach later */
1844         mm->delay_detach = 1;
1845
1846         return 0;
1847 }
1848
1849 /* 4.3.5.2 ABORT is received */
1850 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
1851 {
1852         struct gsm48_mmlayer *mm = &ms->mmlayer;
1853         struct gsm_subscriber *subscr = &ms->subscr;
1854         struct gsm48_hdr *gh = msgb_l3(msg);
1855         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1856         uint8_t reject_cause;
1857
1858         if (payload_len < 1) {
1859                 LOGP(DMM, LOGL_NOTICE, "Short read of ABORT message error.\n");
1860                 return -EINVAL;
1861         }
1862
1863         reject_cause = *gh->data;
1864
1865         if (llist_empty(&mm->mm_conn)) {
1866                 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while no MM "
1867                         "connection is established.\n", reject_cause);
1868                 return gsm48_mm_tx_mm_status(ms,
1869                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
1870         } else {
1871                 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while MM connection "
1872                         "is established.\n", reject_cause);
1873                 /* stop MM connection timer */
1874                 stop_mm_t3230(mm);
1875
1876                 gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1877         }
1878
1879         if (reject_cause == GSM48_REJECT_ILLEGAL_ME) { 
1880                 /* SIM invalid */
1881                 subscr->sim_valid = 0;
1882
1883                 /* TMSI and LAI invalid */
1884                 subscr->tmsi = 0xffffffff;
1885                 subscr->lac = 0x0000;
1886
1887                 /* key is invalid */
1888                 subscr->key_seq = 7;
1889
1890                 /* update status */
1891                 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
1892
1893                 /* store LOCI on sim */
1894                 gsm_subscr_write_loci(ms);
1895
1896                 /* CS process will trigger: return to MM IDLE / No SIM */
1897                 return 0;
1898         }
1899
1900         return 0;
1901 }
1902
1903 /* 4.3.6.2 MM INFORMATION is received */
1904 static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
1905 {
1906         struct gsm48_mmlayer *mm = &ms->mmlayer;
1907         struct gsm48_hdr *gh = msgb_l3(msg);
1908         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1909         struct tlv_parsed tp;
1910
1911         if (payload_len < 0) {
1912                 LOGP(DMM, LOGL_NOTICE, "Short read of MM INFORMATION message "
1913                         "error.\n");
1914                 return -EINVAL;
1915         }
1916         tlv_parse(&tp, &gsm48_mm_att_tlvdef, gh->data, payload_len, 0, 0);
1917
1918         /* long name */
1919         if (TLVP_PRESENT(&tp, GSM48_IE_NAME_LONG)) {
1920                 decode_network_name(mm->name_long, sizeof(mm->name_long),
1921                                 TLVP_VAL(&tp, GSM48_IE_NAME_LONG)-1);
1922         }
1923         /* short name */
1924         if (TLVP_PRESENT(&tp, GSM48_IE_NAME_SHORT)) {
1925                 decode_network_name(mm->name_short, sizeof(mm->name_short),
1926                                 TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)-1);
1927         }
1928
1929         return 0;
1930 }
1931
1932 /*
1933  * process handlers for Location Update + IMSI attach (MM specific procedures)
1934  */
1935
1936 /* 4.4.2 received sysinfo change event */
1937 static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
1938 {
1939         struct gsm48_mmlayer *mm = &ms->mmlayer;
1940         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1941
1942         /* t3212 not changed in these states */ 
1943         if (mm->state == GSM48_MM_ST_MM_IDLE
1944          && (mm->substate == GSM48_MM_SST_NO_CELL_AVAIL
1945           || mm->substate == GSM48_MM_SST_LIMITED_SERVICE
1946           || mm->substate == GSM48_MM_SST_PLMN_SEARCH
1947           || mm->substate == GSM48_MM_SST_PLMN_SEARCH_NORMAL))
1948                 return 0;
1949
1950         /* new periodic location update timer timeout */
1951         if (s->t3212 && s->t3212 != mm->t3212_value) {
1952                 if (bsc_timer_pending(&mm->t3212)) {
1953                         int t;
1954                         struct timeval current_time;
1955
1956                         /* get rest time */
1957                         gettimeofday(&current_time, NULL);
1958                         t = mm->t3212.timeout.tv_sec - current_time.tv_sec;
1959                         if (t < 0)
1960                                 t = 0;
1961                         LOGP(DMM, LOGL_INFO, "New T3212 while timer is running "
1962                                 "(value %d rest %d)\n", s->t3212, t);
1963
1964                         /* rest time modulo given value */
1965                         mm->t3212.timeout.tv_sec = current_time.tv_sec
1966                                 + (t % s->t3212);
1967                 } else {
1968                         uint32_t rand = random();
1969
1970                         LOGP(DMM, LOGL_INFO, "New T3212 while timer is not "
1971                                 "running (value %d)\n", s->t3212);
1972
1973                         /* value between 0 and given value */
1974                         start_mm_t3212(mm, rand % (s->t3212 + 1));
1975                 }
1976                 mm->t3212_value = s->t3212;
1977         }
1978         
1979         return 0;
1980 }
1981
1982 /* 4.4.4.1 (re)start location update
1983  *
1984  * this function is called by
1985  * - normal location update
1986  * - periodic location update
1987  * - imsi attach (normal loc. upd. function)
1988  * - retry timers (T3211 and T3213)
1989  */
1990 static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
1991 {
1992         struct gsm48_mmlayer *mm = &ms->mmlayer;
1993         struct gsm322_cellsel *cs = &ms->cellsel;
1994         struct gsm48_sysinfo *s = &cs->sel_si;
1995         struct gsm_subscriber *subscr = &ms->subscr;
1996         struct gsm_settings *set = &ms->settings;
1997         struct msgb *nmsg;
1998         int msg_type;
1999         
2000         /* (re)start only if we still require location update */
2001         if (!mm->lupd_pending) {
2002                 LOGP(DMM, LOGL_INFO, "No loc. upd. pending.\n");
2003                 return 0;
2004         }
2005
2006         /* must camp normally */
2007         if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2008                 LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
2009                 msg_type = GSM322_EVENT_REG_FAILED;
2010                 stop:
2011                 LOGP(DSUM, LOGL_INFO, "Location updating not possible\n");
2012                 _stop:
2013                 mm->lupd_pending = 0;
2014                 /* send message to PLMN search process */
2015                 nmsg = gsm322_msgb_alloc(msg_type);
2016                 if (!nmsg)
2017                         return -ENOMEM;
2018                 gsm322_plmn_sendmsg(ms, nmsg);
2019                 return 0;
2020         }
2021
2022         /* deny network, if disabled */
2023         if (set->no_lupd) {
2024                 LOGP(DMM, LOGL_INFO, "Loc. upd. disabled, adding "
2025                         "forbidden PLMN.\n");
2026                 LOGP(DSUM, LOGL_INFO, "Location updating is disabled by "
2027                         "configuration\n");
2028                 gsm_subscr_add_forbidden_plmn(subscr, cs->sel_mcc,
2029                         cs->sel_mnc, GSM48_REJECT_PLMN_NOT_ALLOWED);
2030                 msg_type = GSM322_EVENT_ROAMING_NA;
2031                 goto _stop;
2032         }
2033
2034         /* if LAI is forbidden, don't start */
2035         if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
2036                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
2037                 msg_type = GSM322_EVENT_ROAMING_NA;
2038                 goto stop;
2039         }
2040         if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
2041                 cs->sel_mnc, cs->sel_lac)) {
2042                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
2043                 msg_type = GSM322_EVENT_ROAMING_NA;
2044                 goto stop;
2045         }
2046
2047         /* 4.4.4.9 if cell is barred, don't start */
2048         if ((!subscr->acc_barr && s->cell_barr)
2049          || (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
2050                                         (s->class_barr ^ 0xffff)))) {
2051                 LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
2052                 msg_type = GSM322_EVENT_ROAMING_NA;
2053                 goto stop;
2054         }
2055
2056         mm->lupd_mcc = cs->sel_mcc;
2057         mm->lupd_mnc = cs->sel_mnc;
2058         mm->lupd_lac = cs->sel_lac;
2059
2060         LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %s, MNC %s "
2061                 "LAC 0x%04x)\n", gsm_print_mcc(mm->lupd_mcc),
2062                 gsm_print_mnc(mm->lupd_mnc), mm->lupd_lac);
2063
2064         return gsm48_mm_tx_loc_upd_req(ms);
2065 }
2066
2067 /* initiate a normal location update / imsi attach */
2068 static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg)
2069 {
2070         struct gsm48_mmlayer *mm = &ms->mmlayer;
2071         struct gsm_subscriber *subscr = &ms->subscr;
2072         struct gsm322_cellsel *cs = &ms->cellsel;
2073         struct gsm48_sysinfo *s = &cs->sel_si;
2074         struct msgb *nmsg;
2075
2076         /* in case we already have a location update going on */
2077         if (mm->lupd_pending) {
2078                 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2079
2080                 return -EBUSY;
2081         }
2082
2083         /* no location update, if limited service */
2084         if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2085                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed.\n");
2086
2087                 /* send message to PLMN search process */
2088                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2089                 if (!nmsg)
2090                         return -ENOMEM;
2091                 gsm322_plmn_sendmsg(ms, nmsg);
2092
2093                 return 0;
2094         }
2095
2096         /* if location update is not required */
2097         if (subscr->ustate == GSM_SIM_U1_UPDATED
2098          && cs->selected
2099          && cs->sel_mcc == subscr->mcc
2100          && cs->sel_mnc == subscr->mnc
2101          && cs->sel_lac == subscr->lac
2102          && (subscr->imsi_attached
2103           || !s->att_allowed)) {
2104                 LOGP(DMM, LOGL_INFO, "Loc. upd. not required.\n");
2105                 subscr->imsi_attached = 1;
2106
2107                 /* send message to PLMN search process */
2108                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2109                 if (!nmsg)
2110                         return -ENOMEM;
2111                 gsm322_plmn_sendmsg(ms, nmsg);
2112
2113                 return 0;
2114         }
2115
2116         /* 4.4.3 is attachment required? */
2117         if (subscr->ustate == GSM_SIM_U1_UPDATED
2118          && cs->selected
2119          && cs->sel_mcc == subscr->mcc
2120          && cs->sel_mnc == subscr->mnc
2121          && cs->sel_lac == subscr->lac
2122          && !subscr->imsi_attached
2123          && s->att_allowed) {
2124                 /* do location update for IMSI attach */
2125                 LOGP(DMM, LOGL_INFO, "Do Loc. upd. for IMSI attach.\n");
2126                 mm->lupd_type = 2;
2127         } else {
2128                 /* do normal location update */
2129                 LOGP(DMM, LOGL_INFO, "Do normal Loc. upd.\n");
2130                 mm->lupd_type = 0;
2131         }
2132
2133         /* start location update */
2134         mm->lupd_attempt = 0;
2135         mm->lupd_pending = 1;
2136         mm->lupd_ra_failure = 0;
2137
2138         return gsm48_mm_loc_upd(ms, msg);
2139 }
2140
2141 /* initiate a periodic location update */
2142 static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg)
2143 {
2144         struct gsm48_mmlayer *mm = &ms->mmlayer;
2145
2146         /* in case we already have a location update going on */
2147         if (mm->lupd_pending) {
2148                 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2149                 return -EBUSY;
2150         }
2151
2152         /* start periodic location update */
2153         mm->lupd_type = 1;
2154         mm->lupd_pending = 1;
2155         mm->lupd_ra_failure = 0;
2156
2157         return gsm48_mm_loc_upd(ms, msg);
2158 }
2159
2160 /* ignore location update */
2161 static int gsm48_mm_loc_upd_ignore(struct osmocom_ms *ms, struct msgb *msg)
2162 {
2163         return 0;
2164 }
2165
2166 /* 9.2.15 send LOCATION UPDATING REQUEST message */
2167 static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
2168 {
2169         struct gsm48_mmlayer *mm = &ms->mmlayer;
2170         struct gsm_support *sup = &ms->support;
2171         struct gsm_subscriber *subscr = &ms->subscr;
2172         struct gsm48_rrlayer *rr = &ms->rrlayer;
2173         struct msgb *nmsg;
2174         struct gsm48_hdr *ngh;
2175         struct gsm48_loc_upd_req *nlu; /* NOTE: mi_len is part of struct */
2176         uint8_t pwr_lev;
2177         uint8_t buf[11];
2178
2179         LOGP(DMM, LOGL_INFO, "LOCATION UPDATING REQUEST\n");
2180
2181         nmsg = gsm48_l3_msgb_alloc();
2182         if (!nmsg)
2183                 return -ENOMEM;
2184         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2185         nlu = (struct gsm48_loc_upd_req *)msgb_put(nmsg, sizeof(*nlu));
2186
2187         ngh->proto_discr = GSM48_PDISC_MM;
2188         ngh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
2189
2190         /* location updating type */
2191         nlu->type = mm->lupd_type;
2192         /* cipering key */
2193         nlu->key_seq = subscr->key_seq;
2194         /* LAI (last SIM stored LAI)
2195          *
2196          * NOTE: The TMSI is only valid within a LAI!
2197          */
2198         gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
2199         /* classmark 1 */
2200         if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
2201                 pwr_lev = sup->pwr_lev_1800;
2202         else
2203                 pwr_lev = sup->pwr_lev_900;
2204         gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind,
2205                 sup->a5_1, pwr_lev);
2206         /* MI */
2207         if (subscr->tmsi != 0xffffffff) /* have TMSI ? */
2208                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2209         else
2210                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2211         msgb_put(nmsg, buf[1]); /* length is part of nlu */
2212         memcpy(&nlu->mi_len, buf + 1, 1 + buf[1]);
2213
2214         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
2215
2216         /* push RR header and send down */
2217         mm->est_cause = RR_EST_CAUSE_LOC_UPD;
2218         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, mm->est_cause);
2219 }
2220
2221 /* 4.4.4.1 RR is esablised during location update */
2222 static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
2223 {
2224         struct gsm48_mmlayer *mm = &ms->mmlayer;
2225
2226         /* start location update timer */
2227         start_mm_t3210(mm);
2228
2229         new_mm_state(mm, GSM48_MM_ST_LOC_UPD_INIT, 0);
2230
2231         return 0;
2232 }
2233
2234 /* 4.4.4.6 LOCATION UPDATING ACCEPT is received */
2235 static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
2236 {
2237         struct gsm48_mmlayer *mm = &ms->mmlayer;
2238         struct gsm_subscriber *subscr = &ms->subscr;
2239         struct gsm48_hdr *gh = msgb_l3(msg);
2240         struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
2241         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2242         struct tlv_parsed tp;
2243         struct msgb *nmsg;
2244
2245         if (payload_len < sizeof(struct gsm48_loc_area_id)) {
2246                 short_read:
2247                 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING ACCEPT "
2248                         "message error.\n");
2249                 return -EINVAL;
2250         }
2251         tlv_parse(&tp, &gsm48_mm_att_tlvdef,
2252                 gh->data + sizeof(struct gsm48_loc_area_id),
2253                 payload_len - sizeof(struct gsm48_loc_area_id), 0, 0);
2254
2255         /* update has finished */
2256         mm->lupd_pending = 0;
2257
2258         /* RA was successfull */
2259         mm->lupd_ra_failure = 0;
2260
2261         /* stop periodic location updating timer */
2262         stop_mm_t3212(mm); /* 4.4.2 */
2263
2264         /* LAI */
2265         gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
2266
2267         /* stop location update timer */
2268         stop_mm_t3210(mm);
2269
2270         /* reset attempt counter */
2271         mm->lupd_attempt = 0;
2272
2273         /* mark SIM as attached */
2274         subscr->imsi_attached = 1;
2275
2276         /* set the status in the sim to updated */
2277         new_sim_ustate(subscr, GSM_SIM_U1_UPDATED);
2278
2279         /* store LOCI on sim */
2280         gsm_subscr_write_loci(ms);
2281
2282         /* set last registered PLMN */
2283         if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
2284                 subscr->plmn_valid = 1;
2285                 subscr->plmn_mcc = subscr->mcc;
2286                 subscr->plmn_mnc = subscr->mnc;
2287         }
2288
2289         LOGP(DSUM, LOGL_INFO, "Location update accepted\n");
2290         LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %s mnc %s "
2291                 "lac 0x%04x)\n", gsm_print_mcc(subscr->mcc),
2292                 gsm_print_mnc(subscr->mnc), subscr->lac);
2293
2294         /* remove LA from forbidden list */
2295         gsm322_del_forbidden_la(ms, subscr->mcc, subscr->mnc, subscr->lac);
2296
2297         /* MI */
2298         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
2299                 const uint8_t *mi;
2300                 uint8_t mi_type;
2301                 uint32_t tmsi;
2302
2303                 mi = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)-1;
2304                 if (mi[0] < 1)
2305                         goto short_read;
2306                 mi_type = mi[1] & GSM_MI_TYPE_MASK;
2307                 switch (mi_type) {
2308                 case GSM_MI_TYPE_TMSI:
2309                         if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
2310                          || mi[0] < 5)
2311                                 goto short_read;
2312                         memcpy(&tmsi, mi+2, 4);
2313                         subscr->tmsi = ntohl(tmsi);
2314                         LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x (%u)\n",
2315                                 subscr->tmsi, subscr->tmsi);
2316
2317                         /* store LOCI on sim */
2318                         gsm_subscr_write_loci(ms);
2319
2320                         break;
2321                 case GSM_MI_TYPE_IMSI:
2322                         LOGP(DMM, LOGL_INFO, "TMSI removed\n");
2323                         subscr->tmsi = 0xffffffff;
2324
2325                         /* store LOCI on sim */
2326                         gsm_subscr_write_loci(ms);
2327
2328                         /* send TMSI REALLOCATION COMPLETE */
2329                         gsm48_mm_tx_tmsi_reall_cpl(ms);
2330                         break;
2331                 default:
2332                         LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown "
2333                                 "MI type %d.\n", mi_type);
2334                 }
2335         }
2336
2337         /* send message to PLMN search process */
2338         nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2339         if (!nmsg)
2340                 return -ENOMEM;
2341         gsm322_plmn_sendmsg(ms, nmsg);
2342
2343         /* follow on proceed */
2344         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID))
2345                 LOGP(DMM, LOGL_NOTICE, "follow-on proceed not supported.\n");
2346
2347         /* start RR release timer */
2348         start_mm_t3240(mm);
2349
2350         new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2351
2352         return 0;
2353 }
2354
2355 /* 4.4.4.7 LOCATION UPDATING REJECT is received */
2356 static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2357 {
2358         struct gsm48_mmlayer *mm = &ms->mmlayer;
2359         struct gsm48_hdr *gh = msgb_l3(msg);
2360         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2361
2362         if (payload_len < 1) {
2363                 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING REJECT "
2364                         "message error.\n");
2365                 return -EINVAL;
2366         }
2367
2368         /* RA was successfull */
2369         mm->lupd_ra_failure = 0;
2370
2371         /* stop periodic location updating timer */
2372         stop_mm_t3212(mm); /* 4.4.2 */
2373
2374         /* stop location update timer */
2375         stop_mm_t3210(mm);
2376
2377         /* store until RR is released */
2378         mm->lupd_rej_cause = *gh->data;
2379
2380         /* start RR release timer */
2381         start_mm_t3240(mm);
2382
2383         new_mm_state(mm, GSM48_MM_ST_LOC_UPD_REJ, 0);
2384         
2385         return 0;
2386 }
2387
2388 /* 4.4.4.7 RR is released after location update reject */
2389 static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2390 {
2391         struct gsm48_mmlayer *mm = &ms->mmlayer;
2392         struct gsm_subscriber *subscr = &ms->subscr;
2393         struct msgb *nmsg;
2394         struct gsm322_msg *ngm;
2395         
2396         LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n",
2397                 mm->lupd_rej_cause);
2398
2399         /* stop RR release timer */
2400         stop_mm_t3240(mm);
2401
2402         /* new status */
2403         switch (mm->lupd_rej_cause) {
2404         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2405         case GSM48_REJECT_ILLEGAL_MS:
2406         case GSM48_REJECT_ILLEGAL_ME:
2407                 /* reset attempt counter */
2408                 mm->lupd_attempt = 0;
2409
2410                 /* SIM invalid */
2411                 subscr->sim_valid = 0;
2412
2413                 // fall through
2414         case GSM48_REJECT_PLMN_NOT_ALLOWED:
2415         case GSM48_REJECT_LOC_NOT_ALLOWED:
2416         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2417                 /* TMSI and LAI invalid */
2418                 subscr->tmsi = 0xffffffff;
2419                 subscr->lac = 0x0000;
2420
2421                 /* key is invalid */
2422                 subscr->key_seq = 7;
2423
2424                 /* update status */
2425                 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
2426
2427                 /* store LOCI on sim */
2428                 gsm_subscr_write_loci(ms);
2429
2430                 /* update has finished */
2431                 mm->lupd_pending = 0;
2432         }
2433
2434         /* send event to PLMN search process */
2435         switch(mm->lupd_rej_cause) {
2436         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2437                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
2438                 break;
2439         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2440         case GSM48_REJECT_ILLEGAL_MS:
2441         case GSM48_REJECT_ILLEGAL_ME:
2442                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM);
2443                 break;
2444         default:
2445                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2446         }
2447         if (!nmsg)
2448                 return -ENOMEM;
2449         ngm = (struct gsm322_msg *)nmsg->data;
2450         ngm->reject = mm->lupd_rej_cause;
2451         gsm322_plmn_sendmsg(ms, nmsg);
2452
2453         /* forbidden list */
2454         switch (mm->lupd_rej_cause) {
2455         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2456                 LOGP(DSUM, LOGL_INFO, "Location update failed (IMSI unknown "
2457                         "in HLR)\n");
2458                 break;
2459         case GSM48_REJECT_ILLEGAL_MS:
2460                 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal MS)\n");
2461                 break;
2462         case GSM48_REJECT_ILLEGAL_ME:
2463                 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n");
2464                 break;
2465         case GSM48_REJECT_PLMN_NOT_ALLOWED:
2466                 gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc,
2467                         mm->lupd_mnc, mm->lupd_rej_cause);
2468                 LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not "
2469                         "allowed)\n");
2470                 break;
2471         case GSM48_REJECT_LOC_NOT_ALLOWED:
2472         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2473                 gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc,
2474                         mm->lupd_lac, mm->lupd_rej_cause);
2475                 LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not "
2476                         "allowed)\n");
2477                 break;
2478         default:
2479                 /* 4.4.4.9 continue with failure handling */
2480                 return gsm48_mm_loc_upd_failed(ms, NULL);
2481         }
2482
2483         /* CS proc triggers: return to IDLE, case 13 is also handled there */
2484         return 0;
2485 }
2486
2487 /* 4.2.2 delay a location update */
2488 static int gsm48_mm_loc_upd_delay_per(struct osmocom_ms *ms, struct msgb *msg)
2489 {
2490         struct gsm48_mmlayer *mm = &ms->mmlayer;
2491
2492         LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2493         mm->lupd_periodic = 1;
2494
2495         return 0;
2496 }
2497
2498 /* delay a location update retry */
2499 static int gsm48_mm_loc_upd_delay_retry(struct osmocom_ms *ms, struct msgb *msg)
2500 {
2501         struct gsm48_mmlayer *mm = &ms->mmlayer;
2502
2503         LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2504         mm->lupd_retry = 1;
2505
2506         return 0;
2507 }
2508
2509 /* process failues as described in the lower part of 4.4.4.9 */
2510 static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
2511 {
2512         struct gsm48_mmlayer *mm = &ms->mmlayer;
2513         struct gsm_subscriber *subscr = &ms->subscr;
2514
2515         LOGP(DSUM, LOGL_INFO, "Location update failed\n");
2516
2517         /* stop location update timer, if running */
2518         stop_mm_t3210(mm);
2519
2520         if (subscr->ustate == GSM_SIM_U1_UPDATED
2521          && mm->lupd_mcc == subscr->mcc
2522          && mm->lupd_mnc == subscr->mnc
2523          && mm->lupd_lac == subscr->lac) {
2524                 if (mm->lupd_attempt < 4) {
2525                         LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2526                         LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
2527                                 mm->lupd_attempt);
2528
2529                         /* start update retry timer */
2530                         start_mm_t3211(mm);
2531
2532                         /* CS process will trigger: return to MM IDLE */
2533                         return 0;
2534                 } else
2535                         LOGP(DMM, LOGL_INFO, "Loc. upd. failed too often.\n");
2536         }
2537
2538         /* TMSI and LAI invalid */
2539         subscr->tmsi = 0xffffffff;
2540         subscr->lac = 0x0000;
2541
2542         /* key is invalid */
2543         subscr->key_seq = 7;
2544
2545         /* update status */
2546         new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2547
2548         /* store LOCI on sim */
2549         gsm_subscr_write_loci(ms);
2550
2551         /* start update retry timer (RR connection is released) */
2552         if (mm->lupd_attempt < 4) {
2553                 mm->start_t3211 = 1;
2554                 LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2555         }
2556
2557         /* CS process will trigger: return to MM IDLE */
2558         return 0;
2559 }
2560
2561 /* abort a location update due to radio failure or release */
2562 static int gsm48_mm_rel_loc_upd_abort(struct osmocom_ms *ms, struct msgb *msg)
2563 {
2564         struct gsm48_mmlayer *mm = &ms->mmlayer;
2565         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
2566
2567         /* stop RR release timer */
2568         stop_mm_t3240(mm);
2569
2570         if (rrh->msg_type == GSM48_RR_REL_IND) {
2571                 LOGP(DMM, LOGL_INFO, "RR link released after loc. upd.\n");
2572
2573                 /* continue with failure handling */
2574                 return gsm48_mm_loc_upd_failed(ms, NULL);
2575         }
2576
2577         LOGP(DMM, LOGL_INFO, "Loc. upd. aborted by radio (cause #%d)\n",
2578                 rrh->cause);
2579
2580         /* random access failure, but not two successive failures */
2581         if (rrh->cause == RR_REL_CAUSE_RA_FAILURE && !mm->lupd_ra_failure) {
2582                 mm->lupd_ra_failure = 1;
2583
2584                 /* start RA failure timer */
2585                 start_mm_t3213(mm);
2586
2587                 return 0;
2588         }
2589
2590         /* RA was successfull or sent twice */
2591         mm->lupd_ra_failure = 0;
2592
2593         /* continue with failure handling */
2594         return gsm48_mm_loc_upd_failed(ms, NULL);
2595 }
2596
2597 /* location update has timed out */
2598 static int gsm48_mm_loc_upd_timeout(struct osmocom_ms *ms, struct msgb *msg)
2599 {
2600         struct msgb *nmsg;
2601         struct gsm48_rr_hdr *nrrh;
2602
2603         /* abort RR connection */
2604         nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
2605         if (!nmsg)
2606                 return -ENOMEM;
2607         nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
2608         nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
2609         gsm48_rr_downmsg(ms, nmsg);
2610
2611         /* continue with failure handling */
2612         return gsm48_mm_loc_upd_failed(ms, NULL);
2613 }
2614
2615 /*
2616  * process handlers for MM connections
2617  */
2618
2619 /* cm reestablish request message from upper layer */
2620 static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
2621         uint8_t cm_serv)
2622 {
2623         struct gsm48_mmlayer *mm = &ms->mmlayer;
2624         struct gsm_subscriber *subscr = &ms->subscr;
2625         struct gsm_settings *set = &ms->settings;
2626         struct msgb *nmsg;
2627         struct gsm48_hdr *ngh;
2628         struct gsm48_service_request *nsr; /* NOTE: includes MI length */
2629         uint8_t *cm2lv;
2630         uint8_t buf[11];
2631
2632         LOGP(DMM, LOGL_INFO, "CM SERVICE REQUEST (cause %d)\n", mm->est_cause);
2633
2634         nmsg = gsm48_l3_msgb_alloc();
2635         if (!nmsg)
2636                 return -ENOMEM;
2637         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2638         nsr = (struct gsm48_service_request *)msgb_put(nmsg, sizeof(*nsr));
2639         cm2lv = (uint8_t *)&nsr->classmark;
2640
2641         ngh->proto_discr = GSM48_PDISC_MM;
2642         ngh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
2643
2644         /* type and key */
2645         nsr->cm_service_type = cm_serv;
2646         nsr->cipher_key_seq = subscr->key_seq;
2647         /* classmark 2 */
2648         cm2lv[0] = sizeof(struct gsm48_classmark2);
2649         gsm48_rr_enc_cm2(ms, (struct gsm48_classmark2 *)(cm2lv + 1));
2650         /* MI */
2651         if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0]) {
2652                 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s for emergency\n",
2653                         set->emergency_imsi);
2654                 gsm48_generate_mid_from_imsi(buf, set->emergency_imsi);
2655         } else
2656         if (!subscr->sim_valid) { /* have no SIM ? */
2657                 LOGP(DMM, LOGL_INFO, "-> Using IMEI %s\n",
2658                         set->imei);
2659                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMEI);
2660         } else
2661         if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
2662                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2663                 LOGP(DMM, LOGL_INFO, "-> Using TMSI\n");
2664         } else {
2665                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2666                 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s\n",
2667                         subscr->imsi);
2668         }
2669         msgb_put(nmsg, buf[1]); /* length is part of nsr */
2670         memcpy(&nsr->mi_len, buf + 1, 1 + buf[1]);
2671         /* prio is optional for eMLPP */
2672
2673         /* push RR header and send down */
2674         return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
2675 }
2676
2677 /* cm service abort message from upper layer
2678  * NOTE: T3240 is started by the calling function
2679  */
2680 static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms)
2681 {
2682         struct msgb *nmsg;
2683         struct gsm48_hdr *ngh;
2684
2685         LOGP(DMM, LOGL_INFO, "CM SERVICE ABORT\n");
2686
2687         nmsg = gsm48_l3_msgb_alloc();
2688         if (!nmsg)
2689                 return -ENOMEM;
2690         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2691
2692         ngh->proto_discr = GSM48_PDISC_MM;
2693         ngh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
2694
2695         /* push RR header and send down */
2696         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
2697 }
2698
2699 /* cm service acknowledge is received from lower layer */
2700 static int gsm48_mm_rx_cm_service_acc(struct osmocom_ms *ms, struct msgb *msg)
2701 {
2702         struct gsm48_mmlayer *mm = &ms->mmlayer;
2703
2704         /* stop MM connection timer */
2705         stop_mm_t3230(mm);
2706
2707         new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2708
2709         return gsm48_mm_conn_go_dedic(ms);
2710 }
2711
2712 /* 9.2.6 CM SERVICE REJECT message received */
2713 static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
2714 {
2715         struct gsm48_mmlayer *mm = &ms->mmlayer;
2716         struct gsm_subscriber *subscr = &ms->subscr;
2717         struct gsm48_hdr *gh = msgb_l3(msg);
2718         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2719         uint8_t abort_any = 0;
2720         uint8_t reject_cause;
2721
2722         if (payload_len < 1) {
2723                 LOGP(DMM, LOGL_NOTICE, "Short read of cm service reject "
2724                         "message error.\n");
2725                 return -EINVAL;
2726         }
2727
2728         /* reject cause */
2729         reject_cause = *gh->data;
2730
2731         LOGP(DMM, LOGL_INFO, "CM SERVICE REJECT (cause %d)\n", reject_cause);
2732
2733         /* stop MM connection timer */
2734         stop_mm_t3230(mm);
2735
2736         /* selection action on cause value */
2737         switch (reject_cause) {
2738         case GSM48_REJECT_IMSI_UNKNOWN_IN_VLR:
2739         case GSM48_REJECT_ILLEGAL_ME:
2740                 abort_any = 1;
2741
2742                 /* TMSI and LAI invalid */
2743                 subscr->tmsi = 0xffffffff;
2744                 subscr->lac = 0x0000;
2745
2746                 /* key is invalid */
2747                 subscr->key_seq = 7;
2748
2749                 /* update status */
2750                 new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2751
2752                 /* store LOCI on sim */
2753                 gsm_subscr_write_loci(ms);
2754
2755                 /* change to WAIT_NETWORK_CMD state impied by abort_any == 1 */
2756
2757                 if (reject_cause == GSM48_REJECT_ILLEGAL_ME)
2758                         subscr->sim_valid = 0;
2759
2760                 break;
2761         default:
2762                 /* state implied by the number of remaining connections */
2763                 ;
2764         }
2765
2766         /* release MM connection(s) */
2767         gsm48_mm_release_mm_conn(ms, abort_any, 16, 0);
2768
2769         /* state depends on the existance of remaining MM connections */
2770         if (llist_empty(&mm->mm_conn))
2771                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2772         else
2773                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2774
2775         return 0;
2776 }
2777
2778 /* initiate an MM connection 4.5.1.1
2779  *
2780  * this function is called when:
2781  * - no RR connection exists
2782  * - an RR connection exists, but this is the first MM connection
2783  * - an RR connection exists, and there are already MM connection(s)
2784  */
2785 static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
2786         int rr_prim)
2787 {
2788         struct gsm48_mmlayer *mm = &ms->mmlayer;
2789         struct gsm_subscriber *subscr = &ms->subscr;
2790         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
2791         int msg_type = mmh->msg_type;
2792         int emergency = 0;
2793         uint8_t cause = 0, cm_serv = 0, proto = 0;
2794         struct msgb *nmsg;
2795         struct gsm48_mmxx_hdr *nmmh;
2796         struct gsm48_mm_conn *conn, *conn_found = NULL;
2797
2798         /* reset loc. upd. counter on CM service request */
2799         mm->lupd_attempt = 0;
2800
2801         /* find if there is already a pending connection */
2802         llist_for_each_entry(conn, &mm->mm_conn, list) {
2803                 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
2804                         conn_found = conn;
2805                         break;
2806                 }
2807         }
2808
2809         /* if pending connection */
2810         if (conn_found) {
2811                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but already have "
2812                         "pending MM Connection.\n");
2813                 cause = 17;
2814                 reject:
2815                 nmsg = NULL;
2816                 switch(msg_type) {
2817                 case GSM48_MMCC_EST_REQ:
2818                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND,
2819                                 mmh->ref, mmh->transaction_id);
2820                         break;
2821                 case GSM48_MMSS_EST_REQ:
2822                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND,
2823                                 mmh->ref, mmh->transaction_id);
2824                         break;
2825                 case GSM48_MMSMS_EST_REQ:
2826                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND,
2827                                 mmh->ref, mmh->transaction_id);
2828                         break;
2829                 }
2830                 if (!nmsg)
2831                         return -ENOMEM;
2832                 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
2833                 nmmh->cause = cause;
2834                 gsm48_mmxx_upmsg(ms, nmsg);
2835
2836                 return -EBUSY;
2837         }
2838         /* in case of an emergency setup */
2839         if (msg_type == GSM48_MMCC_EST_REQ && mmh->emergency)
2840                 emergency = 1;
2841
2842         /* if sim is not updated */
2843         if (!emergency && subscr->ustate != GSM_SIM_U1_UPDATED) {
2844                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but SIM not "
2845                         "updated.\n");
2846                 cause = 21;
2847                 goto reject;
2848         }
2849
2850         if (mm->state == GSM48_MM_ST_MM_IDLE) {
2851                 /* current MM idle state */
2852                 switch (mm->substate) {
2853                 case GSM48_MM_SST_NORMAL_SERVICE:
2854                 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
2855                         LOGP(DMM, LOGL_INFO, "Init MM Connection.\n");
2856                         break; /* allow when normal */
2857                 case GSM48_MM_SST_LOC_UPD_NEEDED:
2858                 case GSM48_MM_SST_ATTEMPT_UPDATE:
2859                         /* store mm request if attempting to update */
2860                         if (!emergency) {
2861                                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but "
2862                                         "attempting to update.\n");
2863                                 cause = 21;
2864                                 goto reject;
2865                                 /* TODO: implement delay and start loc upd. */
2866                         }
2867                         break;
2868                 default:
2869                         /* reject if not emergency */
2870                         if (!emergency) {
2871                                 LOGP(DMM, LOGL_INFO, "Init MM Connection, not "
2872                                         "in normal state.\n");
2873                                 cause = 21;
2874                                 goto reject;
2875                         }
2876                         break;
2877                 }
2878         } else
2879                 LOGP(DMM, LOGL_INFO, "Init another MM Connection.\n");
2880
2881         /* set cause, service, proto */
2882         switch(msg_type) {
2883         case GSM48_MMCC_EST_REQ:
2884                 if (emergency) {
2885                         cause = RR_EST_CAUSE_EMERGENCY;
2886                         cm_serv = GSM48_CMSERV_EMERGENCY;
2887                 } else {
2888                         cause = RR_EST_CAUSE_ORIG_TCHF;
2889                         cm_serv = GSM48_CMSERV_MO_CALL_PACKET;
2890                 }
2891                 proto = GSM48_PDISC_CC;
2892                 break;
2893         case GSM48_MMSS_EST_REQ:
2894                 cause = RR_EST_CAUSE_OTHER_SDCCH;
2895                 cm_serv = GSM48_CMSERV_SUP_SERV;
2896                 proto = GSM48_PDISC_NC_SS;
2897                 break;
2898         case GSM48_MMSMS_EST_REQ:
2899                 cause = RR_EST_CAUSE_OTHER_SDCCH;
2900                 cm_serv = GSM48_CMSERV_SMS;
2901                 proto = GSM48_PDISC_SMS;
2902                 break;
2903         }
2904
2905         /* create MM connection instance */
2906         conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
2907         if (!conn)
2908                 return -ENOMEM;
2909
2910         new_conn_state(conn, GSM48_MMXX_ST_CONN_PEND);
2911
2912         /* send CM SERVICE REQUEST */
2913         if (rr_prim) {
2914                 mm->est_cause = cause;
2915                 return gsm48_mm_tx_cm_serv_req(ms, rr_prim, cm_serv);
2916         } else
2917                 return 0;
2918 }
2919
2920 /* 4.5.1.1 a) MM connection request triggers RR connection */
2921 static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, struct msgb *msg)
2922 {
2923         struct gsm48_mmlayer *mm = &ms->mmlayer;
2924         int rc;
2925
2926         /* start MM connection by requesting RR connection */
2927         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_EST_REQ);
2928         if (rc)
2929                 return rc;
2930
2931         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
2932
2933         return 0;
2934 }
2935
2936 /* 4.5.1.1 a) RR is esablised during mm connection, wait for CM accepted */
2937 static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct msgb *msg)
2938 {
2939         struct gsm48_mmlayer *mm = &ms->mmlayer;
2940
2941         /* 4.5.1.7 if there is no more MM connection */
2942         if (llist_empty(&mm->mm_conn)) {
2943                 LOGP(DMM, LOGL_INFO, "MM Connection, are already gone.\n");
2944
2945                 /* start RR release timer */
2946                 start_mm_t3240(mm);
2947
2948                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2949
2950                 /* send abort */
2951                 return gsm48_mm_tx_cm_service_abort(ms);
2952         }
2953
2954         /* start MM connection timer */
2955         start_mm_t3230(mm);
2956
2957         new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2958
2959         return 0;
2960 }
2961
2962 /* 4.5.1.1 b) MM connection request on existing RR connection */
2963 static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, struct msgb *msg)
2964 {
2965         struct gsm48_mmlayer *mm = &ms->mmlayer;
2966         int rc;
2967
2968         /* start MM connection by sending data */
2969         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
2970         if (rc)
2971                 return rc;
2972
2973         /* stop "RR connection release not allowed" timer */
2974         stop_mm_t3241(mm);
2975
2976         /* start MM connection timer */
2977         start_mm_t3230(mm);
2978
2979         new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2980
2981         return 0;
2982 }
2983
2984 /* 4.5.1.1 b) another MM connection request on existing RR connection */
2985 static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, struct msgb *msg)
2986 {
2987         struct gsm48_mmlayer *mm = &ms->mmlayer;
2988         int rc;
2989
2990         /* start MM connection by sending data */
2991         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
2992         if (rc)
2993                 return rc;
2994
2995         /* start MM connection timer */
2996         start_mm_t3230(mm);
2997
2998         new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
2999
3000         return 0;
3001 }
3002
3003 /* 4.5.1.1 b) delay on WAIT FOR NETWORK COMMAND state */
3004 static int gsm48_mm_init_mm_wait(struct osmocom_ms *ms, struct msgb *msg)
3005 {
3006         /* reject */
3007         gsm48_mm_init_mm_reject(ms, msg);
3008 #if 0
3009         this requires handling when leaving this state...
3010
3011         struct gsm48_mmlayer *mm = &ms->mmlayer;
3012         int rc;
3013
3014         /* just create the MM connection in pending state */
3015         rc = gsm48_mm_init_mm(ms, msg, 0);
3016         if (rc)
3017                 return rc;
3018
3019         /* start MM connection timer */
3020         start_mm_t3230(mm);
3021
3022         new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
3023 #endif
3024
3025         return 0;
3026 }
3027
3028 /* initiate an mm connection other cases */
3029 static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
3030 {
3031         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3032         int msg_type = mmh->msg_type;
3033         struct msgb *nmsg;
3034         struct gsm48_mmxx_hdr *nmmh;
3035
3036         /* reject */
3037         nmsg = NULL;
3038         switch(msg_type) {
3039         case GSM48_MMCC_EST_REQ:
3040                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
3041                         mmh->transaction_id);
3042                 break;
3043         case GSM48_MMSS_EST_REQ:
3044                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
3045                         mmh->transaction_id);
3046                 break;
3047         case GSM48_MMSMS_EST_REQ:
3048                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
3049                         mmh->transaction_id);
3050                 break;
3051         }
3052         if (!nmsg)
3053                 return -ENOMEM;
3054         nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3055         nmmh->cause = 17;
3056         gsm48_mmxx_upmsg(ms, nmsg);
3057
3058         return 0;
3059 }
3060
3061 /* accepting pending connection, got dedicated mode
3062  *
3063  * this function is called:
3064  * - when ciphering command is received
3065  * - when cm service is accepted 
3066  */
3067 static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
3068 {
3069         struct gsm48_mmlayer *mm = &ms->mmlayer;
3070         struct gsm48_mm_conn *conn, *conn_found = NULL;
3071         struct msgb *nmsg;
3072         struct gsm48_mmxx_hdr *nmmh;
3073
3074         /* the first and only pending connection is the recent requested */
3075         llist_for_each_entry(conn, &mm->mm_conn, list) {
3076                 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
3077                         conn_found = conn;
3078                         break;
3079                 }
3080         }
3081
3082         /* if no pending connection (anymore) */
3083         if (!conn_found) {
3084                 LOGP(DMM, LOGL_INFO, "No pending MM Connection.\n");
3085
3086                 return 0;
3087         }
3088
3089         new_conn_state(conn, GSM48_MMXX_ST_DEDICATED);
3090
3091         /* send establishment confirm */
3092         nmsg = NULL;
3093         switch(conn_found->protocol) {
3094         case GSM48_PDISC_CC:
3095                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF, conn->ref,
3096                         conn->transaction_id);
3097                 break;
3098         case GSM48_PDISC_NC_SS:
3099                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF, conn->ref,
3100                         conn->transaction_id);
3101                 break;
3102         case GSM48_PDISC_SMS:
3103                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF, conn->ref,
3104                         conn->transaction_id);
3105                 break;
3106         }
3107         if (!nmsg)
3108                 return -ENOMEM;
3109         nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3110         nmmh->cause = 17;
3111         gsm48_mmxx_upmsg(ms, nmsg);
3112
3113         return 0;
3114 }
3115
3116 /* a RR-SYNC-IND is received during MM connection establishment */
3117 static int gsm48_mm_sync_ind_wait(struct osmocom_ms *ms, struct msgb *msg)
3118 {
3119         struct gsm48_mmlayer *mm = &ms->mmlayer;
3120         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3121
3122         if (rrh->cause != RR_SYNC_CAUSE_CIPHERING) {
3123                 LOGP(DMM, LOGL_NOTICE, "Ignore sync indication, not waiting "
3124                         "for CM service\n");
3125                 return -EINVAL;
3126         }
3127
3128         /* stop MM connection timer */
3129         stop_mm_t3230(mm);
3130
3131         return gsm48_mm_conn_go_dedic(ms);
3132 }
3133
3134 /* a RR-SYNC-IND is received during MM connection active */
3135 static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
3136 {
3137         struct gsm48_mmlayer *mm = &ms->mmlayer;
3138         struct gsm48_mm_conn *conn;
3139         struct msgb *nmsg;
3140         struct gsm48_mmxx_hdr *nmmh;
3141
3142         /* stop MM connection timer */
3143         stop_mm_t3230(mm);
3144
3145         /* broadcast all MMCC connection(s) */
3146         llist_for_each_entry(conn, &mm->mm_conn, list) {
3147                 /* send MMCC-SYNC-IND */
3148                 nmsg = NULL;
3149                 switch(conn->protocol) {
3150                 case GSM48_PDISC_CC:
3151                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_SYNC_IND,
3152                                 conn->ref, conn->transaction_id);
3153                         break;
3154                 }
3155                 if (!nmsg)
3156                         continue; /* skip if not of CC type */
3157                 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3158                 nmmh->cause = 17;
3159                 /* copy L3 message */
3160                 nmsg->l3h = msgb_put(nmsg, msgb_l3len(msg));
3161                 memcpy(nmsg->l3h, msg->l3h, msgb_l3len(msg));
3162                 gsm48_mmxx_upmsg(ms, nmsg);
3163         }
3164
3165         return 0;
3166 }
3167
3168 /* 4.5.1.2 RR abort/release is received during MM connection establishment */
3169 static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3170 {
3171         struct gsm48_mmlayer *mm = &ms->mmlayer;
3172         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3173         int cause;
3174
3175         /* stop RR release timer */
3176         stop_mm_t3240(mm);
3177
3178         /* this conversion is not of any standard */
3179         switch(rrh->cause) {
3180         case RR_REL_CAUSE_NOT_AUTHORIZED:
3181         case RR_REL_CAUSE_EMERGENCY_ONLY:
3182         case RR_REL_CAUSE_TRY_LATER:
3183                 cause = 21;
3184                 break;
3185         case RR_REL_CAUSE_NORMAL:
3186                 cause = 16;
3187                 break;
3188         default:
3189                 cause = 47;
3190         }
3191
3192         /* stop MM connection timer */
3193         stop_mm_t3230(mm);
3194
3195         /* release all connections */
3196         gsm48_mm_release_mm_conn(ms, 1, cause, 1);
3197
3198         /* no RR connection, so we return to MM IDLE */
3199         if (mm->state == GSM48_MM_ST_WAIT_RR_CONN_MM_CON)
3200                 return gsm48_mm_return_idle(ms, NULL);
3201
3202         /* CS process will trigger: return to MM IDLE */
3203         return 0;
3204 }
3205
3206 /* 4.5.1.2 timeout is received during MM connection establishment */
3207 static int gsm48_mm_timeout_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3208 {
3209         struct gsm48_mmlayer *mm = &ms->mmlayer;
3210
3211         /* release pending connection */
3212         gsm48_mm_release_mm_conn(ms, 0, 102, 0);
3213
3214         /* state depends on the existance of remaining MM connections */
3215         if (llist_empty(&mm->mm_conn)) {
3216                 /* start RR release timer */
3217                 start_mm_t3240(mm);
3218
3219                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3220         } else
3221                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3222
3223         return 0;
3224 }
3225
3226 /* respond to paging */
3227 static int gsm48_mm_est(struct osmocom_ms *ms, struct msgb *msg)
3228 {
3229         struct gsm48_mmlayer *mm = &ms->mmlayer;
3230
3231         mm->est_cause = RR_EST_CAUSE_ANS_PAG_ANY;
3232         new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3233
3234         return 0;
3235 }
3236
3237 /* send CM data */
3238 static int gsm48_mm_data(struct osmocom_ms *ms, struct msgb *msg)
3239 {
3240         struct gsm48_mmlayer *mm = &ms->mmlayer;
3241         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3242         struct gsm48_mm_conn *conn;
3243         int msg_type = mmh->msg_type;
3244
3245         /* get connection, if not exist (anymore), release */
3246         conn = mm_conn_by_ref(mm, mmh->ref);
3247         if (!conn) {
3248                 LOGP(DMM, LOGL_INFO, "MMXX_DATA_REQ with unknown (already "
3249                         "released) ref=%x, sending MMXX_REL_IND\n", mmh->ref);
3250                 switch(msg_type & GSM48_MMXX_MASK) {
3251                 case GSM48_MMCC_CLASS:
3252                         mmh->msg_type = GSM48_MMCC_REL_IND;
3253                         break;
3254                 case GSM48_MMSS_CLASS:
3255                         mmh->msg_type = GSM48_MMSS_REL_IND;
3256                         break;
3257                 case GSM48_MMSMS_CLASS:
3258                         mmh->msg_type = GSM48_MMSMS_REL_IND;
3259                         break;
3260                 }
3261                 mmh->cause = 31;
3262
3263                 /* mirror message with REL_IND + cause */
3264                 return gsm48_mmxx_upmsg(ms, msg);
3265         }
3266         
3267         /* pull MM header */
3268         msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
3269
3270         /* push RR header and send down */
3271         return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, 0);
3272 }
3273
3274 /* release of MM connection (active state) */
3275 static int gsm48_mm_release_active(struct osmocom_ms *ms, struct msgb *msg)
3276 {
3277         struct gsm48_mmlayer *mm = &ms->mmlayer;
3278         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3279         struct gsm48_mm_conn *conn;
3280
3281         /* get connection, if not exist (anymore), release */
3282         conn = mm_conn_by_ref(mm, mmh->ref);
3283         if (conn)
3284                 mm_conn_free(conn);
3285
3286         /* state depends on the existance of remaining MM connections */
3287         if (llist_empty(&mm->mm_conn)) {
3288                 /* start RR release timer */
3289                 start_mm_t3240(mm);
3290
3291                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3292         } else
3293                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3294
3295         return 0;
3296 }
3297
3298 /* release of MM connection (wait for additional state) */
3299 static int gsm48_mm_release_wait_add(struct osmocom_ms *ms, struct msgb *msg)
3300 {
3301         struct gsm48_mmlayer *mm = &ms->mmlayer;
3302         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3303         struct gsm48_mm_conn *conn;
3304
3305         /* get connection, if not exist (anymore), release */
3306         conn = mm_conn_by_ref(mm, mmh->ref);
3307         if (conn)
3308                 mm_conn_free(conn);
3309
3310         return 0;
3311 }
3312
3313 /* release of MM connection (wait for active state) */
3314 static int gsm48_mm_release_wait_active(struct osmocom_ms *ms, struct msgb *msg)
3315 {
3316         struct gsm48_mmlayer *mm = &ms->mmlayer;
3317         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3318         struct gsm48_mm_conn *conn;
3319
3320         /* get connection, if not exist (anymore), release */
3321         conn = mm_conn_by_ref(mm, mmh->ref);
3322         if (conn)
3323                 mm_conn_free(conn);
3324
3325         /* 4.5.1.7 if there is no MM connection during wait for active state */
3326         if (llist_empty(&mm->mm_conn)) {
3327                 LOGP(DMM, LOGL_INFO, "No MM Connection during 'wait for "
3328                         "active' state.\n");
3329
3330                 /* start RR release timer */
3331                 start_mm_t3240(mm);
3332
3333                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3334
3335                 /* send abort */
3336                 return gsm48_mm_tx_cm_service_abort(ms);
3337         }
3338
3339         return 0;
3340 }
3341
3342 /* release of MM connection (wait for RR state) */
3343 static int gsm48_mm_release_wait_rr(struct osmocom_ms *ms, struct msgb *msg)
3344 {
3345         struct gsm48_mmlayer *mm = &ms->mmlayer;
3346         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3347         struct gsm48_mm_conn *conn;
3348
3349         /* get connection, if not exist (anymore), release */
3350         conn = mm_conn_by_ref(mm, mmh->ref);
3351         if (conn)
3352                 mm_conn_free(conn);
3353
3354         /* later, if RR connection is established, the CM SERIVE ABORT
3355          * message will be sent
3356          */
3357         return 0;
3358 }
3359
3360 /* abort RR connection (due to T3240) */
3361 static int gsm48_mm_abort_rr(struct osmocom_ms *ms, struct msgb *msg)
3362 {
3363         struct msgb *nmsg;
3364         struct gsm48_rr_hdr *nrrh;
3365
3366         /* send abort to RR */
3367         nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
3368         if (!nmsg)
3369                 return -ENOMEM;
3370         nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
3371         nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
3372         gsm48_rr_downmsg(ms, nmsg);
3373
3374         /* CS process will trigger: return to MM IDLE / No SIM */
3375         return 0;
3376 }
3377
3378 /*
3379  * other processes
3380  */
3381
3382 /* RR is released in other states */
3383 static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct msgb *msg)
3384 {
3385         struct gsm48_mmlayer *mm = &ms->mmlayer;
3386
3387         /* stop RR release timer (if running) */
3388         stop_mm_t3240(mm);
3389
3390         /* CS process will trigger: return to MM IDLE */
3391         return 0;
3392 }
3393
3394 /*
3395  * state machines
3396  */
3397
3398 /* state trasitions for MMxx-SAP messages from upper layers */
3399 static struct downstate {
3400         uint32_t        states;
3401         uint32_t        substates;
3402         int             type;
3403         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3404 } downstatelist[] = {
3405         /* 4.2.2.1 Normal service */
3406         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3407          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3408
3409         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3410          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3411
3412         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3413          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3414
3415         /* 4.2.2.2 Attempt to update / Loc. Upd. needed */
3416         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3417                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3418          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr}, /* emergency only */
3419
3420         /* 4.2.2.3 Limited service */
3421         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3422          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3423
3424         /* 4.2.2.4 No IMSI */
3425         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
3426          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3427
3428         /* 4.2.2.5 PLMN search, normal service */
3429         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3430          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3431
3432         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3433          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3434
3435         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3436          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3437
3438         /* 4.2.2.6 PLMN search */
3439         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3440          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3441
3442         /* 4.5.1.1 MM Connection (EST) */
3443         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3444          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_first},
3445
3446         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3447          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_first},
3448
3449         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3450          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_first},
3451
3452         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3453          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_more},
3454
3455         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3456          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_more},
3457
3458         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3459          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_more},
3460
3461         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3462          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_wait},
3463
3464         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3465          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_wait},
3466
3467         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3468          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_wait},
3469
3470         {ALL_STATES, ALL_STATES,
3471          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_reject},
3472
3473         {ALL_STATES, ALL_STATES,
3474          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_reject},
3475
3476         {ALL_STATES, ALL_STATES,
3477          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_reject},
3478
3479         /* 4.5.2.1 MM Connection (DATA) */
3480         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3481          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3482          GSM48_MMCC_DATA_REQ, gsm48_mm_data},
3483
3484         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3485          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3486          GSM48_MMSS_DATA_REQ, gsm48_mm_data},
3487
3488         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3489          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3490          GSM48_MMSMS_DATA_REQ, gsm48_mm_data},
3491
3492         /* 4.5.2.1 MM Connection (REL) */
3493         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3494          GSM48_MMCC_REL_REQ, gsm48_mm_release_active},
3495
3496         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3497          GSM48_MMSS_REL_REQ, gsm48_mm_release_active},
3498
3499         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3500          GSM48_MMSMS_REL_REQ, gsm48_mm_release_active},
3501
3502         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3503          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_add},
3504
3505         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3506          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_add},
3507
3508         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3509          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_add},
3510
3511         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3512          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_active},
3513
3514         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3515          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_active},
3516
3517         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3518          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_active},
3519
3520         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3521          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_rr},
3522
3523         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3524          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_rr},
3525
3526         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3527          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_rr},
3528 };
3529
3530 #define DOWNSLLEN \
3531         (sizeof(downstatelist) / sizeof(struct downstate))
3532
3533 int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg)
3534 {
3535         struct gsm48_mmlayer *mm = &ms->mmlayer;
3536         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3537         int msg_type = mmh->msg_type;
3538         struct gsm48_mm_conn *conn;
3539         int i, rc;
3540
3541         /* keep up to date with the transaction ID */
3542         conn = mm_conn_by_ref(mm, mmh->ref);
3543         if (conn)
3544                 conn->transaction_id = mmh->transaction_id;
3545
3546         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
3547                 ms->name, get_mmxx_name(msg_type),
3548                 gsm48_mm_state_names[mm->state]);
3549         if (mm->state == GSM48_MM_ST_MM_IDLE)
3550                 LOGP(DMM, LOGL_INFO, "-> substate %s\n",
3551                         gsm48_mm_substate_names[mm->substate]);
3552         LOGP(DMM, LOGL_INFO, "-> callref %x, transaction_id %d\n",
3553                 mmh->ref, mmh->transaction_id);
3554
3555         /* Find function for current state and message */
3556         for (i = 0; i < DOWNSLLEN; i++)
3557                 if ((msg_type == downstatelist[i].type)
3558                  && ((1 << mm->state) & downstatelist[i].states)
3559                  && ((1 << mm->substate) & downstatelist[i].substates))
3560                         break;
3561         if (i == DOWNSLLEN) {
3562                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3563                 msgb_free(msg);
3564                 return 0;
3565         }
3566
3567         rc = downstatelist[i].rout(ms, msg);
3568
3569         if (downstatelist[i].rout != gsm48_mm_data)
3570                 msgb_free(msg);
3571
3572         return rc;
3573 }
3574
3575 /* state trasitions for radio ressource messages (lower layer) */
3576 static struct rrdatastate {
3577         uint32_t        states;
3578         int             type;
3579         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3580 } rrdatastatelist[] = {
3581         /* paging */
3582         {SBIT(GSM48_MM_ST_MM_IDLE),
3583          GSM48_RR_EST_IND, gsm48_mm_est},
3584
3585         /* imsi detach */
3586         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 */
3587          GSM48_RR_EST_CNF, gsm48_mm_imsi_detach_sent},
3588
3589         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (unsuc.) */
3590          GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3591                 /* also this may happen if SABM is ackwnowledged with DISC */
3592
3593         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (lost) */
3594          GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3595
3596         {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (unsuc.) */
3597          GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3598
3599         {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (lost) */
3600          GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3601
3602         /* location update */
3603         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
3604          GSM48_RR_EST_CNF, gsm48_mm_est_loc_upd},
3605
3606         {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3607          SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3608          GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_abort},
3609
3610         {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3611          SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3612          GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_abort},
3613
3614         {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3615          GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
3616
3617         {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3618          GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_rej},
3619
3620         /* MM connection (EST) */
3621         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
3622          GSM48_RR_EST_CNF, gsm48_mm_est_mm_con},
3623
3624         /* MM connection (DATA) */
3625         {ALL_STATES,
3626          GSM48_RR_DATA_IND, gsm48_mm_data_ind},
3627
3628         /* MM connection (SYNC) */
3629         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3630          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.1 */
3631          GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_wait},
3632
3633         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE),
3634          GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_active},
3635
3636         /* MM connection (REL/ABORT) */
3637         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3638          SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3639          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3640          GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3641
3642         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3643          SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3644          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3645          GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3646
3647         /* MM connection (REL/ABORT with re-establishment possibility) */
3648         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), /* not supported */
3649          GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3650
3651         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3652          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* not supported */
3653          GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3654
3655         /* other (also wait for network command) */
3656         {ALL_STATES,
3657          GSM48_RR_REL_IND, gsm48_mm_rel_other},
3658
3659         {ALL_STATES,
3660          GSM48_RR_ABORT_IND, gsm48_mm_rel_other},
3661 };
3662
3663 #define RRDATASLLEN \
3664         (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
3665
3666 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
3667 {
3668         struct gsm48_mmlayer *mm = &ms->mmlayer;
3669         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3670         int msg_type = rrh->msg_type;
3671         int i, rc;
3672
3673         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s\n",
3674                 ms->name, get_rr_name(msg_type),
3675                 gsm48_mm_state_names[mm->state]);
3676
3677         /* find function for current state and message */
3678         for (i = 0; i < RRDATASLLEN; i++)
3679                 if ((msg_type == rrdatastatelist[i].type)
3680                  && ((1 << mm->state) & rrdatastatelist[i].states))
3681                         break;
3682         if (i == RRDATASLLEN) {
3683                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3684                 msgb_free(msg);
3685                 return 0;
3686         }
3687
3688         rc = rrdatastatelist[i].rout(ms, msg);
3689         
3690         if (rrdatastatelist[i].rout != gsm48_mm_data_ind)
3691                 msgb_free(msg);
3692
3693         return rc;
3694 }
3695
3696 /* state trasitions for mobile managemnt messages (lower layer) */
3697 static struct mmdatastate {
3698         uint32_t        states;
3699         int             type;
3700         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3701 } mmdatastatelist[] = {
3702         {ALL_STATES, /* 4.3.1.2 */
3703          GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
3704
3705         {ALL_STATES, /* 4.3.2.2 */
3706          GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
3707
3708         {ALL_STATES, /* 4.3.2.5 */
3709          GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
3710
3711         {ALL_STATES, /* 4.3.3.2 */
3712          GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
3713
3714         {ALL_STATES, /* 4.3.5.2 */
3715          GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
3716
3717         {ALL_STATES, /* 4.3.6.2 */
3718          GSM48_MT_MM_INFO, gsm48_mm_rx_info},
3719
3720         {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.6 */
3721          GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
3722
3723         {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.7 */
3724          GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
3725
3726         {ALL_STATES, /* 4.5.1.1 */
3727          GSM48_MT_MM_CM_SERV_ACC, gsm48_mm_rx_cm_service_acc},
3728
3729         {ALL_STATES, /* 4.5.1.1 */
3730          GSM48_MT_MM_CM_SERV_REJ, gsm48_mm_rx_cm_service_rej},
3731 };
3732
3733 #define MMDATASLLEN \
3734         (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
3735
3736 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
3737 {
3738         struct gsm48_mmlayer *mm = &ms->mmlayer;
3739         struct gsm48_hdr *gh = msgb_l3(msg);
3740         uint8_t pdisc = gh->proto_discr & 0x0f;
3741         uint8_t msg_type = gh->msg_type & 0xbf;
3742         struct gsm48_mmxx_hdr *mmh;
3743         int msg_supported = 0; /* determine, if message is supported at all */
3744         int rr_prim = -1, rr_est = -1; /* no prim set */
3745         uint8_t skip_ind;
3746         int i, rc;
3747
3748         /* 9.2.19 */
3749         if (msg_type == GSM48_MT_MM_NULL)
3750                 return 0;
3751
3752         if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
3753                 LOGP(DMM, LOGL_NOTICE, "DATA IND ignored during IMSI "
3754                         "detach.\n");
3755                 return 0;
3756         }
3757         /* pull the RR header */
3758         msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
3759
3760         /* create transaction (if not exists) and push message */
3761         switch (pdisc) {
3762         case GSM48_PDISC_CC:
3763                 rr_prim = GSM48_MMCC_DATA_IND;
3764                 rr_est = GSM48_MMCC_EST_IND;
3765                 break;
3766 #if 0
3767         case GSM48_PDISC_NC_SS:
3768                 rr_prim = GSM48_MMSS_DATA_IND;
3769                 rr_est = GSM48_MMSS_EST_IND;
3770                 break;
3771         case GSM48_PDISC_SMS:
3772                 rr_prim = GSM48_MMSMS_DATA_IND;
3773                 rr_est = GSM48_MMSMS_EST_IND;
3774                 break;
3775 #endif
3776         }
3777         if (rr_prim != -1) {
3778                 uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
3779                         /* flip */
3780                 struct gsm48_mm_conn *conn;
3781
3782                 /* find transaction, if any */
3783                 conn = mm_conn_by_id(mm, pdisc, transaction_id);
3784
3785                 /* create MM connection instance */
3786                 if (!conn) {
3787                         conn = mm_conn_new(mm, pdisc, transaction_id,
3788                                 mm_conn_new_ref++);
3789                         rr_prim = rr_est;
3790                 }
3791                 if (!conn)
3792                         return -ENOMEM;
3793
3794                 /* push new header */
3795                 msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
3796                 mmh = (struct gsm48_mmxx_hdr *)msg->data;
3797                 mmh->msg_type = rr_prim;
3798                 mmh->ref = conn->ref;
3799
3800                 /* go MM CONN ACTIVE state */
3801                 if (mm->state == GSM48_MM_ST_WAIT_NETWORK_CMD
3802                  || mm->state == GSM48_MM_ST_RR_CONN_RELEASE_NA) {
3803                         /* stop RR release timer */
3804                         stop_mm_t3240(mm);
3805
3806                         /* stop "RR connection release not allowed" timer */
3807                         stop_mm_t3241(mm);
3808
3809                         new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3810                 }
3811         }
3812
3813         /* forward message */
3814         switch (pdisc) {
3815         case GSM48_PDISC_MM:
3816                 skip_ind = (gh->proto_discr & 0xf0) >> 4;
3817
3818                 /* ignore if skip indicator is not B'0000' */
3819                 if (skip_ind)
3820                         return 0;
3821                 break; /* follow the selection proceedure below */
3822
3823         case GSM48_PDISC_CC:
3824                 return gsm48_rcv_cc(ms, msg);
3825
3826 #if 0
3827         case GSM48_PDISC_NC_SS:
3828                 return gsm48_rcv_ss(ms, msg);
3829
3830         case GSM48_PDISC_SMS:
3831                 return gsm48_rcv_sms(ms, msg);
3832 #endif
3833
3834         default:
3835                 LOGP(DMM, LOGL_NOTICE, "Protocol type 0x%02x unsupported.\n",
3836                         pdisc);
3837                 msgb_free(msg);
3838                 return gsm48_mm_tx_mm_status(ms,
3839                         GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3840         }
3841
3842         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
3843                 get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
3844
3845         stop_mm_t3212(mm); /* 4.4.2 */
3846
3847         /* 11.2 re-start pending RR release timer */
3848         if (bsc_timer_pending(&mm->t3240)) {
3849                 stop_mm_t3240(mm);
3850                 start_mm_t3240(mm);
3851         }
3852
3853         /* find function for current state and message */
3854         for (i = 0; i < MMDATASLLEN; i++) {
3855                 if (msg_type == mmdatastatelist[i].type)
3856                         msg_supported = 1;
3857                 if ((msg_type == mmdatastatelist[i].type)
3858                  && ((1 << mm->state) & mmdatastatelist[i].states))
3859                         break;
3860         }
3861         if (i == MMDATASLLEN) {
3862                 msgb_free(msg);
3863                 if (msg_supported) {
3864                         LOGP(DMM, LOGL_NOTICE, "Message unhandled at this "
3865                                 "state.\n");
3866                         return gsm48_mm_tx_mm_status(ms,
3867                                 GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
3868                 } else {
3869                         LOGP(DMM, LOGL_NOTICE, "Message not supported.\n");
3870                         return gsm48_mm_tx_mm_status(ms,
3871                                 GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3872                 }
3873         }
3874
3875         rc = mmdatastatelist[i].rout(ms, msg);
3876
3877         msgb_free(msg);
3878
3879         return rc;
3880 }
3881
3882 /* state trasitions for mobile management events */
3883 static struct eventstate {
3884         uint32_t        states;
3885         uint32_t        substates;
3886         int             type;
3887         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3888 } eventstatelist[] = {
3889         /* 4.2.3 return to MM IDLE */
3890         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3891          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found},
3892
3893         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3894          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_return_idle},
3895
3896         /* 4.2.2.1 Normal service */
3897         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3898          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3899
3900         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3901          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3902
3903         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3904          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3905
3906         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3907          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3908
3909         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3910          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3911
3912         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3913          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3914
3915         /* 4.2.2.2 Attempt to update / Loc. upd. needed */
3916         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3917                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3918          GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3919
3920         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3921                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3922          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3923
3924         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3925                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3926          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3927
3928         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3929          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3930
3931         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3932          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3933
3934         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3935          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3936
3937         /* 4.2.2.3 Limited service */
3938         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3939          GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3940
3941         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3942          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3943
3944         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3945          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* if allow. */
3946
3947         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3948          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3949
3950         /* 4.2.2.4 No IMSI */
3951         /* 4.2.2.5 PLMN search, normal service */
3952         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3953          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3954
3955         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3956          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3957
3958         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3959          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd_delay_retry},
3960
3961         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3962          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_delay_retry},
3963
3964         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3965          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3966
3967         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3968          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3969
3970         /* 4.2.2.6 PLMN search */
3971         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3972          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3973
3974         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3975          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3976
3977         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3978          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3979
3980         /* No cell available */
3981         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3982          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3983
3984         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3985          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3986
3987         /* IMSI detach in other cases */
3988         {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES, /* silently detach */
3989          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_end},
3990
3991         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3992          SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3993          SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
3994          SBIT(GSM48_MM_ST_WAIT_REEST) |
3995          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON) |
3996          SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
3997          SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES, /* we can release */
3998          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_release},
3999
4000         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D) |
4001          SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
4002          SBIT(GSM48_MM_ST_IMSI_DETACH_PEND), ALL_STATES, /* ignore */
4003          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_ignore},
4004
4005         {ALL_STATES, ALL_STATES,
4006          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
4007
4008         {GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
4009          GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
4010
4011         /* location update in other cases */
4012         {ALL_STATES, ALL_STATES,
4013          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_ignore},
4014
4015         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4016          GSM48_MM_EVENT_TIMEOUT_T3210, gsm48_mm_loc_upd_timeout},
4017
4018         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4019          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_failed},
4020                 /* 4.4.4.9 c) (but without retry) */
4021
4022         /* SYSINFO event */
4023         {ALL_STATES, ALL_STATES,
4024          GSM48_MM_EVENT_SYSINFO, gsm48_mm_sysinfo},
4025
4026         /* T3240 timed out */
4027         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
4028          SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES, /* 4.4.4.8 */
4029          GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
4030
4031         /* T3230 timed out */
4032         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
4033          GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
4034
4035         /* SIM reports SRES */
4036         {ALL_STATES, ALL_STATES, /* 4.3.2.2 */
4037          GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
4038
4039 #if 0
4040         /* change in classmark is reported */
4041         {ALL_STATES, ALL_STATES,
4042          GSM48_MM_EVENT_CLASSMARK_CHG, gsm48_mm_classm_chg},
4043 #endif
4044 };
4045
4046 #define EVENTSLLEN \
4047         (sizeof(eventstatelist) / sizeof(struct eventstate))
4048
4049 static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg)
4050 {
4051         struct gsm48_mmlayer *mm = &ms->mmlayer;
4052         int i, rc;
4053
4054         if (mm->state == GSM48_MM_ST_MM_IDLE)
4055                 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4056                         "MM IDLE, %s\n", ms->name, get_mmevent_name(msg_type),
4057                         gsm48_mm_substate_names[mm->substate]);
4058         else
4059                 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4060                         "%s\n", ms->name, get_mmevent_name(msg_type),
4061                 gsm48_mm_state_names[mm->state]);
4062
4063         /* Find function for current state and message */
4064         for (i = 0; i < EVENTSLLEN; i++)
4065                 if ((msg_type == eventstatelist[i].type)
4066                  && ((1 << mm->state) & eventstatelist[i].states)
4067                  && ((1 << mm->substate) & eventstatelist[i].substates))
4068                         break;
4069         if (i == EVENTSLLEN) {
4070                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
4071                 return 0;
4072         }
4073
4074         rc = eventstatelist[i].rout(ms, msg);
4075
4076         return rc;
4077 }
4078
4079 /*
4080  * MM Register (SIM insert and remove)
4081  */
4082
4083 /* register new SIM card and trigger attach */
4084 static int gsm48_mmr_reg_req(struct osmocom_ms *ms)
4085 {
4086         struct gsm48_mmlayer *mm = &ms->mmlayer;
4087         struct msgb *nmsg;
4088
4089         /* schedule insertion of SIM */
4090         nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_INSERT);
4091         if (!nmsg)
4092                 return -ENOMEM;
4093         gsm322_plmn_sendmsg(ms, nmsg);
4094
4095         /* 4.2.1.2 SIM is inserted in state NO IMSI */
4096         if (mm->state == GSM48_MM_ST_MM_IDLE
4097          && mm->substate == GSM48_MM_SST_NO_IMSI)
4098                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
4099                         gsm48_mm_set_plmn_search(ms));
4100
4101         return 0;
4102 }
4103
4104 /* trigger detach of sim card */
4105 static int gsm48_mmr_nreg_req(struct osmocom_ms *ms)
4106 {
4107         struct gsm48_mmlayer *mm = &ms->mmlayer;
4108         struct msgb *nmsg;
4109
4110         nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
4111         if (!nmsg)
4112                 return -ENOMEM;
4113         gsm48_mmevent_msg(mm->ms, nmsg);
4114
4115         return 0;
4116 }
4117
4118 static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg)
4119 {
4120         struct gsm48_mmr *mmr = (struct gsm48_mmr *)msg->data;
4121         int msg_type = mmr->msg_type;
4122         int rc = 0;
4123
4124         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event\n", ms->name,
4125                 get_mmr_name(msg_type));
4126         switch(msg_type) {
4127                 case GSM48_MMR_REG_REQ:
4128                         rc = gsm48_mmr_reg_req(ms);
4129                         break;
4130                 case GSM48_MMR_NREG_REQ:
4131                         rc = gsm48_mmr_nreg_req(ms);
4132                         break;
4133                 default:
4134                         LOGP(DMM, LOGL_NOTICE, "Message unhandled.\n");
4135         }
4136
4137         return rc;
4138 }
4139
4140