68231273c4b78fa1bbe187f856a063d8d88b1bb2
[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 = 0xffffffff;
1493                 LOGP(DMM, LOGL_INFO, "TMSI removed.\n");
1494                 gsm48_mm_tx_tmsi_reall_cpl(ms);
1495                 break;
1496         default:
1497                 subscr->tmsi = 0xffffffff;
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                 LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
1716         } else {
1717                 gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_IMSI);
1718                 LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
1719         }
1720
1721         /* push RR header and send down */
1722         mm->est_cause = RR_EST_CAUSE_OTHER_SDCCH;
1723         return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
1724 }
1725
1726 /* detach has ended */
1727 static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
1728 {
1729         struct gsm48_mmlayer *mm = &ms->mmlayer;
1730         struct gsm_subscriber *subscr = &ms->subscr;
1731         struct msgb *nmsg;
1732
1733         LOGP(DMM, LOGL_INFO, "IMSI has been detached.\n");
1734
1735         /* stop IMSI detach timer (if running) */
1736         stop_mm_t3220(mm);
1737
1738
1739         /* SIM invalid */
1740         subscr->sim_valid = 0;
1741
1742         /* wait for RR idle and then power off when IMSI is detached */
1743         if (mm->power_off) {
1744                 if (mm->state == GSM48_MM_ST_MM_IDLE) {
1745                         l23_app_exit(ms);
1746                         exit(0);
1747                 }
1748                 mm->power_off_idle = 1;
1749
1750                 return 0;
1751         }
1752
1753         /* send SIM remove event to gsm322 */
1754         nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
1755         if (!nmsg)
1756                 return -ENOMEM;
1757         gsm322_plmn_sendmsg(ms, nmsg);
1758
1759         /* CS process will trigger return to MM IDLE / No SIM */
1760         return 0;
1761 }
1762
1763 /* start an IMSI detach in MM IDLE */
1764 static int gsm48_mm_imsi_detach_start(struct osmocom_ms *ms, struct msgb *msg)
1765 {
1766         struct gsm_subscriber *subscr = &ms->subscr;
1767         struct gsm48_mmlayer *mm = &ms->mmlayer;
1768         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1769
1770         /* we may silently finish IMSI detach */
1771         if (!s->att_allowed || !subscr->imsi_attached) {
1772                 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1773
1774                 return gsm48_mm_imsi_detach_end(ms, msg);
1775         }
1776         LOGP(DMM, LOGL_INFO, "IMSI detach started (MM IDLE)\n");
1777
1778         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
1779
1780         /* establish RR and send IMSI detach */
1781         return gsm48_mm_tx_imsi_detach(ms, GSM48_RR_EST_REQ);
1782 }
1783
1784 /* IMSI detach has been sent, wait for RR release */
1785 static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, struct msgb *msg)
1786 {
1787         struct gsm48_mmlayer *mm = &ms->mmlayer;
1788
1789         /* start T3220 (4.3.4.1) */
1790         start_mm_t3220(mm);
1791
1792         LOGP(DMM, LOGL_INFO, "IMSI detach started (Wait for RR release)\n");
1793
1794         new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
1795
1796         return 0;
1797 }
1798         
1799 /* release MM connection and proceed with IMSI detach */
1800 static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
1801 {
1802         struct gsm_subscriber *subscr = &ms->subscr;
1803         struct gsm48_mmlayer *mm = &ms->mmlayer;
1804         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1805
1806         /* stop MM connection timer */
1807         stop_mm_t3230(mm);
1808
1809         /* release all connections */
1810         gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1811
1812         /* wait for release of RR */
1813         if (!s->att_allowed || !subscr->imsi_attached) {
1814                 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1815                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
1816
1817                 /* power off */
1818                 if (mm->power_off) {
1819                         l23_app_exit(ms);
1820                         exit(0);
1821                 }
1822
1823                 return 0;
1824         }
1825
1826         /* send IMSI detach */
1827         gsm48_mm_tx_imsi_detach(ms, GSM48_RR_DATA_REQ);
1828
1829         /* go to sent state */
1830         return gsm48_mm_imsi_detach_sent(ms, msg);
1831 }
1832
1833 /* ignore ongoing IMSI detach */
1834 static int gsm48_mm_imsi_detach_ignore(struct osmocom_ms *ms, struct msgb *msg)
1835 {
1836         return 0;
1837 }
1838
1839 /* delay until state change (and then retry) */
1840 static int gsm48_mm_imsi_detach_delay(struct osmocom_ms *ms, struct msgb *msg)
1841 {
1842         struct gsm48_mmlayer *mm = &ms->mmlayer;
1843
1844         LOGP(DMM, LOGL_INFO, "IMSI detach delayed.\n");
1845
1846         /* remember to detach later */
1847         mm->delay_detach = 1;
1848
1849         return 0;
1850 }
1851
1852 /* 4.3.5.2 ABORT is received */
1853 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
1854 {
1855         struct gsm48_mmlayer *mm = &ms->mmlayer;
1856         struct gsm_subscriber *subscr = &ms->subscr;
1857         struct gsm48_hdr *gh = msgb_l3(msg);
1858         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1859         uint8_t reject_cause;
1860
1861         if (payload_len < 1) {
1862                 LOGP(DMM, LOGL_NOTICE, "Short read of ABORT message error.\n");
1863                 return -EINVAL;
1864         }
1865
1866         reject_cause = *gh->data;
1867
1868         if (llist_empty(&mm->mm_conn)) {
1869                 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while no MM "
1870                         "connection is established.\n", reject_cause);
1871                 return gsm48_mm_tx_mm_status(ms,
1872                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
1873         } else {
1874                 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while MM connection "
1875                         "is established.\n", reject_cause);
1876                 /* stop MM connection timer */
1877                 stop_mm_t3230(mm);
1878
1879                 gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1880         }
1881
1882         if (reject_cause == GSM48_REJECT_ILLEGAL_ME) { 
1883                 /* SIM invalid */
1884                 subscr->sim_valid = 0;
1885
1886                 /* TMSI and LAI invalid */
1887                 subscr->tmsi = 0xffffffff;
1888                 subscr->lac = 0x0000;
1889
1890                 /* key is invalid */
1891                 subscr->key_seq = 7;
1892
1893                 /* update status */
1894                 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
1895
1896                 /* store LOCI on sim */
1897                 gsm_subscr_write_loci(ms);
1898
1899                 /* CS process will trigger: return to MM IDLE / No SIM */
1900                 return 0;
1901         }
1902
1903         return 0;
1904 }
1905
1906 /* 4.3.6.2 MM INFORMATION is received */
1907 static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
1908 {
1909         struct gsm48_mmlayer *mm = &ms->mmlayer;
1910         struct gsm48_hdr *gh = msgb_l3(msg);
1911         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1912         struct tlv_parsed tp;
1913
1914         if (payload_len < 0) {
1915                 LOGP(DMM, LOGL_NOTICE, "Short read of MM INFORMATION message "
1916                         "error.\n");
1917                 return -EINVAL;
1918         }
1919         tlv_parse(&tp, &gsm48_mm_att_tlvdef, gh->data, payload_len, 0, 0);
1920
1921         /* long name */
1922         if (TLVP_PRESENT(&tp, GSM48_IE_NAME_LONG)) {
1923                 decode_network_name(mm->name_long, sizeof(mm->name_long),
1924                                 TLVP_VAL(&tp, GSM48_IE_NAME_LONG)-1);
1925         }
1926         /* short name */
1927         if (TLVP_PRESENT(&tp, GSM48_IE_NAME_SHORT)) {
1928                 decode_network_name(mm->name_short, sizeof(mm->name_short),
1929                                 TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)-1);
1930         }
1931
1932         return 0;
1933 }
1934
1935 /*
1936  * process handlers for Location Update + IMSI attach (MM specific procedures)
1937  */
1938
1939 /* 4.4.2 received sysinfo change event */
1940 static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
1941 {
1942         struct gsm48_mmlayer *mm = &ms->mmlayer;
1943         struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1944
1945         /* t3212 not changed in these states */ 
1946         if (mm->state == GSM48_MM_ST_MM_IDLE
1947          && (mm->substate == GSM48_MM_SST_NO_CELL_AVAIL
1948           || mm->substate == GSM48_MM_SST_LIMITED_SERVICE
1949           || mm->substate == GSM48_MM_SST_PLMN_SEARCH
1950           || mm->substate == GSM48_MM_SST_PLMN_SEARCH_NORMAL))
1951                 return 0;
1952
1953         /* new periodic location update timer timeout */
1954         if (s->t3212 && s->t3212 != mm->t3212_value) {
1955                 if (bsc_timer_pending(&mm->t3212)) {
1956                         int t;
1957                         struct timeval current_time;
1958
1959                         /* get rest time */
1960                         gettimeofday(&current_time, NULL);
1961                         t = mm->t3212.timeout.tv_sec - current_time.tv_sec;
1962                         if (t < 0)
1963                                 t = 0;
1964                         LOGP(DMM, LOGL_INFO, "New T3212 while timer is running "
1965                                 "(value %d rest %d)\n", s->t3212, t);
1966
1967                         /* rest time modulo given value */
1968                         mm->t3212.timeout.tv_sec = current_time.tv_sec
1969                                 + (t % s->t3212);
1970                 } else {
1971                         uint32_t rand = random();
1972
1973                         LOGP(DMM, LOGL_INFO, "New T3212 while timer is not "
1974                                 "running (value %d)\n", s->t3212);
1975
1976                         /* value between 0 and given value */
1977                         start_mm_t3212(mm, rand % (s->t3212 + 1));
1978                 }
1979                 mm->t3212_value = s->t3212;
1980         }
1981         
1982         return 0;
1983 }
1984
1985 /* 4.4.4.1 (re)start location update
1986  *
1987  * this function is called by
1988  * - normal location update
1989  * - periodic location update
1990  * - imsi attach (normal loc. upd. function)
1991  * - retry timers (T3211 and T3213)
1992  */
1993 static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
1994 {
1995         struct gsm48_mmlayer *mm = &ms->mmlayer;
1996         struct gsm322_cellsel *cs = &ms->cellsel;
1997         struct gsm48_sysinfo *s = &cs->sel_si;
1998         struct gsm_subscriber *subscr = &ms->subscr;
1999         struct gsm_settings *set = &ms->settings;
2000         struct msgb *nmsg;
2001         int msg_type;
2002         
2003         /* (re)start only if we still require location update */
2004         if (!mm->lupd_pending) {
2005                 LOGP(DMM, LOGL_INFO, "No loc. upd. pending.\n");
2006                 return 0;
2007         }
2008
2009         /* must camp normally */
2010         if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2011                 LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
2012                 msg_type = GSM322_EVENT_REG_FAILED;
2013                 stop:
2014                 LOGP(DSUM, LOGL_INFO, "Location updating not possible\n");
2015                 _stop:
2016                 mm->lupd_pending = 0;
2017                 /* send message to PLMN search process */
2018                 nmsg = gsm322_msgb_alloc(msg_type);
2019                 if (!nmsg)
2020                         return -ENOMEM;
2021                 gsm322_plmn_sendmsg(ms, nmsg);
2022                 return 0;
2023         }
2024
2025         /* deny network, if disabled */
2026         if (set->no_lupd) {
2027                 LOGP(DMM, LOGL_INFO, "Loc. upd. disabled, adding "
2028                         "forbidden PLMN.\n");
2029                 LOGP(DSUM, LOGL_INFO, "Location updating is disabled by "
2030                         "configuration\n");
2031                 gsm_subscr_add_forbidden_plmn(subscr, cs->sel_mcc,
2032                         cs->sel_mnc, GSM48_REJECT_PLMN_NOT_ALLOWED);
2033                 msg_type = GSM322_EVENT_ROAMING_NA;
2034                 goto _stop;
2035         }
2036
2037         /* if LAI is forbidden, don't start */
2038         if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
2039                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
2040                 msg_type = GSM322_EVENT_ROAMING_NA;
2041                 goto stop;
2042         }
2043         if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
2044                 cs->sel_mnc, cs->sel_lac)) {
2045                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
2046                 msg_type = GSM322_EVENT_ROAMING_NA;
2047                 goto stop;
2048         }
2049
2050         /* 4.4.4.9 if cell is barred, don't start */
2051         if ((!subscr->acc_barr && s->cell_barr)
2052          || (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
2053                                         (s->class_barr ^ 0xffff)))) {
2054                 LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
2055                 msg_type = GSM322_EVENT_ROAMING_NA;
2056                 goto stop;
2057         }
2058
2059         mm->lupd_mcc = cs->sel_mcc;
2060         mm->lupd_mnc = cs->sel_mnc;
2061         mm->lupd_lac = cs->sel_lac;
2062
2063         LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %s, MNC %s "
2064                 "LAC 0x%04x)\n", gsm_print_mcc(mm->lupd_mcc),
2065                 gsm_print_mnc(mm->lupd_mnc), mm->lupd_lac);
2066
2067         return gsm48_mm_tx_loc_upd_req(ms);
2068 }
2069
2070 /* initiate a normal location update / imsi attach */
2071 static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg)
2072 {
2073         struct gsm48_mmlayer *mm = &ms->mmlayer;
2074         struct gsm_subscriber *subscr = &ms->subscr;
2075         struct gsm322_cellsel *cs = &ms->cellsel;
2076         struct gsm48_sysinfo *s = &cs->sel_si;
2077         struct msgb *nmsg;
2078
2079         /* in case we already have a location update going on */
2080         if (mm->lupd_pending) {
2081                 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2082
2083                 return -EBUSY;
2084         }
2085
2086         /* no location update, if limited service */
2087         if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2088                 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed.\n");
2089
2090                 /* send message to PLMN search process */
2091                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2092                 if (!nmsg)
2093                         return -ENOMEM;
2094                 gsm322_plmn_sendmsg(ms, nmsg);
2095
2096                 return 0;
2097         }
2098
2099         /* if location update is not required */
2100         if (subscr->ustate == GSM_SIM_U1_UPDATED
2101          && cs->selected
2102          && cs->sel_mcc == subscr->mcc
2103          && cs->sel_mnc == subscr->mnc
2104          && cs->sel_lac == subscr->lac
2105          && (subscr->imsi_attached
2106           || !s->att_allowed)) {
2107                 LOGP(DMM, LOGL_INFO, "Loc. upd. not required.\n");
2108                 subscr->imsi_attached = 1;
2109
2110                 /* send message to PLMN search process */
2111                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2112                 if (!nmsg)
2113                         return -ENOMEM;
2114                 gsm322_plmn_sendmsg(ms, nmsg);
2115
2116                 return 0;
2117         }
2118
2119         /* 4.4.3 is attachment required? */
2120         if (subscr->ustate == GSM_SIM_U1_UPDATED
2121          && cs->selected
2122          && cs->sel_mcc == subscr->mcc
2123          && cs->sel_mnc == subscr->mnc
2124          && cs->sel_lac == subscr->lac
2125          && !subscr->imsi_attached
2126          && s->att_allowed) {
2127                 /* do location update for IMSI attach */
2128                 LOGP(DMM, LOGL_INFO, "Do Loc. upd. for IMSI attach.\n");
2129                 mm->lupd_type = 2;
2130         } else {
2131                 /* do normal location update */
2132                 LOGP(DMM, LOGL_INFO, "Do normal Loc. upd.\n");
2133                 mm->lupd_type = 0;
2134         }
2135
2136         /* start location update */
2137         mm->lupd_attempt = 0;
2138         mm->lupd_pending = 1;
2139         mm->lupd_ra_failure = 0;
2140
2141         return gsm48_mm_loc_upd(ms, msg);
2142 }
2143
2144 /* initiate a periodic location update */
2145 static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg)
2146 {
2147         struct gsm48_mmlayer *mm = &ms->mmlayer;
2148
2149         /* in case we already have a location update going on */
2150         if (mm->lupd_pending) {
2151                 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2152                 return -EBUSY;
2153         }
2154
2155         /* start periodic location update */
2156         mm->lupd_type = 1;
2157         mm->lupd_pending = 1;
2158         mm->lupd_ra_failure = 0;
2159
2160         return gsm48_mm_loc_upd(ms, msg);
2161 }
2162
2163 /* ignore location update */
2164 static int gsm48_mm_loc_upd_ignore(struct osmocom_ms *ms, struct msgb *msg)
2165 {
2166         return 0;
2167 }
2168
2169 /* 9.2.15 send LOCATION UPDATING REQUEST message */
2170 static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
2171 {
2172         struct gsm48_mmlayer *mm = &ms->mmlayer;
2173         struct gsm_support *sup = &ms->support;
2174         struct gsm_subscriber *subscr = &ms->subscr;
2175         struct gsm48_rrlayer *rr = &ms->rrlayer;
2176         struct msgb *nmsg;
2177         struct gsm48_hdr *ngh;
2178         struct gsm48_loc_upd_req *nlu; /* NOTE: mi_len is part of struct */
2179         uint8_t pwr_lev;
2180         uint8_t buf[11];
2181
2182         LOGP(DMM, LOGL_INFO, "LOCATION UPDATING REQUEST\n");
2183
2184         nmsg = gsm48_l3_msgb_alloc();
2185         if (!nmsg)
2186                 return -ENOMEM;
2187         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2188         nlu = (struct gsm48_loc_upd_req *)msgb_put(nmsg, sizeof(*nlu));
2189
2190         ngh->proto_discr = GSM48_PDISC_MM;
2191         ngh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
2192
2193         /* location updating type */
2194         nlu->type = mm->lupd_type;
2195         /* cipering key */
2196         nlu->key_seq = subscr->key_seq;
2197         /* LAI (last SIM stored LAI)
2198          *
2199          * NOTE: The TMSI is only valid within a LAI!
2200          */
2201         gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
2202         /* classmark 1 */
2203         if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
2204                 pwr_lev = sup->pwr_lev_1800;
2205         else
2206                 pwr_lev = sup->pwr_lev_900;
2207         gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind,
2208                 sup->a5_1, pwr_lev);
2209         /* MI */
2210         if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
2211                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2212                 LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
2213         } else {
2214                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2215                 LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
2216         }
2217         msgb_put(nmsg, buf[1]); /* length is part of nlu */
2218         memcpy(&nlu->mi_len, buf + 1, 1 + buf[1]);
2219
2220         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
2221
2222         /* push RR header and send down */
2223         mm->est_cause = RR_EST_CAUSE_LOC_UPD;
2224         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, mm->est_cause);
2225 }
2226
2227 /* 4.4.4.1 RR is esablised during location update */
2228 static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
2229 {
2230         struct gsm48_mmlayer *mm = &ms->mmlayer;
2231
2232         /* start location update timer */
2233         start_mm_t3210(mm);
2234
2235         new_mm_state(mm, GSM48_MM_ST_LOC_UPD_INIT, 0);
2236
2237         return 0;
2238 }
2239
2240 /* 4.4.4.6 LOCATION UPDATING ACCEPT is received */
2241 static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
2242 {
2243         struct gsm48_mmlayer *mm = &ms->mmlayer;
2244         struct gsm_subscriber *subscr = &ms->subscr;
2245         struct gsm48_hdr *gh = msgb_l3(msg);
2246         struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
2247         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2248         struct tlv_parsed tp;
2249         struct msgb *nmsg;
2250
2251         if (payload_len < sizeof(struct gsm48_loc_area_id)) {
2252                 short_read:
2253                 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING ACCEPT "
2254                         "message error.\n");
2255                 return -EINVAL;
2256         }
2257         tlv_parse(&tp, &gsm48_mm_att_tlvdef,
2258                 gh->data + sizeof(struct gsm48_loc_area_id),
2259                 payload_len - sizeof(struct gsm48_loc_area_id), 0, 0);
2260
2261         /* update has finished */
2262         mm->lupd_pending = 0;
2263
2264         /* RA was successfull */
2265         mm->lupd_ra_failure = 0;
2266
2267         /* stop periodic location updating timer */
2268         stop_mm_t3212(mm); /* 4.4.2 */
2269
2270         /* LAI */
2271         gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
2272
2273         /* stop location update timer */
2274         stop_mm_t3210(mm);
2275
2276         /* reset attempt counter */
2277         mm->lupd_attempt = 0;
2278
2279         /* mark SIM as attached */
2280         subscr->imsi_attached = 1;
2281
2282         /* set the status in the sim to updated */
2283         new_sim_ustate(subscr, GSM_SIM_U1_UPDATED);
2284
2285         /* store LOCI on sim */
2286         gsm_subscr_write_loci(ms);
2287
2288         /* set last registered PLMN */
2289         if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
2290                 subscr->plmn_valid = 1;
2291                 subscr->plmn_mcc = subscr->mcc;
2292                 subscr->plmn_mnc = subscr->mnc;
2293         }
2294
2295         LOGP(DSUM, LOGL_INFO, "Location update accepted\n");
2296         LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %s mnc %s "
2297                 "lac 0x%04x)\n", gsm_print_mcc(subscr->mcc),
2298                 gsm_print_mnc(subscr->mnc), subscr->lac);
2299
2300         /* remove LA from forbidden list */
2301         gsm322_del_forbidden_la(ms, subscr->mcc, subscr->mnc, subscr->lac);
2302
2303         /* MI */
2304         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
2305                 const uint8_t *mi;
2306                 uint8_t mi_type;
2307                 uint32_t tmsi;
2308
2309                 mi = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)-1;
2310                 if (mi[0] < 1)
2311                         goto short_read;
2312                 mi_type = mi[1] & GSM_MI_TYPE_MASK;
2313                 switch (mi_type) {
2314                 case GSM_MI_TYPE_TMSI:
2315                         if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
2316                          || mi[0] < 5)
2317                                 goto short_read;
2318                         memcpy(&tmsi, mi+2, 4);
2319                         subscr->tmsi = ntohl(tmsi);
2320                         LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x (%u)\n",
2321                                 subscr->tmsi, subscr->tmsi);
2322
2323                         /* store LOCI on sim */
2324                         gsm_subscr_write_loci(ms);
2325
2326                         /* send TMSI REALLOCATION COMPLETE */
2327                         gsm48_mm_tx_tmsi_reall_cpl(ms);
2328                         break;
2329                 case GSM_MI_TYPE_IMSI:
2330                         LOGP(DMM, LOGL_INFO, "TMSI removed\n");
2331                         subscr->tmsi = 0xffffffff;
2332
2333                         /* store LOCI on sim */
2334                         gsm_subscr_write_loci(ms);
2335
2336                         /* send TMSI REALLOCATION COMPLETE */
2337                         gsm48_mm_tx_tmsi_reall_cpl(ms);
2338                         break;
2339                 default:
2340                         LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown "
2341                                 "MI type %d.\n", mi_type);
2342                 }
2343         }
2344
2345         /* send message to PLMN search process */
2346         nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2347         if (!nmsg)
2348                 return -ENOMEM;
2349         gsm322_plmn_sendmsg(ms, nmsg);
2350
2351         /* follow on proceed */
2352         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID))
2353                 LOGP(DMM, LOGL_NOTICE, "follow-on proceed not supported.\n");
2354
2355         /* start RR release timer */
2356         start_mm_t3240(mm);
2357
2358         new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2359
2360         return 0;
2361 }
2362
2363 /* 4.4.4.7 LOCATION UPDATING REJECT is received */
2364 static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2365 {
2366         struct gsm48_mmlayer *mm = &ms->mmlayer;
2367         struct gsm48_hdr *gh = msgb_l3(msg);
2368         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2369
2370         if (payload_len < 1) {
2371                 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING REJECT "
2372                         "message error.\n");
2373                 return -EINVAL;
2374         }
2375
2376         /* RA was successfull */
2377         mm->lupd_ra_failure = 0;
2378
2379         /* stop periodic location updating timer */
2380         stop_mm_t3212(mm); /* 4.4.2 */
2381
2382         /* stop location update timer */
2383         stop_mm_t3210(mm);
2384
2385         /* store until RR is released */
2386         mm->lupd_rej_cause = *gh->data;
2387
2388         /* start RR release timer */
2389         start_mm_t3240(mm);
2390
2391         new_mm_state(mm, GSM48_MM_ST_LOC_UPD_REJ, 0);
2392         
2393         return 0;
2394 }
2395
2396 /* 4.4.4.7 RR is released after location update reject */
2397 static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2398 {
2399         struct gsm48_mmlayer *mm = &ms->mmlayer;
2400         struct gsm_subscriber *subscr = &ms->subscr;
2401         struct msgb *nmsg;
2402         struct gsm322_msg *ngm;
2403         
2404         LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n",
2405                 mm->lupd_rej_cause);
2406
2407         /* stop RR release timer */
2408         stop_mm_t3240(mm);
2409
2410         /* new status */
2411         switch (mm->lupd_rej_cause) {
2412         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2413         case GSM48_REJECT_ILLEGAL_MS:
2414         case GSM48_REJECT_ILLEGAL_ME:
2415                 /* reset attempt counter */
2416                 mm->lupd_attempt = 0;
2417
2418                 /* SIM invalid */
2419                 subscr->sim_valid = 0;
2420
2421                 // fall through
2422         case GSM48_REJECT_PLMN_NOT_ALLOWED:
2423         case GSM48_REJECT_LOC_NOT_ALLOWED:
2424         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2425                 /* TMSI and LAI invalid */
2426                 subscr->tmsi = 0xffffffff;
2427                 subscr->lac = 0x0000;
2428
2429                 /* key is invalid */
2430                 subscr->key_seq = 7;
2431
2432                 /* update status */
2433                 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
2434
2435                 /* store LOCI on sim */
2436                 gsm_subscr_write_loci(ms);
2437
2438                 /* update has finished */
2439                 mm->lupd_pending = 0;
2440         }
2441
2442         /* send event to PLMN search process */
2443         switch(mm->lupd_rej_cause) {
2444         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2445                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
2446                 break;
2447         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2448         case GSM48_REJECT_ILLEGAL_MS:
2449         case GSM48_REJECT_ILLEGAL_ME:
2450                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM);
2451                 break;
2452         default:
2453                 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2454         }
2455         if (!nmsg)
2456                 return -ENOMEM;
2457         ngm = (struct gsm322_msg *)nmsg->data;
2458         ngm->reject = mm->lupd_rej_cause;
2459         gsm322_plmn_sendmsg(ms, nmsg);
2460
2461         /* forbidden list */
2462         switch (mm->lupd_rej_cause) {
2463         case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2464                 LOGP(DSUM, LOGL_INFO, "Location update failed (IMSI unknown "
2465                         "in HLR)\n");
2466                 break;
2467         case GSM48_REJECT_ILLEGAL_MS:
2468                 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal MS)\n");
2469                 break;
2470         case GSM48_REJECT_ILLEGAL_ME:
2471                 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n");
2472                 break;
2473         case GSM48_REJECT_PLMN_NOT_ALLOWED:
2474                 gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc,
2475                         mm->lupd_mnc, mm->lupd_rej_cause);
2476                 LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not "
2477                         "allowed)\n");
2478                 break;
2479         case GSM48_REJECT_LOC_NOT_ALLOWED:
2480         case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2481                 gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc,
2482                         mm->lupd_lac, mm->lupd_rej_cause);
2483                 LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not "
2484                         "allowed)\n");
2485                 break;
2486         default:
2487                 /* 4.4.4.9 continue with failure handling */
2488                 return gsm48_mm_loc_upd_failed(ms, NULL);
2489         }
2490
2491         /* CS proc triggers: return to IDLE, case 13 is also handled there */
2492         return 0;
2493 }
2494
2495 /* 4.2.2 delay a location update */
2496 static int gsm48_mm_loc_upd_delay_per(struct osmocom_ms *ms, struct msgb *msg)
2497 {
2498         struct gsm48_mmlayer *mm = &ms->mmlayer;
2499
2500         LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2501         mm->lupd_periodic = 1;
2502
2503         return 0;
2504 }
2505
2506 /* delay a location update retry */
2507 static int gsm48_mm_loc_upd_delay_retry(struct osmocom_ms *ms, struct msgb *msg)
2508 {
2509         struct gsm48_mmlayer *mm = &ms->mmlayer;
2510
2511         LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2512         mm->lupd_retry = 1;
2513
2514         return 0;
2515 }
2516
2517 /* process failues as described in the lower part of 4.4.4.9 */
2518 static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
2519 {
2520         struct gsm48_mmlayer *mm = &ms->mmlayer;
2521         struct gsm_subscriber *subscr = &ms->subscr;
2522
2523         LOGP(DSUM, LOGL_INFO, "Location update failed\n");
2524
2525         /* stop location update timer, if running */
2526         stop_mm_t3210(mm);
2527
2528         if (subscr->ustate == GSM_SIM_U1_UPDATED
2529          && mm->lupd_mcc == subscr->mcc
2530          && mm->lupd_mnc == subscr->mnc
2531          && mm->lupd_lac == subscr->lac) {
2532                 if (mm->lupd_attempt < 4) {
2533                         LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2534                         LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
2535                                 mm->lupd_attempt);
2536
2537                         /* start update retry timer */
2538                         start_mm_t3211(mm);
2539
2540                         /* CS process will trigger: return to MM IDLE */
2541                         return 0;
2542                 } else
2543                         LOGP(DMM, LOGL_INFO, "Loc. upd. failed too often.\n");
2544         }
2545
2546         /* TMSI and LAI invalid */
2547         subscr->tmsi = 0xffffffff;
2548         subscr->lac = 0x0000;
2549
2550         /* key is invalid */
2551         subscr->key_seq = 7;
2552
2553         /* update status */
2554         new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2555
2556         /* store LOCI on sim */
2557         gsm_subscr_write_loci(ms);
2558
2559         /* start update retry timer (RR connection is released) */
2560         if (mm->lupd_attempt < 4) {
2561                 mm->start_t3211 = 1;
2562                 LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2563         }
2564
2565         /* CS process will trigger: return to MM IDLE */
2566         return 0;
2567 }
2568
2569 /* abort a location update due to radio failure or release */
2570 static int gsm48_mm_rel_loc_upd_abort(struct osmocom_ms *ms, struct msgb *msg)
2571 {
2572         struct gsm48_mmlayer *mm = &ms->mmlayer;
2573         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
2574
2575         /* stop RR release timer */
2576         stop_mm_t3240(mm);
2577
2578         if (rrh->msg_type == GSM48_RR_REL_IND) {
2579                 LOGP(DMM, LOGL_INFO, "RR link released after loc. upd.\n");
2580
2581                 /* continue with failure handling */
2582                 return gsm48_mm_loc_upd_failed(ms, NULL);
2583         }
2584
2585         LOGP(DMM, LOGL_INFO, "Loc. upd. aborted by radio (cause #%d)\n",
2586                 rrh->cause);
2587
2588         /* random access failure, but not two successive failures */
2589         if (rrh->cause == RR_REL_CAUSE_RA_FAILURE && !mm->lupd_ra_failure) {
2590                 mm->lupd_ra_failure = 1;
2591
2592                 /* start RA failure timer */
2593                 start_mm_t3213(mm);
2594
2595                 return 0;
2596         }
2597
2598         /* RA was successfull or sent twice */
2599         mm->lupd_ra_failure = 0;
2600
2601         /* continue with failure handling */
2602         return gsm48_mm_loc_upd_failed(ms, NULL);
2603 }
2604
2605 /* location update has timed out */
2606 static int gsm48_mm_loc_upd_timeout(struct osmocom_ms *ms, struct msgb *msg)
2607 {
2608         struct msgb *nmsg;
2609         struct gsm48_rr_hdr *nrrh;
2610
2611         /* abort RR connection */
2612         nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
2613         if (!nmsg)
2614                 return -ENOMEM;
2615         nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
2616         nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
2617         gsm48_rr_downmsg(ms, nmsg);
2618
2619         /* continue with failure handling */
2620         return gsm48_mm_loc_upd_failed(ms, NULL);
2621 }
2622
2623 /*
2624  * process handlers for MM connections
2625  */
2626
2627 /* cm reestablish request message from upper layer */
2628 static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
2629         uint8_t cm_serv)
2630 {
2631         struct gsm48_mmlayer *mm = &ms->mmlayer;
2632         struct gsm_subscriber *subscr = &ms->subscr;
2633         struct gsm_settings *set = &ms->settings;
2634         struct msgb *nmsg;
2635         struct gsm48_hdr *ngh;
2636         struct gsm48_service_request *nsr; /* NOTE: includes MI length */
2637         uint8_t *cm2lv;
2638         uint8_t buf[11];
2639
2640         LOGP(DMM, LOGL_INFO, "CM SERVICE REQUEST (cause %d)\n", mm->est_cause);
2641
2642         nmsg = gsm48_l3_msgb_alloc();
2643         if (!nmsg)
2644                 return -ENOMEM;
2645         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2646         nsr = (struct gsm48_service_request *)msgb_put(nmsg, sizeof(*nsr));
2647         cm2lv = (uint8_t *)&nsr->classmark;
2648
2649         ngh->proto_discr = GSM48_PDISC_MM;
2650         ngh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
2651
2652         /* type and key */
2653         nsr->cm_service_type = cm_serv;
2654         nsr->cipher_key_seq = subscr->key_seq;
2655         /* classmark 2 */
2656         cm2lv[0] = sizeof(struct gsm48_classmark2);
2657         gsm48_rr_enc_cm2(ms, (struct gsm48_classmark2 *)(cm2lv + 1));
2658         /* MI */
2659         if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0]) {
2660                 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s for emergency\n",
2661                         set->emergency_imsi);
2662                 gsm48_generate_mid_from_imsi(buf, set->emergency_imsi);
2663         } else
2664         if (!subscr->sim_valid) { /* have no SIM ? */
2665                 LOGP(DMM, LOGL_INFO, "-> Using IMEI %s\n",
2666                         set->imei);
2667                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMEI);
2668         } else
2669         if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
2670                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2671                 LOGP(DMM, LOGL_INFO, "-> Using TMSI\n");
2672         } else {
2673                 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2674                 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s\n",
2675                         subscr->imsi);
2676         }
2677         msgb_put(nmsg, buf[1]); /* length is part of nsr */
2678         memcpy(&nsr->mi_len, buf + 1, 1 + buf[1]);
2679         /* prio is optional for eMLPP */
2680
2681         /* push RR header and send down */
2682         return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
2683 }
2684
2685 /* cm service abort message from upper layer
2686  * NOTE: T3240 is started by the calling function
2687  */
2688 static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms)
2689 {
2690         struct msgb *nmsg;
2691         struct gsm48_hdr *ngh;
2692
2693         LOGP(DMM, LOGL_INFO, "CM SERVICE ABORT\n");
2694
2695         nmsg = gsm48_l3_msgb_alloc();
2696         if (!nmsg)
2697                 return -ENOMEM;
2698         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2699
2700         ngh->proto_discr = GSM48_PDISC_MM;
2701         ngh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
2702
2703         /* push RR header and send down */
2704         return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
2705 }
2706
2707 /* cm service acknowledge is received from lower layer */
2708 static int gsm48_mm_rx_cm_service_acc(struct osmocom_ms *ms, struct msgb *msg)
2709 {
2710         struct gsm48_mmlayer *mm = &ms->mmlayer;
2711
2712         /* stop MM connection timer */
2713         stop_mm_t3230(mm);
2714
2715         new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2716
2717         return gsm48_mm_conn_go_dedic(ms);
2718 }
2719
2720 /* 9.2.6 CM SERVICE REJECT message received */
2721 static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
2722 {
2723         struct gsm48_mmlayer *mm = &ms->mmlayer;
2724         struct gsm_subscriber *subscr = &ms->subscr;
2725         struct gsm48_hdr *gh = msgb_l3(msg);
2726         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2727         uint8_t abort_any = 0;
2728         uint8_t reject_cause;
2729
2730         if (payload_len < 1) {
2731                 LOGP(DMM, LOGL_NOTICE, "Short read of cm service reject "
2732                         "message error.\n");
2733                 return -EINVAL;
2734         }
2735
2736         /* reject cause */
2737         reject_cause = *gh->data;
2738
2739         LOGP(DMM, LOGL_INFO, "CM SERVICE REJECT (cause %d)\n", reject_cause);
2740
2741         /* stop MM connection timer */
2742         stop_mm_t3230(mm);
2743
2744         /* selection action on cause value */
2745         switch (reject_cause) {
2746         case GSM48_REJECT_IMSI_UNKNOWN_IN_VLR:
2747         case GSM48_REJECT_ILLEGAL_ME:
2748                 abort_any = 1;
2749
2750                 /* TMSI and LAI invalid */
2751                 subscr->tmsi = 0xffffffff;
2752                 subscr->lac = 0x0000;
2753
2754                 /* key is invalid */
2755                 subscr->key_seq = 7;
2756
2757                 /* update status */
2758                 new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2759
2760                 /* store LOCI on sim */
2761                 gsm_subscr_write_loci(ms);
2762
2763                 /* change to WAIT_NETWORK_CMD state impied by abort_any == 1 */
2764
2765                 if (reject_cause == GSM48_REJECT_ILLEGAL_ME)
2766                         subscr->sim_valid = 0;
2767
2768                 break;
2769         default:
2770                 /* state implied by the number of remaining connections */
2771                 ;
2772         }
2773
2774         /* release MM connection(s) */
2775         gsm48_mm_release_mm_conn(ms, abort_any, 16, 0);
2776
2777         /* state depends on the existance of remaining MM connections */
2778         if (llist_empty(&mm->mm_conn))
2779                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2780         else
2781                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2782
2783         return 0;
2784 }
2785
2786 /* initiate an MM connection 4.5.1.1
2787  *
2788  * this function is called when:
2789  * - no RR connection exists
2790  * - an RR connection exists, but this is the first MM connection
2791  * - an RR connection exists, and there are already MM connection(s)
2792  */
2793 static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
2794         int rr_prim)
2795 {
2796         struct gsm48_mmlayer *mm = &ms->mmlayer;
2797         struct gsm_subscriber *subscr = &ms->subscr;
2798         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
2799         int msg_type = mmh->msg_type;
2800         int emergency = 0;
2801         uint8_t cause = 0, cm_serv = 0, proto = 0;
2802         struct msgb *nmsg;
2803         struct gsm48_mmxx_hdr *nmmh;
2804         struct gsm48_mm_conn *conn, *conn_found = NULL;
2805
2806         /* reset loc. upd. counter on CM service request */
2807         mm->lupd_attempt = 0;
2808
2809         /* find if there is already a pending connection */
2810         llist_for_each_entry(conn, &mm->mm_conn, list) {
2811                 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
2812                         conn_found = conn;
2813                         break;
2814                 }
2815         }
2816
2817         /* if pending connection */
2818         if (conn_found) {
2819                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but already have "
2820                         "pending MM Connection.\n");
2821                 cause = 17;
2822                 reject:
2823                 nmsg = NULL;
2824                 switch(msg_type) {
2825                 case GSM48_MMCC_EST_REQ:
2826                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND,
2827                                 mmh->ref, mmh->transaction_id);
2828                         break;
2829                 case GSM48_MMSS_EST_REQ:
2830                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND,
2831                                 mmh->ref, mmh->transaction_id);
2832                         break;
2833                 case GSM48_MMSMS_EST_REQ:
2834                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND,
2835                                 mmh->ref, mmh->transaction_id);
2836                         break;
2837                 }
2838                 if (!nmsg)
2839                         return -ENOMEM;
2840                 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
2841                 nmmh->cause = cause;
2842                 gsm48_mmxx_upmsg(ms, nmsg);
2843
2844                 return -EBUSY;
2845         }
2846         /* in case of an emergency setup */
2847         if (msg_type == GSM48_MMCC_EST_REQ && mmh->emergency)
2848                 emergency = 1;
2849
2850         /* if sim is not updated */
2851         if (!emergency && subscr->ustate != GSM_SIM_U1_UPDATED) {
2852                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but SIM not "
2853                         "updated.\n");
2854                 cause = 21;
2855                 goto reject;
2856         }
2857
2858         if (mm->state == GSM48_MM_ST_MM_IDLE) {
2859                 /* current MM idle state */
2860                 switch (mm->substate) {
2861                 case GSM48_MM_SST_NORMAL_SERVICE:
2862                 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
2863                         LOGP(DMM, LOGL_INFO, "Init MM Connection.\n");
2864                         break; /* allow when normal */
2865                 case GSM48_MM_SST_LOC_UPD_NEEDED:
2866                 case GSM48_MM_SST_ATTEMPT_UPDATE:
2867                         /* store mm request if attempting to update */
2868                         if (!emergency) {
2869                                 LOGP(DMM, LOGL_INFO, "Init MM Connection, but "
2870                                         "attempting to update.\n");
2871                                 cause = 21;
2872                                 goto reject;
2873                                 /* TODO: implement delay and start loc upd. */
2874                         }
2875                         break;
2876                 default:
2877                         /* reject if not emergency */
2878                         if (!emergency) {
2879                                 LOGP(DMM, LOGL_INFO, "Init MM Connection, not "
2880                                         "in normal state.\n");
2881                                 cause = 21;
2882                                 goto reject;
2883                         }
2884                         break;
2885                 }
2886         } else
2887                 LOGP(DMM, LOGL_INFO, "Init another MM Connection.\n");
2888
2889         /* set cause, service, proto */
2890         switch(msg_type) {
2891         case GSM48_MMCC_EST_REQ:
2892                 if (emergency) {
2893                         cause = RR_EST_CAUSE_EMERGENCY;
2894                         cm_serv = GSM48_CMSERV_EMERGENCY;
2895                 } else {
2896                         cause = RR_EST_CAUSE_ORIG_TCHF;
2897                         cm_serv = GSM48_CMSERV_MO_CALL_PACKET;
2898                 }
2899                 proto = GSM48_PDISC_CC;
2900                 break;
2901         case GSM48_MMSS_EST_REQ:
2902                 cause = RR_EST_CAUSE_OTHER_SDCCH;
2903                 cm_serv = GSM48_CMSERV_SUP_SERV;
2904                 proto = GSM48_PDISC_NC_SS;
2905                 break;
2906         case GSM48_MMSMS_EST_REQ:
2907                 cause = RR_EST_CAUSE_OTHER_SDCCH;
2908                 cm_serv = GSM48_CMSERV_SMS;
2909                 proto = GSM48_PDISC_SMS;
2910                 break;
2911         }
2912
2913         /* create MM connection instance */
2914         conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
2915         if (!conn)
2916                 return -ENOMEM;
2917
2918         new_conn_state(conn, GSM48_MMXX_ST_CONN_PEND);
2919
2920         /* send CM SERVICE REQUEST */
2921         if (rr_prim) {
2922                 mm->est_cause = cause;
2923                 return gsm48_mm_tx_cm_serv_req(ms, rr_prim, cm_serv);
2924         } else
2925                 return 0;
2926 }
2927
2928 /* 4.5.1.1 a) MM connection request triggers RR connection */
2929 static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, struct msgb *msg)
2930 {
2931         struct gsm48_mmlayer *mm = &ms->mmlayer;
2932         int rc;
2933
2934         /* start MM connection by requesting RR connection */
2935         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_EST_REQ);
2936         if (rc)
2937                 return rc;
2938
2939         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
2940
2941         return 0;
2942 }
2943
2944 /* 4.5.1.1 a) RR is esablised during mm connection, wait for CM accepted */
2945 static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct msgb *msg)
2946 {
2947         struct gsm48_mmlayer *mm = &ms->mmlayer;
2948
2949         /* 4.5.1.7 if there is no more MM connection */
2950         if (llist_empty(&mm->mm_conn)) {
2951                 LOGP(DMM, LOGL_INFO, "MM Connection, are already gone.\n");
2952
2953                 /* start RR release timer */
2954                 start_mm_t3240(mm);
2955
2956                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2957
2958                 /* send abort */
2959                 return gsm48_mm_tx_cm_service_abort(ms);
2960         }
2961
2962         /* start MM connection timer */
2963         start_mm_t3230(mm);
2964
2965         new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2966
2967         return 0;
2968 }
2969
2970 /* 4.5.1.1 b) MM connection request on existing RR connection */
2971 static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, struct msgb *msg)
2972 {
2973         struct gsm48_mmlayer *mm = &ms->mmlayer;
2974         int rc;
2975
2976         /* start MM connection by sending data */
2977         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
2978         if (rc)
2979                 return rc;
2980
2981         /* stop "RR connection release not allowed" timer */
2982         stop_mm_t3241(mm);
2983
2984         /* start MM connection timer */
2985         start_mm_t3230(mm);
2986
2987         new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2988
2989         return 0;
2990 }
2991
2992 /* 4.5.1.1 b) another MM connection request on existing RR connection */
2993 static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, struct msgb *msg)
2994 {
2995         struct gsm48_mmlayer *mm = &ms->mmlayer;
2996         int rc;
2997
2998         /* start MM connection by sending data */
2999         rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
3000         if (rc)
3001                 return rc;
3002
3003         /* start MM connection timer */
3004         start_mm_t3230(mm);
3005
3006         new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
3007
3008         return 0;
3009 }
3010
3011 /* 4.5.1.1 b) delay on WAIT FOR NETWORK COMMAND state */
3012 static int gsm48_mm_init_mm_wait(struct osmocom_ms *ms, struct msgb *msg)
3013 {
3014         /* reject */
3015         gsm48_mm_init_mm_reject(ms, msg);
3016 #if 0
3017         this requires handling when leaving this state...
3018
3019         struct gsm48_mmlayer *mm = &ms->mmlayer;
3020         int rc;
3021
3022         /* just create the MM connection in pending state */
3023         rc = gsm48_mm_init_mm(ms, msg, 0);
3024         if (rc)
3025                 return rc;
3026
3027         /* start MM connection timer */
3028         start_mm_t3230(mm);
3029
3030         new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
3031 #endif
3032
3033         return 0;
3034 }
3035
3036 /* initiate an mm connection other cases */
3037 static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
3038 {
3039         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3040         int msg_type = mmh->msg_type;
3041         struct msgb *nmsg;
3042         struct gsm48_mmxx_hdr *nmmh;
3043
3044         /* reject */
3045         nmsg = NULL;
3046         switch(msg_type) {
3047         case GSM48_MMCC_EST_REQ:
3048                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
3049                         mmh->transaction_id);
3050                 break;
3051         case GSM48_MMSS_EST_REQ:
3052                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
3053                         mmh->transaction_id);
3054                 break;
3055         case GSM48_MMSMS_EST_REQ:
3056                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
3057                         mmh->transaction_id);
3058                 break;
3059         }
3060         if (!nmsg)
3061                 return -ENOMEM;
3062         nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3063         nmmh->cause = 17;
3064         gsm48_mmxx_upmsg(ms, nmsg);
3065
3066         return 0;
3067 }
3068
3069 /* accepting pending connection, got dedicated mode
3070  *
3071  * this function is called:
3072  * - when ciphering command is received
3073  * - when cm service is accepted 
3074  */
3075 static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
3076 {
3077         struct gsm48_mmlayer *mm = &ms->mmlayer;
3078         struct gsm48_mm_conn *conn, *conn_found = NULL;
3079         struct msgb *nmsg;
3080         struct gsm48_mmxx_hdr *nmmh;
3081
3082         /* the first and only pending connection is the recent requested */
3083         llist_for_each_entry(conn, &mm->mm_conn, list) {
3084                 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
3085                         conn_found = conn;
3086                         break;
3087                 }
3088         }
3089
3090         /* if no pending connection (anymore) */
3091         if (!conn_found) {
3092                 LOGP(DMM, LOGL_INFO, "No pending MM Connection.\n");
3093
3094                 return 0;
3095         }
3096
3097         new_conn_state(conn, GSM48_MMXX_ST_DEDICATED);
3098
3099         /* send establishment confirm */
3100         nmsg = NULL;
3101         switch(conn_found->protocol) {
3102         case GSM48_PDISC_CC:
3103                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF, conn->ref,
3104                         conn->transaction_id);
3105                 break;
3106         case GSM48_PDISC_NC_SS:
3107                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF, conn->ref,
3108                         conn->transaction_id);
3109                 break;
3110         case GSM48_PDISC_SMS:
3111                 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF, conn->ref,
3112                         conn->transaction_id);
3113                 break;
3114         }
3115         if (!nmsg)
3116                 return -ENOMEM;
3117         nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3118         nmmh->cause = 17;
3119         gsm48_mmxx_upmsg(ms, nmsg);
3120
3121         return 0;
3122 }
3123
3124 /* a RR-SYNC-IND is received during MM connection establishment */
3125 static int gsm48_mm_sync_ind_wait(struct osmocom_ms *ms, struct msgb *msg)
3126 {
3127         struct gsm48_mmlayer *mm = &ms->mmlayer;
3128         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3129
3130         if (rrh->cause != RR_SYNC_CAUSE_CIPHERING) {
3131                 LOGP(DMM, LOGL_NOTICE, "Ignore sync indication, not waiting "
3132                         "for CM service\n");
3133                 return -EINVAL;
3134         }
3135
3136         /* stop MM connection timer */
3137         stop_mm_t3230(mm);
3138
3139         new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3140
3141         return gsm48_mm_conn_go_dedic(ms);
3142 }
3143
3144 /* a RR-SYNC-IND is received during MM connection active */
3145 static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
3146 {
3147         struct gsm48_mmlayer *mm = &ms->mmlayer;
3148         struct gsm48_mm_conn *conn;
3149         struct msgb *nmsg;
3150         struct gsm48_mmxx_hdr *nmmh;
3151
3152         /* stop MM connection timer */
3153         stop_mm_t3230(mm);
3154
3155         /* broadcast all MMCC connection(s) */
3156         llist_for_each_entry(conn, &mm->mm_conn, list) {
3157                 /* send MMCC-SYNC-IND */
3158                 nmsg = NULL;
3159                 switch(conn->protocol) {
3160                 case GSM48_PDISC_CC:
3161                         nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_SYNC_IND,
3162                                 conn->ref, conn->transaction_id);
3163                         break;
3164                 }
3165                 if (!nmsg)
3166                         continue; /* skip if not of CC type */
3167                 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3168                 nmmh->cause = 17;
3169                 /* copy L3 message */
3170                 nmsg->l3h = msgb_put(nmsg, msgb_l3len(msg));
3171                 memcpy(nmsg->l3h, msg->l3h, msgb_l3len(msg));
3172                 gsm48_mmxx_upmsg(ms, nmsg);
3173         }
3174
3175         return 0;
3176 }
3177
3178 /* 4.5.1.2 RR abort/release is received during MM connection establishment */
3179 static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3180 {
3181         struct gsm48_mmlayer *mm = &ms->mmlayer;
3182         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3183         int cause;
3184
3185         /* stop RR release timer */
3186         stop_mm_t3240(mm);
3187
3188         /* this conversion is not of any standard */
3189         switch(rrh->cause) {
3190         case RR_REL_CAUSE_NOT_AUTHORIZED:
3191         case RR_REL_CAUSE_EMERGENCY_ONLY:
3192         case RR_REL_CAUSE_TRY_LATER:
3193                 cause = 21;
3194                 break;
3195         case RR_REL_CAUSE_NORMAL:
3196                 cause = 16;
3197                 break;
3198         default:
3199                 cause = 47;
3200         }
3201
3202         /* stop MM connection timer */
3203         stop_mm_t3230(mm);
3204
3205         /* release all connections */
3206         gsm48_mm_release_mm_conn(ms, 1, cause, 1);
3207
3208         /* no RR connection, so we return to MM IDLE */
3209         if (mm->state == GSM48_MM_ST_WAIT_RR_CONN_MM_CON)
3210                 return gsm48_mm_return_idle(ms, NULL);
3211
3212         /* CS process will trigger: return to MM IDLE */
3213         return 0;
3214 }
3215
3216 /* 4.5.1.2 timeout is received during MM connection establishment */
3217 static int gsm48_mm_timeout_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3218 {
3219         struct gsm48_mmlayer *mm = &ms->mmlayer;
3220
3221         /* release pending connection */
3222         gsm48_mm_release_mm_conn(ms, 0, 102, 0);
3223
3224         /* state depends on the existance of remaining MM connections */
3225         if (llist_empty(&mm->mm_conn)) {
3226                 /* start RR release timer */
3227                 start_mm_t3240(mm);
3228
3229                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3230         } else
3231                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3232
3233         return 0;
3234 }
3235
3236 /* respond to paging */
3237 static int gsm48_mm_est(struct osmocom_ms *ms, struct msgb *msg)
3238 {
3239         struct gsm48_mmlayer *mm = &ms->mmlayer;
3240
3241         mm->est_cause = RR_EST_CAUSE_ANS_PAG_ANY;
3242         new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3243
3244         return 0;
3245 }
3246
3247 /* send CM data */
3248 static int gsm48_mm_data(struct osmocom_ms *ms, struct msgb *msg)
3249 {
3250         struct gsm48_mmlayer *mm = &ms->mmlayer;
3251         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3252         struct gsm48_mm_conn *conn;
3253         int msg_type = mmh->msg_type;
3254
3255         /* get connection, if not exist (anymore), release */
3256         conn = mm_conn_by_ref(mm, mmh->ref);
3257         if (!conn) {
3258                 LOGP(DMM, LOGL_INFO, "MMXX_DATA_REQ with unknown (already "
3259                         "released) ref=%x, sending MMXX_REL_IND\n", mmh->ref);
3260                 switch(msg_type & GSM48_MMXX_MASK) {
3261                 case GSM48_MMCC_CLASS:
3262                         mmh->msg_type = GSM48_MMCC_REL_IND;
3263                         break;
3264                 case GSM48_MMSS_CLASS:
3265                         mmh->msg_type = GSM48_MMSS_REL_IND;
3266                         break;
3267                 case GSM48_MMSMS_CLASS:
3268                         mmh->msg_type = GSM48_MMSMS_REL_IND;
3269                         break;
3270                 }
3271                 mmh->cause = 31;
3272
3273                 /* mirror message with REL_IND + cause */
3274                 return gsm48_mmxx_upmsg(ms, msg);
3275         }
3276         
3277         /* pull MM header */
3278         msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
3279
3280         /* push RR header and send down */
3281         return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, 0);
3282 }
3283
3284 /* release of MM connection (active state) */
3285 static int gsm48_mm_release_active(struct osmocom_ms *ms, struct msgb *msg)
3286 {
3287         struct gsm48_mmlayer *mm = &ms->mmlayer;
3288         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3289         struct gsm48_mm_conn *conn;
3290
3291         /* get connection, if not exist (anymore), release */
3292         conn = mm_conn_by_ref(mm, mmh->ref);
3293         if (conn)
3294                 mm_conn_free(conn);
3295
3296         /* state depends on the existance of remaining MM connections */
3297         if (llist_empty(&mm->mm_conn)) {
3298                 /* start RR release timer */
3299                 start_mm_t3240(mm);
3300
3301                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3302         } else
3303                 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3304
3305         return 0;
3306 }
3307
3308 /* release of MM connection (wait for additional state) */
3309 static int gsm48_mm_release_wait_add(struct osmocom_ms *ms, struct msgb *msg)
3310 {
3311         struct gsm48_mmlayer *mm = &ms->mmlayer;
3312         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3313         struct gsm48_mm_conn *conn;
3314
3315         /* get connection, if not exist (anymore), release */
3316         conn = mm_conn_by_ref(mm, mmh->ref);
3317         if (conn)
3318                 mm_conn_free(conn);
3319
3320         return 0;
3321 }
3322
3323 /* release of MM connection (wait for active state) */
3324 static int gsm48_mm_release_wait_active(struct osmocom_ms *ms, struct msgb *msg)
3325 {
3326         struct gsm48_mmlayer *mm = &ms->mmlayer;
3327         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3328         struct gsm48_mm_conn *conn;
3329
3330         /* get connection, if not exist (anymore), release */
3331         conn = mm_conn_by_ref(mm, mmh->ref);
3332         if (conn)
3333                 mm_conn_free(conn);
3334
3335         /* 4.5.1.7 if there is no MM connection during wait for active state */
3336         if (llist_empty(&mm->mm_conn)) {
3337                 LOGP(DMM, LOGL_INFO, "No MM Connection during 'wait for "
3338                         "active' state.\n");
3339
3340                 /* start RR release timer */
3341                 start_mm_t3240(mm);
3342
3343                 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3344
3345                 /* send abort */
3346                 return gsm48_mm_tx_cm_service_abort(ms);
3347         }
3348
3349         return 0;
3350 }
3351
3352 /* release of MM connection (wait for RR state) */
3353 static int gsm48_mm_release_wait_rr(struct osmocom_ms *ms, struct msgb *msg)
3354 {
3355         struct gsm48_mmlayer *mm = &ms->mmlayer;
3356         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3357         struct gsm48_mm_conn *conn;
3358
3359         /* get connection, if not exist (anymore), release */
3360         conn = mm_conn_by_ref(mm, mmh->ref);
3361         if (conn)
3362                 mm_conn_free(conn);
3363
3364         /* later, if RR connection is established, the CM SERIVE ABORT
3365          * message will be sent
3366          */
3367         return 0;
3368 }
3369
3370 /* abort RR connection (due to T3240) */
3371 static int gsm48_mm_abort_rr(struct osmocom_ms *ms, struct msgb *msg)
3372 {
3373         struct msgb *nmsg;
3374         struct gsm48_rr_hdr *nrrh;
3375
3376         /* send abort to RR */
3377         nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
3378         if (!nmsg)
3379                 return -ENOMEM;
3380         nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
3381         nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
3382         gsm48_rr_downmsg(ms, nmsg);
3383
3384         /* CS process will trigger: return to MM IDLE / No SIM */
3385         return 0;
3386 }
3387
3388 /*
3389  * other processes
3390  */
3391
3392 /* RR is released in other states */
3393 static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct msgb *msg)
3394 {
3395         struct gsm48_mmlayer *mm = &ms->mmlayer;
3396
3397         /* stop RR release timer (if running) */
3398         stop_mm_t3240(mm);
3399
3400         /* CS process will trigger: return to MM IDLE */
3401         return 0;
3402 }
3403
3404 /*
3405  * state machines
3406  */
3407
3408 /* state trasitions for MMxx-SAP messages from upper layers */
3409 static struct downstate {
3410         uint32_t        states;
3411         uint32_t        substates;
3412         int             type;
3413         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3414 } downstatelist[] = {
3415         /* 4.2.2.1 Normal service */
3416         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3417          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3418
3419         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3420          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3421
3422         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3423          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3424
3425         /* 4.2.2.2 Attempt to update / Loc. Upd. needed */
3426         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3427                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3428          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr}, /* emergency only */
3429
3430         /* 4.2.2.3 Limited service */
3431         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3432          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3433
3434         /* 4.2.2.4 No IMSI */
3435         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
3436          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3437
3438         /* 4.2.2.5 PLMN search, normal service */
3439         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3440          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3441
3442         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3443          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3444
3445         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3446          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3447
3448         /* 4.2.2.6 PLMN search */
3449         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3450          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3451
3452         /* 4.5.1.1 MM Connection (EST) */
3453         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3454          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_first},
3455
3456         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3457          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_first},
3458
3459         {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3460          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_first},
3461
3462         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3463          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_more},
3464
3465         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3466          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_more},
3467
3468         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3469          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_more},
3470
3471         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3472          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_wait},
3473
3474         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3475          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_wait},
3476
3477         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3478          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_wait},
3479
3480         {ALL_STATES, ALL_STATES,
3481          GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_reject},
3482
3483         {ALL_STATES, ALL_STATES,
3484          GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_reject},
3485
3486         {ALL_STATES, ALL_STATES,
3487          GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_reject},
3488
3489         /* 4.5.2.1 MM Connection (DATA) */
3490         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3491          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3492          GSM48_MMCC_DATA_REQ, gsm48_mm_data},
3493
3494         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3495          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3496          GSM48_MMSS_DATA_REQ, gsm48_mm_data},
3497
3498         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3499          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3500          GSM48_MMSMS_DATA_REQ, gsm48_mm_data},
3501
3502         /* 4.5.2.1 MM Connection (REL) */
3503         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3504          GSM48_MMCC_REL_REQ, gsm48_mm_release_active},
3505
3506         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3507          GSM48_MMSS_REL_REQ, gsm48_mm_release_active},
3508
3509         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3510          GSM48_MMSMS_REL_REQ, gsm48_mm_release_active},
3511
3512         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3513          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_add},
3514
3515         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3516          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_add},
3517
3518         {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3519          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_add},
3520
3521         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3522          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_active},
3523
3524         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3525          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_active},
3526
3527         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3528          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_active},
3529
3530         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3531          GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_rr},
3532
3533         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3534          GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_rr},
3535
3536         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3537          GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_rr},
3538 };
3539
3540 #define DOWNSLLEN \
3541         (sizeof(downstatelist) / sizeof(struct downstate))
3542
3543 int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg)
3544 {
3545         struct gsm48_mmlayer *mm = &ms->mmlayer;
3546         struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3547         int msg_type = mmh->msg_type;
3548         struct gsm48_mm_conn *conn;
3549         int i, rc;
3550
3551         /* keep up to date with the transaction ID */
3552         conn = mm_conn_by_ref(mm, mmh->ref);
3553         if (conn)
3554                 conn->transaction_id = mmh->transaction_id;
3555
3556         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
3557                 ms->name, get_mmxx_name(msg_type),
3558                 gsm48_mm_state_names[mm->state]);
3559         if (mm->state == GSM48_MM_ST_MM_IDLE)
3560                 LOGP(DMM, LOGL_INFO, "-> substate %s\n",
3561                         gsm48_mm_substate_names[mm->substate]);
3562         LOGP(DMM, LOGL_INFO, "-> callref %x, transaction_id %d\n",
3563                 mmh->ref, mmh->transaction_id);
3564
3565         /* Find function for current state and message */
3566         for (i = 0; i < DOWNSLLEN; i++)
3567                 if ((msg_type == downstatelist[i].type)
3568                  && ((1 << mm->state) & downstatelist[i].states)
3569                  && ((1 << mm->substate) & downstatelist[i].substates))
3570                         break;
3571         if (i == DOWNSLLEN) {
3572                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3573                 msgb_free(msg);
3574                 return 0;
3575         }
3576
3577         rc = downstatelist[i].rout(ms, msg);
3578
3579         if (downstatelist[i].rout != gsm48_mm_data)
3580                 msgb_free(msg);
3581
3582         return rc;
3583 }
3584
3585 /* state trasitions for radio ressource messages (lower layer) */
3586 static struct rrdatastate {
3587         uint32_t        states;
3588         int             type;
3589         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3590 } rrdatastatelist[] = {
3591         /* paging */
3592         {SBIT(GSM48_MM_ST_MM_IDLE),
3593          GSM48_RR_EST_IND, gsm48_mm_est},
3594
3595         /* imsi detach */
3596         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 */
3597          GSM48_RR_EST_CNF, gsm48_mm_imsi_detach_sent},
3598
3599         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (unsuc.) */
3600          GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3601                 /* also this may happen if SABM is ackwnowledged with DISC */
3602
3603         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (lost) */
3604          GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3605
3606         {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (unsuc.) */
3607          GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3608
3609         {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (lost) */
3610          GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3611
3612         /* location update */
3613         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
3614          GSM48_RR_EST_CNF, gsm48_mm_est_loc_upd},
3615
3616         {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3617          SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3618          GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_abort},
3619
3620         {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3621          SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3622          GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_abort},
3623
3624         {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3625          GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
3626
3627         {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3628          GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_rej},
3629
3630         /* MM connection (EST) */
3631         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
3632          GSM48_RR_EST_CNF, gsm48_mm_est_mm_con},
3633
3634         /* MM connection (DATA) */
3635         {ALL_STATES,
3636          GSM48_RR_DATA_IND, gsm48_mm_data_ind},
3637
3638         /* MM connection (SYNC) */
3639         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3640          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.1 */
3641          GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_wait},
3642
3643         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE),
3644          GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_active},
3645
3646         /* MM connection (REL/ABORT) */
3647         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3648          SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3649          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3650          GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3651
3652         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3653          SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3654          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3655          GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3656
3657         /* MM connection (REL/ABORT with re-establishment possibility) */
3658         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), /* not supported */
3659          GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3660
3661         {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3662          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* not supported */
3663          GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3664
3665         /* other (also wait for network command) */
3666         {ALL_STATES,
3667          GSM48_RR_REL_IND, gsm48_mm_rel_other},
3668
3669         {ALL_STATES,
3670          GSM48_RR_ABORT_IND, gsm48_mm_rel_other},
3671 };
3672
3673 #define RRDATASLLEN \
3674         (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
3675
3676 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
3677 {
3678         struct gsm48_mmlayer *mm = &ms->mmlayer;
3679         struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3680         int msg_type = rrh->msg_type;
3681         int i, rc;
3682
3683         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s\n",
3684                 ms->name, get_rr_name(msg_type),
3685                 gsm48_mm_state_names[mm->state]);
3686
3687         /* find function for current state and message */
3688         for (i = 0; i < RRDATASLLEN; i++)
3689                 if ((msg_type == rrdatastatelist[i].type)
3690                  && ((1 << mm->state) & rrdatastatelist[i].states))
3691                         break;
3692         if (i == RRDATASLLEN) {
3693                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3694                 msgb_free(msg);
3695                 return 0;
3696         }
3697
3698         rc = rrdatastatelist[i].rout(ms, msg);
3699         
3700         if (rrdatastatelist[i].rout != gsm48_mm_data_ind)
3701                 msgb_free(msg);
3702
3703         return rc;
3704 }
3705
3706 /* state trasitions for mobile managemnt messages (lower layer) */
3707 static struct mmdatastate {
3708         uint32_t        states;
3709         int             type;
3710         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3711 } mmdatastatelist[] = {
3712         {ALL_STATES, /* 4.3.1.2 */
3713          GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
3714
3715         {ALL_STATES, /* 4.3.2.2 */
3716          GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
3717
3718         {ALL_STATES, /* 4.3.2.5 */
3719          GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
3720
3721         {ALL_STATES, /* 4.3.3.2 */
3722          GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
3723
3724         {ALL_STATES, /* 4.3.5.2 */
3725          GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
3726
3727         {ALL_STATES, /* 4.3.6.2 */
3728          GSM48_MT_MM_INFO, gsm48_mm_rx_info},
3729
3730         {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.6 */
3731          GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
3732
3733         {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.7 */
3734          GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
3735
3736         {ALL_STATES, /* 4.5.1.1 */
3737          GSM48_MT_MM_CM_SERV_ACC, gsm48_mm_rx_cm_service_acc},
3738
3739         {ALL_STATES, /* 4.5.1.1 */
3740          GSM48_MT_MM_CM_SERV_REJ, gsm48_mm_rx_cm_service_rej},
3741 };
3742
3743 #define MMDATASLLEN \
3744         (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
3745
3746 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
3747 {
3748         struct gsm48_mmlayer *mm = &ms->mmlayer;
3749         struct gsm48_hdr *gh = msgb_l3(msg);
3750         uint8_t pdisc = gh->proto_discr & 0x0f;
3751         uint8_t msg_type = gh->msg_type & 0xbf;
3752         struct gsm48_mmxx_hdr *mmh;
3753         int msg_supported = 0; /* determine, if message is supported at all */
3754         int rr_prim = -1, rr_est = -1; /* no prim set */
3755         uint8_t skip_ind;
3756         int i, rc;
3757
3758         /* 9.2.19 */
3759         if (msg_type == GSM48_MT_MM_NULL)
3760                 return 0;
3761
3762         if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
3763                 LOGP(DMM, LOGL_NOTICE, "DATA IND ignored during IMSI "
3764                         "detach.\n");
3765                 return 0;
3766         }
3767         /* pull the RR header */
3768         msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
3769
3770         /* create transaction (if not exists) and push message */
3771         switch (pdisc) {
3772         case GSM48_PDISC_CC:
3773                 rr_prim = GSM48_MMCC_DATA_IND;
3774                 rr_est = GSM48_MMCC_EST_IND;
3775                 break;
3776 #if 0
3777         case GSM48_PDISC_NC_SS:
3778                 rr_prim = GSM48_MMSS_DATA_IND;
3779                 rr_est = GSM48_MMSS_EST_IND;
3780                 break;
3781         case GSM48_PDISC_SMS:
3782                 rr_prim = GSM48_MMSMS_DATA_IND;
3783                 rr_est = GSM48_MMSMS_EST_IND;
3784                 break;
3785 #endif
3786         }
3787         if (rr_prim != -1) {
3788                 uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
3789                         /* flip */
3790                 struct gsm48_mm_conn *conn;
3791
3792                 /* find transaction, if any */
3793                 conn = mm_conn_by_id(mm, pdisc, transaction_id);
3794
3795                 /* create MM connection instance */
3796                 if (!conn) {
3797                         conn = mm_conn_new(mm, pdisc, transaction_id,
3798                                 mm_conn_new_ref++);
3799                         rr_prim = rr_est;
3800                 }
3801                 if (!conn)
3802                         return -ENOMEM;
3803
3804                 /* push new header */
3805                 msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
3806                 mmh = (struct gsm48_mmxx_hdr *)msg->data;
3807                 mmh->msg_type = rr_prim;
3808                 mmh->ref = conn->ref;
3809
3810                 /* go MM CONN ACTIVE state */
3811                 if (mm->state == GSM48_MM_ST_WAIT_NETWORK_CMD
3812                  || mm->state == GSM48_MM_ST_RR_CONN_RELEASE_NA) {
3813                         /* stop RR release timer */
3814                         stop_mm_t3240(mm);
3815
3816                         /* stop "RR connection release not allowed" timer */
3817                         stop_mm_t3241(mm);
3818
3819                         new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3820                 }
3821         }
3822
3823         /* forward message */
3824         switch (pdisc) {
3825         case GSM48_PDISC_MM:
3826                 skip_ind = (gh->proto_discr & 0xf0) >> 4;
3827
3828                 /* ignore if skip indicator is not B'0000' */
3829                 if (skip_ind)
3830                         return 0;
3831                 break; /* follow the selection proceedure below */
3832
3833         case GSM48_PDISC_CC:
3834                 return gsm48_rcv_cc(ms, msg);
3835
3836 #if 0
3837         case GSM48_PDISC_NC_SS:
3838                 return gsm48_rcv_ss(ms, msg);
3839
3840         case GSM48_PDISC_SMS:
3841                 return gsm48_rcv_sms(ms, msg);
3842 #endif
3843
3844         default:
3845                 LOGP(DMM, LOGL_NOTICE, "Protocol type 0x%02x unsupported.\n",
3846                         pdisc);
3847                 msgb_free(msg);
3848                 return gsm48_mm_tx_mm_status(ms,
3849                         GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3850         }
3851
3852         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
3853                 get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
3854
3855         stop_mm_t3212(mm); /* 4.4.2 */
3856
3857         /* 11.2 re-start pending RR release timer */
3858         if (bsc_timer_pending(&mm->t3240)) {
3859                 stop_mm_t3240(mm);
3860                 start_mm_t3240(mm);
3861         }
3862
3863         /* find function for current state and message */
3864         for (i = 0; i < MMDATASLLEN; i++) {
3865                 if (msg_type == mmdatastatelist[i].type)
3866                         msg_supported = 1;
3867                 if ((msg_type == mmdatastatelist[i].type)
3868                  && ((1 << mm->state) & mmdatastatelist[i].states))
3869                         break;
3870         }
3871         if (i == MMDATASLLEN) {
3872                 msgb_free(msg);
3873                 if (msg_supported) {
3874                         LOGP(DMM, LOGL_NOTICE, "Message unhandled at this "
3875                                 "state.\n");
3876                         return gsm48_mm_tx_mm_status(ms,
3877                                 GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
3878                 } else {
3879                         LOGP(DMM, LOGL_NOTICE, "Message not supported.\n");
3880                         return gsm48_mm_tx_mm_status(ms,
3881                                 GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3882                 }
3883         }
3884
3885         rc = mmdatastatelist[i].rout(ms, msg);
3886
3887         msgb_free(msg);
3888
3889         return rc;
3890 }
3891
3892 /* state trasitions for mobile management events */
3893 static struct eventstate {
3894         uint32_t        states;
3895         uint32_t        substates;
3896         int             type;
3897         int             (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3898 } eventstatelist[] = {
3899         /* 4.2.3 return to MM IDLE */
3900         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3901          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found},
3902
3903         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3904          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_return_idle},
3905
3906         /* 4.2.2.1 Normal service */
3907         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3908          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3909
3910         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3911          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3912
3913         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3914          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3915
3916         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3917          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3918
3919         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3920          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3921
3922         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3923          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3924
3925         /* 4.2.2.2 Attempt to update / Loc. upd. needed */
3926         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3927                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3928          GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3929
3930         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3931                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3932          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3933
3934         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3935                                 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3936          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3937
3938         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3939          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3940
3941         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3942          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3943
3944         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3945          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3946
3947         /* 4.2.2.3 Limited service */
3948         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3949          GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3950
3951         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3952          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3953
3954         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3955          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* if allow. */
3956
3957         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3958          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3959
3960         /* 4.2.2.4 No IMSI */
3961         /* 4.2.2.5 PLMN search, normal service */
3962         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3963          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3964
3965         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3966          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3967
3968         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3969          GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd_delay_retry},
3970
3971         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3972          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_delay_retry},
3973
3974         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3975          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3976
3977         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3978          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3979
3980         /* 4.2.2.6 PLMN search */
3981         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3982          GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3983
3984         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3985          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3986
3987         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3988          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3989
3990         /* No cell available */
3991         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3992          GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3993
3994         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3995          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3996
3997         /* IMSI detach in other cases */
3998         {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES, /* silently detach */
3999          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_end},
4000
4001         {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
4002          SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
4003          SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
4004          SBIT(GSM48_MM_ST_WAIT_REEST) |
4005          SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON) |
4006          SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
4007          SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES, /* we can release */
4008          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_release},
4009
4010         {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D) |
4011          SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
4012          SBIT(GSM48_MM_ST_IMSI_DETACH_PEND), ALL_STATES, /* ignore */
4013          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_ignore},
4014
4015         {ALL_STATES, ALL_STATES,
4016          GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
4017
4018         {GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
4019          GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
4020
4021         /* location update in other cases */
4022         {ALL_STATES, ALL_STATES,
4023          GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_ignore},
4024
4025         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4026          GSM48_MM_EVENT_TIMEOUT_T3210, gsm48_mm_loc_upd_timeout},
4027
4028         {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4029          GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_failed},
4030                 /* 4.4.4.9 c) (but without retry) */
4031
4032         /* SYSINFO event */
4033         {ALL_STATES, ALL_STATES,
4034          GSM48_MM_EVENT_SYSINFO, gsm48_mm_sysinfo},
4035
4036         /* T3240 timed out */
4037         {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
4038          SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES, /* 4.4.4.8 */
4039          GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
4040
4041         /* T3230 timed out */
4042         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
4043          GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
4044
4045         /* SIM reports SRES */
4046         {ALL_STATES, ALL_STATES, /* 4.3.2.2 */
4047          GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
4048
4049 #if 0
4050         /* change in classmark is reported */
4051         {ALL_STATES, ALL_STATES,
4052          GSM48_MM_EVENT_CLASSMARK_CHG, gsm48_mm_classm_chg},
4053 #endif
4054 };
4055
4056 #define EVENTSLLEN \
4057         (sizeof(eventstatelist) / sizeof(struct eventstate))
4058
4059 static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg)
4060 {
4061         struct gsm48_mmlayer *mm = &ms->mmlayer;
4062         int i, rc;
4063
4064         if (mm->state == GSM48_MM_ST_MM_IDLE)
4065                 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4066                         "MM IDLE, %s\n", ms->name, get_mmevent_name(msg_type),
4067                         gsm48_mm_substate_names[mm->substate]);
4068         else
4069                 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4070                         "%s\n", ms->name, get_mmevent_name(msg_type),
4071                 gsm48_mm_state_names[mm->state]);
4072
4073         /* Find function for current state and message */
4074         for (i = 0; i < EVENTSLLEN; i++)
4075                 if ((msg_type == eventstatelist[i].type)
4076                  && ((1 << mm->state) & eventstatelist[i].states)
4077                  && ((1 << mm->substate) & eventstatelist[i].substates))
4078                         break;
4079         if (i == EVENTSLLEN) {
4080                 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
4081                 return 0;
4082         }
4083
4084         rc = eventstatelist[i].rout(ms, msg);
4085
4086         return rc;
4087 }
4088
4089 /*
4090  * MM Register (SIM insert and remove)
4091  */
4092
4093 /* register new SIM card and trigger attach */
4094 static int gsm48_mmr_reg_req(struct osmocom_ms *ms)
4095 {
4096         struct gsm48_mmlayer *mm = &ms->mmlayer;
4097         struct msgb *nmsg;
4098
4099         /* schedule insertion of SIM */
4100         nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_INSERT);
4101         if (!nmsg)
4102                 return -ENOMEM;
4103         gsm322_plmn_sendmsg(ms, nmsg);
4104
4105         /* 4.2.1.2 SIM is inserted in state NO IMSI */
4106         if (mm->state == GSM48_MM_ST_MM_IDLE
4107          && mm->substate == GSM48_MM_SST_NO_IMSI)
4108                 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
4109                         gsm48_mm_set_plmn_search(ms));
4110
4111         return 0;
4112 }
4113
4114 /* trigger detach of sim card */
4115 static int gsm48_mmr_nreg_req(struct osmocom_ms *ms)
4116 {
4117         struct gsm48_mmlayer *mm = &ms->mmlayer;
4118         struct msgb *nmsg;
4119
4120         nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
4121         if (!nmsg)
4122                 return -ENOMEM;
4123         gsm48_mmevent_msg(mm->ms, nmsg);
4124
4125         return 0;
4126 }
4127
4128 static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg)
4129 {
4130         struct gsm48_mmr *mmr = (struct gsm48_mmr *)msg->data;
4131         int msg_type = mmr->msg_type;
4132         int rc = 0;
4133
4134         LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event\n", ms->name,
4135                 get_mmr_name(msg_type));
4136         switch(msg_type) {
4137                 case GSM48_MMR_REG_REQ:
4138                         rc = gsm48_mmr_reg_req(ms);
4139                         break;
4140                 case GSM48_MMR_NREG_REQ:
4141                         rc = gsm48_mmr_nreg_req(ms);
4142                         break;
4143                 default:
4144                         LOGP(DMM, LOGL_NOTICE, "Message unhandled.\n");
4145         }
4146
4147         return rc;
4148 }
4149
4150