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