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