2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
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.
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.
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.
27 #include <arpa/inet.h>
29 #include <osmocore/msgb.h>
30 #include <osmocore/utils.h>
31 #include <osmocore/gsm48.h>
32 #include <osmocore/talloc.h>
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>
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);
63 * Notes on IMSI detach procedure:
65 * At the end of the procedure, the state of MM, RR, cell selection: No SIM.
67 * In MM IDLE state, cell available: RR is establised, IMSI detach specific
68 * procedure is performed.
70 * In MM IDLE state, no cell: State is silently changed to No SIM.
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.
76 * During IMSI detach processing: Request of IMSI detach is ignored.
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.
81 * The procedure is not spec conform, but always succeeds.
85 /* Notes on Service states:
87 * There are two PLMN search states:
89 * - PLMN SEARCH NORMAL
92 * They are entered, if: (4.2.1.2)
95 * - user has asked PLMN selection in certain Service states
96 * - coverage is lost in certain Service states
98 * - (optionally see 4.2.1.2)
100 * PLMN SEARCH NORMAL state is then entered, if all these conditions are met:
107 * Otherwhise PLMN SEARCH is entered.
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)
118 * During PLMN SEARCH state: (4.2.2.6)
119 * - reject MM connection except for emergency calls
122 * The NO CELL AVAILABLE state is entered, if:
123 * - no cell found during PLMN search
125 * During NO CELL AVAILABLE state:
126 * - reject any MM connection
129 * The NO IMSI state is entered if:
131 * - and cell is selected during PLMN SEARCH states
133 * During NO IMSO state: (4.2.2.4)
134 * - reject MM connection except for emergency calls
137 * The LIMITED SERVICE state is entered if:
139 * - and SIM state is U3
140 * - and cell is selected
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
147 * The LOCATION UPDATE NEEDED state is entered if:
149 * - and location update must be performed for any reason
151 * During LOCATION UPDATE NEEDED state:
152 * - reject MM connection except for emergency calls
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
160 * The ATTEMPTING TO UPDATE state is entered if:
162 * - and SIM state is U2
163 * - and cell is selected
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)
175 * The NORMAL SERVICE state is entered if:
177 * - and SIM state is U1
178 * - and cell is selected
179 * - and SIM LAI == cell
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
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.
194 * gsm48_mm_return_idle() is used to select the Service state when returning
195 * to MM IDLE state after cell reselection.
198 * If cell selection process indicates NO_CELL_FOUND:
200 * - NO CELL AVAILABLE state is entered, if not already.
202 * gsm48_mm_no_cell_found() is used to select the Service state.
205 * If cell selection process indicates CELL_SELECTED:
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.
218 * gsm48_mm_cell_selected() is used to select the Service state.
226 /* decode network name */
227 static int decode_network_name(char *name, int name_len,
230 uint8_t in_len = lv[0];
237 /* must be CB encoded */
238 if ((lv[1] & 0x70) != 0x00)
241 padding = lv[1] & 0x03;
242 length = ((in_len - 1) * 8 - padding) / 7;
245 if (length >= name_len)
246 length = name_len - 1;
247 gsm_7bit_decode(name, lv + 2, length);
253 /* encode 'mobile identity' */
254 int gsm48_encode_mi(uint8_t *buf, struct msgb *msg, struct osmocom_ms *ms,
257 struct gsm_subscriber *subscr = &ms->subscr;
258 struct gsm_settings *set = &ms->settings;
262 case GSM_MI_TYPE_TMSI:
263 gsm48_generate_mid_from_tmsi(buf, subscr->tmsi);
265 case GSM_MI_TYPE_IMSI:
266 gsm48_generate_mid_from_imsi(buf, subscr->imsi);
268 case GSM_MI_TYPE_IMEI:
269 gsm48_generate_mid_from_imsi(buf, set->imei);
271 case GSM_MI_TYPE_IMEISV:
272 gsm48_generate_mid_from_imsi(buf, set->imeisv);
274 case GSM_MI_TYPE_NONE:
276 buf[0] = GSM48_IE_MOBILE_ID;
282 buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | mi_type;
286 ie = msgb_put(msg, 1 + buf[1]);
287 memcpy(ie, buf + 1, 1 + buf[1]);
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)
297 memset(cm, 0, sizeof(*cm));
298 cm->rev_lev = rev_lev;
301 cm->pwr_lev = pwr_lev;
310 static void timeout_mm_t3210(void *arg)
312 struct gsm48_mmlayer *mm = arg;
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);
318 static void timeout_mm_t3211(void *arg)
320 struct gsm48_mmlayer *mm = arg;
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);
327 static void timeout_mm_t3212(void *arg)
329 struct gsm48_mmlayer *mm = arg;
331 LOGP(DSUM, LOGL_INFO, "Periodic location update\n");
332 LOGP(DMM, LOGL_INFO, "timer T3212 (periodic loc. upd. delay) has "
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;
340 gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3212, NULL);
343 static void timeout_mm_t3213(void *arg)
345 struct gsm48_mmlayer *mm = arg;
347 LOGP(DSUM, LOGL_INFO, "Location update retry\n");
348 LOGP(DMM, LOGL_INFO, "timer T3213 (delay after RA failure) has "
350 gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213, NULL);
353 static void timeout_mm_t3230(void *arg)
355 struct gsm48_mmlayer *mm = arg;
357 LOGP(DMM, LOGL_INFO, "timer T3230 (MM connection timeout) has "
359 gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3230, NULL);
362 static void timeout_mm_t3220(void *arg)
364 struct gsm48_mmlayer *mm = arg;
366 LOGP(DMM, LOGL_INFO, "timer T3220 (IMSI detach keepalive) has "
368 gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3220, NULL);
371 static void timeout_mm_t3240(void *arg)
373 struct gsm48_mmlayer *mm = arg;
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);
379 static void start_mm_t3210(struct gsm48_mmlayer *mm)
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;
385 bsc_schedule_timer(&mm->t3210, GSM_T3210_MS);
388 static void start_mm_t3211(struct gsm48_mmlayer *mm)
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;
394 bsc_schedule_timer(&mm->t3211, GSM_T3211_MS);
397 static void start_mm_t3212(struct gsm48_mmlayer *mm, int sec)
399 /* don't start, if is not available */
403 LOGP(DMM, LOGL_INFO, "starting T3212 (periodic loc. upd. delay) with "
404 "%d seconds\n", sec);
405 mm->t3212.cb = timeout_mm_t3212;
407 bsc_schedule_timer(&mm->t3212, sec, 0);
410 static void start_mm_t3213(struct gsm48_mmlayer *mm)
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;
416 bsc_schedule_timer(&mm->t3213, GSM_T3213_MS);
419 static void start_mm_t3220(struct gsm48_mmlayer *mm)
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;
425 bsc_schedule_timer(&mm->t3220, GSM_T3220_MS);
428 static void start_mm_t3230(struct gsm48_mmlayer *mm)
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;
434 bsc_schedule_timer(&mm->t3230, GSM_T3230_MS);
437 static void start_mm_t3240(struct gsm48_mmlayer *mm)
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;
443 bsc_schedule_timer(&mm->t3240, GSM_T3240_MS);
446 static void stop_mm_t3210(struct gsm48_mmlayer *mm)
448 if (bsc_timer_pending(&mm->t3210)) {
449 LOGP(DMM, LOGL_INFO, "stopping pending (loc. upd. timeout) "
451 bsc_del_timer(&mm->t3210);
455 static void stop_mm_t3211(struct gsm48_mmlayer *mm)
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);
464 static void stop_mm_t3212(struct gsm48_mmlayer *mm)
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);
473 static void stop_mm_t3213(struct gsm48_mmlayer *mm)
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);
482 static void stop_mm_t3220(struct gsm48_mmlayer *mm)
484 if (bsc_timer_pending(&mm->t3220)) {
485 LOGP(DMM, LOGL_INFO, "stopping pending (IMSI detach keepalive) "
487 bsc_del_timer(&mm->t3220);
491 static void stop_mm_t3230(struct gsm48_mmlayer *mm)
493 if (bsc_timer_pending(&mm->t3230)) {
494 LOGP(DMM, LOGL_INFO, "stopping pending (MM connection timeout) "
496 bsc_del_timer(&mm->t3230);
500 static void stop_mm_t3240(struct gsm48_mmlayer *mm)
502 if (bsc_timer_pending(&mm->t3240)) {
503 LOGP(DMM, LOGL_INFO, "stopping pending (RR release timeout) "
505 bsc_del_timer(&mm->t3240);
509 static void stop_mm_t3241(struct gsm48_mmlayer *mm)
511 /* not implemented, not required */
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" },
537 const char *get_mmevent_name(int value)
539 return get_value_string(gsm48_mmevent_names, value);
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" },
568 const char *get_mm_name(int value)
570 return get_value_string(gsm48_mm_msg_names, value);
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" },
621 const char *get_mmxx_name(int value)
623 return get_value_string(gsm48_mmxx_msg_names, value);
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" },
635 const char *get_mmr_name(int value)
637 return get_value_string(gsm48_mmr_msg_names, value);
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)
645 struct gsm48_mmxx_hdr *mmh;
647 msg = msgb_alloc_headroom(MMXX_ALLOC_SIZE+MMXX_ALLOC_HEADROOM,
648 MMXX_ALLOC_HEADROOM, "GSM 04.08 MMxx");
652 mmh = (struct gsm48_mmxx_hdr *)msgb_put(msg, sizeof(*mmh));
653 mmh->msg_type = msg_type;
655 mmh->transaction_id = transaction_id;
660 /* allocate MM event message */
661 struct msgb *gsm48_mmevent_msgb_alloc(int msg_type)
664 struct gsm48_mm_event *mme;
666 msg = msgb_alloc_headroom(sizeof(*mme), 0, "GSM 04.08 MM event");
670 mme = (struct gsm48_mm_event *)msgb_put(msg, sizeof(*mme));
671 mme->msg_type = msg_type;
676 /* allocate MMR message */
677 struct msgb *gsm48_mmr_msgb_alloc(int msg_type)
680 struct gsm48_mmr *mmr;
682 msg = msgb_alloc_headroom(sizeof(*mmr), 0, "GSM 04.08 MMR");
686 mmr = (struct gsm48_mmr *)msgb_put(msg, sizeof(*mmr));
687 mmr->msg_type = msg_type;
692 /* queue message (MMxx-SAP) */
693 int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg)
695 struct gsm48_mmlayer *mm = &ms->mmlayer;
697 msgb_enqueue(&mm->mmxx_upqueue, msg);
702 /* queue message (MMR-SAP) */
703 int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
705 struct gsm48_mmlayer *mm = &ms->mmlayer;
707 msgb_enqueue(&mm->mmr_downqueue, msg);
712 /* queue MM event message */
713 int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg)
715 struct gsm48_mmlayer *mm = &ms->mmlayer;
717 msgb_enqueue(&mm->event_queue, msg);
722 /* dequeue messages (MMxx-SAP) */
723 int gsm48_mmxx_dequeue(struct osmocom_ms *ms)
725 struct gsm48_mmlayer *mm = &ms->mmlayer;
727 struct gsm48_mmxx_hdr *mmh;
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);
737 case GSM48_MMSS_CLASS:
738 gsm48_rcv_ss(ms, msg);
740 case GSM48_MMSMS_CLASS:
741 gsm48_rcv_sms(ms, msg);
746 work = 1; /* work done */
752 /* dequeue messages (MMR-SAP) */
753 int gsm48_mmr_dequeue(struct osmocom_ms *ms)
755 struct gsm48_mmlayer *mm = &ms->mmlayer;
757 struct gsm48_mmr *mmr;
760 while ((msg = msgb_dequeue(&mm->mmr_downqueue))) {
761 mmr = (struct gsm48_mmr *) msg->data;
762 gsm48_rcv_mmr(ms, msg);
764 work = 1; /* work done */
770 /* dequeue messages (RR-SAP) */
771 int gsm48_rr_dequeue(struct osmocom_ms *ms)
773 struct gsm48_mmlayer *mm = &ms->mmlayer;
777 while ((msg = msgb_dequeue(&mm->rr_upqueue))) {
778 /* msg is freed there */
779 gsm48_rcv_rr(ms, msg);
780 work = 1; /* work done */
786 /* dequeue MM event messages */
787 int gsm48_mmevent_dequeue(struct osmocom_ms *ms)
789 struct gsm48_mmlayer *mm = &ms->mmlayer;
790 struct gsm48_mm_event *mme;
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);
798 work = 1; /* work done */
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)
808 struct gsm48_rr_hdr *rrh;
811 msgb_push(msg, sizeof(struct gsm48_rr_hdr));
812 rrh = (struct gsm48_rr_hdr *) msg->data;
813 rrh->msg_type = msg_type;
816 /* send message to RR */
817 return gsm48_rr_downmsg(ms, msg);
824 const char *gsm48_mm_state_names[] = {
828 "location updating initiated",
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",
838 "wait for RR connection (location updating)",
839 "wait for RR connection (MM connection)",
840 "wait for RR connection (IMSI detach)",
842 "wait for re-establishment",
843 "wait for RR connection active",
845 "wait for additional outgoing MM connection",
846 "MM_CONN_ACTIVE_VGCS",
848 "location updating pending",
849 "IMSI detach pending",
850 "RR connection release not allowed"
853 const char *gsm48_mm_substate_names[] = {
856 "attempting to update",
860 "location updating needed",
862 "PLMN search (normal)",
867 /* change state from LOCATION UPDATE NEEDED to ATTEMPTING TO UPDATE */
868 static int gsm48_mm_loc_upd_possible(struct gsm48_mmlayer *mm)
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);
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)
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 */
895 LOGP(DMM, LOGL_INFO, "new state %s -> %s\n",
896 gsm48_mm_state_names[mm->state],
897 gsm48_mm_state_names[state]);
899 /* remember most recent substate */
900 if (mm->state == GSM48_MM_ST_MM_IDLE)
901 mm->mr_substate = mm->substate;
904 mm->substate = substate;
906 /* resend detach event, if flag is set */
907 if (state == GSM48_MM_ST_MM_IDLE && mm->delay_detach) {
910 mm->delay_detach = 0;
912 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
915 gsm48_mmevent_msg(mm->ms, nmsg);
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",
930 gsm48_mm_loc_upd(mm->ms, NULL);
931 /* must exit, because this function can be called
936 if (mm->lupd_periodic) {
937 struct gsm48_sysinfo *s = &mm->ms->cellsel.sel_si;
939 LOGP(DMM, LOGL_INFO, "Periodic loc. upd. pending "
940 "(type %d)\n", mm->lupd_type);
941 mm->lupd_periodic = 0;
943 gsm48_mm_loc_upd_periodic(mm->ms, NULL);
945 LOGP(DMM, LOGL_INFO, "but not requred\n");
946 /* must exit, because this function can be called
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 */
962 /* return PLMN SEARCH or PLMN SEARCH NORMAL state */
963 static int gsm48_mm_set_plmn_search(struct osmocom_ms *ms)
965 struct gsm_subscriber *subscr = &ms->subscr;
966 struct gsm322_cellsel *cs = &ms->cellsel;
968 /* SIM not inserted */
969 if (!subscr->sim_valid) {
970 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
972 return GSM48_MM_SST_PLMN_SEARCH;
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;
981 if (subscr->lac == 0x0000 || subscr->lac >= 0xfffe) {
982 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
983 "LAI in SIM not valid.\n");
984 return GSM48_MM_SST_PLMN_SEARCH;
987 /* no cell selected */
989 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
990 "no cell selected.\n");
991 return GSM48_MM_SST_PLMN_SEARCH;
994 /* selected cell's LAI not equal to LAI stored on the sim */
995 if (cs->sel_mcc != subscr->mcc
996 || cs->sel_mnc != subscr->mnc
997 || cs->sel_lac != subscr->lac) {
998 LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
999 "LAI of selected cell (MCC %s MNC %s LAC 0x%04x) "
1000 "!= LAI in SIM (MCC %s MNC %s LAC 0x%04x).\n",
1001 gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc),
1002 cs->sel_lac, gsm_print_mcc(subscr->mcc),
1003 gsm_print_mnc(subscr->mnc), subscr->lac);
1004 return GSM48_MM_SST_PLMN_SEARCH;
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;
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)
1015 struct gsm_subscriber *subscr = &ms->subscr;
1016 struct gsm48_mmlayer *mm = &ms->mmlayer;
1017 struct gsm322_cellsel *cs = &ms->cellsel;
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;
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 "
1030 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1031 gsm48_mm_set_plmn_search(ms));
1036 /* no SIM present or invalid */
1037 if (!subscr->sim_valid) {
1038 LOGP(DMM, LOGL_INFO, "SIM invalid as returning to MM IDLE\n");
1040 /* stop periodic location updating */
1041 mm->lupd_pending = 0;
1042 stop_mm_t3212(mm); /* 4.4.2 */
1044 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_IMSI);
1049 /* selected cell equals the registered LAI */
1050 if (subscr->lac /* valid */
1051 && cs->sel_mcc == subscr->mcc
1052 && cs->sel_mnc == subscr->mnc
1053 && cs->sel_lac == subscr->lac) {
1054 LOGP(DMM, LOGL_INFO, "We are in registered LAI as returning "
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);
1061 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1062 GSM48_MM_SST_NORMAL_SERVICE);
1067 /* location update allowed */
1068 if (cs->state == GSM322_C3_CAMPED_NORMALLY) {
1069 LOGP(DMM, LOGL_INFO, "We are camping normally as returning to "
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 "
1076 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
1077 GSM48_MM_SST_LIMITED_SERVICE);
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)
1086 struct gsm48_mmlayer *mm = &ms->mmlayer;
1088 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_CELL_AVAIL);
1093 /* 4.2.1.1 Service state PLMN SEARCH (NORMAL) / NO CELL AVAILABLE is left
1096 static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg)
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;
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);
1113 /* SIM not updated in this LA */
1114 if (subscr->ustate == GSM_SIM_U1_UPDATED
1115 && subscr->lac /* valid */
1116 && cs->sel_mcc == subscr->mcc
1117 && cs->sel_mnc == subscr->mnc
1118 && cs->sel_lac == subscr->lac
1119 && !mm->lupd_periodic) {
1120 if (subscr->imsi_attached) {
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);
1127 /* send message to PLMN search process */
1128 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
1131 gsm322_plmn_sendmsg(ms, nmsg);
1135 if (!s->att_allowed) {
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);
1142 /* send message to PLMN search process */
1143 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
1146 gsm322_plmn_sendmsg(ms, nmsg);
1150 /* else, continue */
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,
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);
1164 /* send message to PLMN search process */
1165 nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
1168 gsm322_plmn_sendmsg(ms, nmsg);
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)) {
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);
1183 /* send message to PLMN search process */
1184 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
1187 gsm322_plmn_sendmsg(ms, nmsg);
1193 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LOC_UPD_NEEDED);
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)
1201 struct gsm48_mmlayer *mm = &ms->mmlayer;
1203 new_mm_state(mm, GSM48_MM_ST_MM_IDLE, gsm48_mm_set_plmn_search(ms));
1212 /* initialize Mobility Management process */
1213 int gsm48_mm_init(struct osmocom_ms *ms)
1215 struct gsm48_mmlayer *mm = &ms->mmlayer;
1217 memset(mm, 0, sizeof(*mm));
1220 LOGP(DMM, LOGL_INFO, "init Mobility Management process\n");
1223 mm->state = GSM48_MM_ST_MM_IDLE;
1224 mm->substate = gsm48_mm_set_plmn_search(ms);
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);
1236 /* exit MM process */
1237 int gsm48_mm_exit(struct osmocom_ms *ms)
1239 struct gsm48_mmlayer *mm = &ms->mmlayer;
1240 struct gsm48_mm_conn *conn;
1243 LOGP(DMM, LOGL_INFO, "exit Mobility Management process\n");
1246 while (!llist_empty(&mm->mm_conn)) {
1247 conn = llist_entry(mm->mm_conn.next,
1248 struct gsm48_mm_conn, list);
1251 while ((msg = msgb_dequeue(&mm->rr_upqueue)))
1253 while ((msg = msgb_dequeue(&mm->mmxx_upqueue)))
1255 while ((msg = msgb_dequeue(&mm->mmr_downqueue)))
1257 while ((msg = msgb_dequeue(&mm->event_queue)))
1273 * MM connection management
1276 static const char *gsm48_mmxx_state_names[] = {
1284 uint32_t mm_conn_new_ref = 0x80000001;
1286 /* new MM connection state */
1287 static void new_conn_state(struct gsm48_mm_conn *conn, int state)
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;
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)
1299 struct gsm48_mm_conn *conn;
1301 llist_for_each_entry(conn, &mm->mm_conn, list) {
1302 if (conn->protocol == proto &&
1303 conn->transaction_id == transaction_id)
1309 /* find MM connection by reference */
1310 struct gsm48_mm_conn *mm_conn_by_ref(struct gsm48_mmlayer *mm,
1313 struct gsm48_mm_conn *conn;
1315 llist_for_each_entry(conn, &mm->mm_conn, list) {
1316 if (conn->ref == ref)
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)
1326 struct gsm48_mm_conn *conn = talloc_zero(l23_ctx, struct gsm48_mm_conn);
1331 LOGP(DMM, LOGL_INFO, "New MM Connection (proto 0x%02x trans_id %d "
1332 "ref %d)\n", proto, transaction_id, ref);
1335 conn->state = GSM48_MMXX_ST_IDLE;
1336 conn->transaction_id = transaction_id;
1337 conn->protocol = proto;
1340 llist_add(&conn->list, &mm->mm_conn);
1345 /* destroy MM connection instance */
1346 void mm_conn_free(struct gsm48_mm_conn *conn)
1348 LOGP(DMM, LOGL_INFO, "Freeing MM Connection\n");
1350 new_conn_state(conn, GSM48_MMXX_ST_IDLE);
1352 llist_del(&conn->list);
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)
1361 struct gsm48_mmlayer *mm = &ms->mmlayer;
1362 struct gsm48_mm_conn *conn, *conn2;
1364 struct gsm48_mmxx_hdr *nmmh;
1367 LOGP(DMM, LOGL_INFO, "Release any MM Connection\n");
1369 LOGP(DMM, LOGL_INFO, "Release pending MM Connections\n");
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 */
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);
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);
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);
1398 /* this should not happen */
1400 continue; /* skip if not of CC type */
1402 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
1403 nmmh->cause = cause;
1404 gsm48_mmxx_upmsg(ms, nmsg);
1413 * process handlers (Common procedures)
1416 /* sending MM STATUS message */
1417 static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, uint8_t cause)
1420 struct gsm48_hdr *ngh;
1421 uint8_t *reject_cause;
1423 LOGP(DMM, LOGL_INFO, "MM STATUS (cause #%d)\n", cause);
1425 nmsg = gsm48_l3_msgb_alloc();
1428 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1429 reject_cause = msgb_put(nmsg, 1);
1431 ngh->proto_discr = GSM48_PDISC_MM;
1432 ngh->msg_type = GSM48_MT_MM_STATUS;
1433 *reject_cause = cause;
1435 /* push RR header and send down */
1436 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1439 /* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
1440 static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
1443 struct gsm48_hdr *ngh;
1445 LOGP(DMM, LOGL_INFO, "TMSI REALLOCATION COMPLETE\n");
1447 nmsg = gsm48_l3_msgb_alloc();
1450 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1452 ngh->proto_discr = GSM48_PDISC_MM;
1453 ngh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
1455 /* push RR header and send down */
1456 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
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)
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;
1469 if (payload_len < sizeof(struct gsm48_loc_area_id) + 2) {
1471 LOGP(DMM, LOGL_NOTICE, "Short read of TMSI REALLOCATION "
1472 "COMMAND message error.\n");
1476 gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
1478 mi = gh->data + sizeof(struct gsm48_loc_area_id);
1479 mi_type = mi[1] & GSM_MI_TYPE_MASK;
1481 case GSM_MI_TYPE_TMSI:
1482 if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
1485 memcpy(&tmsi, mi+2, 4);
1486 subscr->tmsi = ntohl(tmsi);
1487 LOGP(DMM, LOGL_INFO, "TMSI 0x%08x (%u) assigned.\n",
1488 subscr->tmsi, subscr->tmsi);
1489 gsm48_mm_tx_tmsi_reall_cpl(ms);
1491 case GSM_MI_TYPE_IMSI:
1492 subscr->tmsi = 0xffffffff;
1493 LOGP(DMM, LOGL_INFO, "TMSI removed.\n");
1494 gsm48_mm_tx_tmsi_reall_cpl(ms);
1497 subscr->tmsi = 0xffffffff;
1498 LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown MI "
1499 "type %d.\n", mi_type);
1500 gsm48_mm_tx_mm_status(ms, GSM48_REJECT_INCORRECT_MESSAGE);
1503 /* store LOCI on sim */
1504 gsm_subscr_write_loci(ms);
1509 /* 4.3.2.2 AUTHENTICATION REQUEST is received */
1510 static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
1512 struct gsm_subscriber *subscr = &ms->subscr;
1513 struct gsm_settings *set = &ms->settings;
1514 struct gsm48_mmlayer *mm = &ms->mmlayer;
1515 struct gsm48_hdr *gh = msgb_l3(msg);
1516 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1517 struct gsm48_auth_req *ar = (struct gsm48_auth_req *) gh->data;
1520 if (payload_len < sizeof(struct gsm48_auth_req)) {
1521 LOGP(DMM, LOGL_NOTICE, "Short read of AUTHENTICATION REQUEST "
1522 "message error.\n");
1526 /* SIM is not available */
1527 if (!subscr->sim_valid) {
1528 LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST without SIM\n");
1529 return gsm48_mm_tx_mm_status(ms,
1530 GSM48_REJECT_MSG_NOT_COMPATIBLE);
1533 LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST (seq %d)\n", ar->key_seq);
1535 /* key_seq and random
1536 * in case of test card, there is a dummy response.
1537 * authentication request is possible during emergency call, if
1538 * IMSI is known to the network. in case of emergency IMSI, we need to
1539 * send a dummy response also.
1541 if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0])
1543 gsm_subscr_generate_kc(ms, ar->key_seq, ar->rand, no_sim);
1545 /* wait for auth response event from SIM */
1549 /* 4.3.2.2 sending AUTHENTICATION RESPONSE */
1550 static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct msgb *msg)
1552 struct gsm48_mm_event *mme = (struct gsm48_mm_event *) msg->data;
1554 struct gsm48_hdr *ngh;
1557 LOGP(DMM, LOGL_INFO, "AUTHENTICATION RESPONSE\n");
1559 nmsg = gsm48_l3_msgb_alloc();
1562 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1564 ngh->proto_discr = GSM48_PDISC_MM;
1565 ngh->msg_type = GSM48_MT_MM_AUTH_RESP;
1568 sres = msgb_put(nmsg, 4);
1569 memcpy(sres, mme->sres, 4);
1571 /* push RR header and send down */
1572 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1575 /* 4.3.2.5 AUTHENTICATION REJECT is received */
1576 static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg)
1578 struct gsm_subscriber *subscr = &ms->subscr;
1579 struct gsm48_mmlayer *mm = &ms->mmlayer;
1581 LOGP(DMM, LOGL_INFO, "AUTHENTICATION REJECT\n");
1583 stop_mm_t3212(mm); /* 4.4.2 */
1586 subscr->sim_valid = 0;
1588 /* TMSI and LAI invalid */
1589 subscr->tmsi = 0xffffffff;
1590 subscr->lac = 0x0000;
1592 /* key is invalid */
1593 subscr->key_seq = 7;
1596 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
1598 /* store LOCI on sim */
1599 gsm_subscr_write_loci(ms);
1601 /* abort IMSI detach procedure */
1602 if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
1604 struct gsm48_rr_hdr *nrrh;
1606 /* abort RR connection */
1607 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
1610 nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
1611 nrrh->cause = GSM48_RR_CAUSE_NORMAL;
1612 gsm48_rr_downmsg(ms, nmsg);
1614 /* CS process will trigger: return to MM IDLE / No SIM */
1621 /* 4.3.3.1 IDENTITY REQUEST is received */
1622 static int gsm48_mm_rx_id_req(struct osmocom_ms *ms, struct msgb *msg)
1624 struct gsm_subscriber *subscr = &ms->subscr;
1625 struct gsm48_hdr *gh = msgb_l3(msg);
1626 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1629 if (payload_len < 1) {
1630 LOGP(DMM, LOGL_NOTICE, "Short read of IDENTITY REQUEST message "
1636 mi_type = *gh->data;
1637 LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST (mi_type %d)\n", mi_type);
1639 /* check if request can be fulfilled */
1640 if (!subscr->sim_valid && mi_type != GSM_MI_TYPE_IMEI
1641 && mi_type != GSM_MI_TYPE_IMEISV) {
1642 LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST without SIM\n");
1643 return gsm48_mm_tx_mm_status(ms,
1644 GSM48_REJECT_MSG_NOT_COMPATIBLE);
1646 if (mi_type == GSM_MI_TYPE_TMSI && subscr->tmsi == 0xffffffff) {
1647 LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST of TMSI, but we have no "
1649 return gsm48_mm_tx_mm_status(ms,
1650 GSM48_REJECT_MSG_NOT_COMPATIBLE);
1653 return gsm48_mm_tx_id_rsp(ms, mi_type);
1656 /* send IDENTITY RESPONSE message */
1657 static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type)
1660 struct gsm48_hdr *ngh;
1663 LOGP(DMM, LOGL_INFO, "IDENTITY RESPONSE\n");
1665 nmsg = gsm48_l3_msgb_alloc();
1668 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1670 ngh->proto_discr = GSM48_PDISC_MM;
1671 ngh->msg_type = GSM48_MT_MM_ID_RESP;
1674 gsm48_encode_mi(buf, nmsg, ms, mi_type);
1676 /* push RR header and send down */
1677 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
1680 /* 4.3.4.1 sending IMSI DETACH INDICATION message */
1681 static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
1683 struct gsm_subscriber *subscr = &ms->subscr;
1684 struct gsm48_mmlayer *mm = &ms->mmlayer;
1685 struct gsm_support *sup = &ms->support;
1686 struct gsm48_rrlayer *rr = &ms->rrlayer;
1688 struct gsm48_hdr *ngh;
1691 struct gsm48_classmark1 cm;
1694 LOGP(DMM, LOGL_INFO, "IMSI DETACH INDICATION\n");
1696 nmsg = gsm48_l3_msgb_alloc();
1699 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
1701 ngh->proto_discr = GSM48_PDISC_MM;
1702 ngh->msg_type = GSM48_MT_MM_IMSI_DETACH_IND;
1705 if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
1706 pwr_lev = sup->pwr_lev_1800;
1708 pwr_lev = sup->pwr_lev_900;
1709 gsm48_encode_classmark1(&cm, sup->rev_lev, sup->es_ind, sup->a5_1,
1711 msgb_v_put(nmsg, *((uint8_t *)&cm));
1713 if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
1714 gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_TMSI);
1715 LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
1717 gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_IMSI);
1718 LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
1721 /* push RR header and send down */
1722 mm->est_cause = RR_EST_CAUSE_OTHER_SDCCH;
1723 return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
1726 /* detach has ended */
1727 static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
1729 struct gsm48_mmlayer *mm = &ms->mmlayer;
1730 struct gsm_subscriber *subscr = &ms->subscr;
1733 LOGP(DMM, LOGL_INFO, "IMSI has been detached.\n");
1735 /* stop IMSI detach timer (if running) */
1740 subscr->sim_valid = 0;
1742 /* wait for RR idle and then power off when IMSI is detached */
1743 if (mm->power_off) {
1744 if (mm->state == GSM48_MM_ST_MM_IDLE) {
1748 mm->power_off_idle = 1;
1753 /* send SIM remove event to gsm322 */
1754 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
1757 gsm322_plmn_sendmsg(ms, nmsg);
1759 /* CS process will trigger return to MM IDLE / No SIM */
1763 /* start an IMSI detach in MM IDLE */
1764 static int gsm48_mm_imsi_detach_start(struct osmocom_ms *ms, struct msgb *msg)
1766 struct gsm_subscriber *subscr = &ms->subscr;
1767 struct gsm48_mmlayer *mm = &ms->mmlayer;
1768 struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1770 /* we may silently finish IMSI detach */
1771 if (!s->att_allowed || !subscr->imsi_attached) {
1772 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1774 return gsm48_mm_imsi_detach_end(ms, msg);
1776 LOGP(DMM, LOGL_INFO, "IMSI detach started (MM IDLE)\n");
1778 new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
1780 /* establish RR and send IMSI detach */
1781 return gsm48_mm_tx_imsi_detach(ms, GSM48_RR_EST_REQ);
1784 /* IMSI detach has been sent, wait for RR release */
1785 static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, struct msgb *msg)
1787 struct gsm48_mmlayer *mm = &ms->mmlayer;
1789 /* start T3220 (4.3.4.1) */
1792 LOGP(DMM, LOGL_INFO, "IMSI detach started (Wait for RR release)\n");
1794 new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
1799 /* release MM connection and proceed with IMSI detach */
1800 static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
1802 struct gsm_subscriber *subscr = &ms->subscr;
1803 struct gsm48_mmlayer *mm = &ms->mmlayer;
1804 struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1806 /* stop MM connection timer */
1809 /* release all connections */
1810 gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1812 /* wait for release of RR */
1813 if (!s->att_allowed || !subscr->imsi_attached) {
1814 LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
1815 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
1818 if (mm->power_off) {
1826 /* send IMSI detach */
1827 gsm48_mm_tx_imsi_detach(ms, GSM48_RR_DATA_REQ);
1829 /* go to sent state */
1830 return gsm48_mm_imsi_detach_sent(ms, msg);
1833 /* ignore ongoing IMSI detach */
1834 static int gsm48_mm_imsi_detach_ignore(struct osmocom_ms *ms, struct msgb *msg)
1839 /* delay until state change (and then retry) */
1840 static int gsm48_mm_imsi_detach_delay(struct osmocom_ms *ms, struct msgb *msg)
1842 struct gsm48_mmlayer *mm = &ms->mmlayer;
1844 LOGP(DMM, LOGL_INFO, "IMSI detach delayed.\n");
1846 /* remember to detach later */
1847 mm->delay_detach = 1;
1852 /* 4.3.5.2 ABORT is received */
1853 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
1855 struct gsm48_mmlayer *mm = &ms->mmlayer;
1856 struct gsm_subscriber *subscr = &ms->subscr;
1857 struct gsm48_hdr *gh = msgb_l3(msg);
1858 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1859 uint8_t reject_cause;
1861 if (payload_len < 1) {
1862 LOGP(DMM, LOGL_NOTICE, "Short read of ABORT message error.\n");
1866 reject_cause = *gh->data;
1868 if (llist_empty(&mm->mm_conn)) {
1869 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while no MM "
1870 "connection is established.\n", reject_cause);
1871 return gsm48_mm_tx_mm_status(ms,
1872 GSM48_REJECT_MSG_NOT_COMPATIBLE);
1874 LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while MM connection "
1875 "is established.\n", reject_cause);
1876 /* stop MM connection timer */
1879 gsm48_mm_release_mm_conn(ms, 1, 16, 0);
1882 if (reject_cause == GSM48_REJECT_ILLEGAL_ME) {
1884 subscr->sim_valid = 0;
1886 /* TMSI and LAI invalid */
1887 subscr->tmsi = 0xffffffff;
1888 subscr->lac = 0x0000;
1890 /* key is invalid */
1891 subscr->key_seq = 7;
1894 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
1896 /* store LOCI on sim */
1897 gsm_subscr_write_loci(ms);
1899 /* CS process will trigger: return to MM IDLE / No SIM */
1906 /* 4.3.6.2 MM INFORMATION is received */
1907 static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
1909 struct gsm48_mmlayer *mm = &ms->mmlayer;
1910 struct gsm48_hdr *gh = msgb_l3(msg);
1911 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1912 struct tlv_parsed tp;
1914 if (payload_len < 0) {
1915 LOGP(DMM, LOGL_NOTICE, "Short read of MM INFORMATION message "
1919 tlv_parse(&tp, &gsm48_mm_att_tlvdef, gh->data, payload_len, 0, 0);
1922 if (TLVP_PRESENT(&tp, GSM48_IE_NAME_LONG)) {
1923 decode_network_name(mm->name_long, sizeof(mm->name_long),
1924 TLVP_VAL(&tp, GSM48_IE_NAME_LONG)-1);
1927 if (TLVP_PRESENT(&tp, GSM48_IE_NAME_SHORT)) {
1928 decode_network_name(mm->name_short, sizeof(mm->name_short),
1929 TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)-1);
1936 * process handlers for Location Update + IMSI attach (MM specific procedures)
1939 /* 4.4.2 received sysinfo change event */
1940 static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
1942 struct gsm48_mmlayer *mm = &ms->mmlayer;
1943 struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
1945 /* t3212 not changed in these states */
1946 if (mm->state == GSM48_MM_ST_MM_IDLE
1947 && (mm->substate == GSM48_MM_SST_NO_CELL_AVAIL
1948 || mm->substate == GSM48_MM_SST_LIMITED_SERVICE
1949 || mm->substate == GSM48_MM_SST_PLMN_SEARCH
1950 || mm->substate == GSM48_MM_SST_PLMN_SEARCH_NORMAL))
1953 /* new periodic location update timer timeout */
1954 if (s->t3212 && s->t3212 != mm->t3212_value) {
1955 if (bsc_timer_pending(&mm->t3212)) {
1957 struct timeval current_time;
1960 gettimeofday(¤t_time, NULL);
1961 t = mm->t3212.timeout.tv_sec - current_time.tv_sec;
1964 LOGP(DMM, LOGL_INFO, "New T3212 while timer is running "
1965 "(value %d rest %d)\n", s->t3212, t);
1967 /* rest time modulo given value */
1968 mm->t3212.timeout.tv_sec = current_time.tv_sec
1971 uint32_t rand = random();
1973 LOGP(DMM, LOGL_INFO, "New T3212 while timer is not "
1974 "running (value %d)\n", s->t3212);
1976 /* value between 0 and given value */
1977 start_mm_t3212(mm, rand % (s->t3212 + 1));
1979 mm->t3212_value = s->t3212;
1985 /* 4.4.4.1 (re)start location update
1987 * this function is called by
1988 * - normal location update
1989 * - periodic location update
1990 * - imsi attach (normal loc. upd. function)
1991 * - retry timers (T3211 and T3213)
1993 static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
1995 struct gsm48_mmlayer *mm = &ms->mmlayer;
1996 struct gsm322_cellsel *cs = &ms->cellsel;
1997 struct gsm48_sysinfo *s = &cs->sel_si;
1998 struct gsm_subscriber *subscr = &ms->subscr;
1999 struct gsm_settings *set = &ms->settings;
2003 /* (re)start only if we still require location update */
2004 if (!mm->lupd_pending) {
2005 LOGP(DMM, LOGL_INFO, "No loc. upd. pending.\n");
2009 /* must camp normally */
2010 if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2011 LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
2012 msg_type = GSM322_EVENT_REG_FAILED;
2014 LOGP(DSUM, LOGL_INFO, "Location updating not possible\n");
2016 mm->lupd_pending = 0;
2017 /* send message to PLMN search process */
2018 nmsg = gsm322_msgb_alloc(msg_type);
2021 gsm322_plmn_sendmsg(ms, nmsg);
2025 /* deny network, if disabled */
2027 LOGP(DMM, LOGL_INFO, "Loc. upd. disabled, adding "
2028 "forbidden PLMN.\n");
2029 LOGP(DSUM, LOGL_INFO, "Location updating is disabled by "
2031 gsm_subscr_add_forbidden_plmn(subscr, cs->sel_mcc,
2032 cs->sel_mnc, GSM48_REJECT_PLMN_NOT_ALLOWED);
2033 msg_type = GSM322_EVENT_ROAMING_NA;
2037 /* if LAI is forbidden, don't start */
2038 if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
2039 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
2040 msg_type = GSM322_EVENT_ROAMING_NA;
2043 if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
2044 cs->sel_mnc, cs->sel_lac)) {
2045 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
2046 msg_type = GSM322_EVENT_ROAMING_NA;
2050 /* 4.4.4.9 if cell is barred, don't start */
2051 if ((!subscr->acc_barr && s->cell_barr)
2052 || (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
2053 (s->class_barr ^ 0xffff)))) {
2054 LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
2055 msg_type = GSM322_EVENT_ROAMING_NA;
2059 mm->lupd_mcc = cs->sel_mcc;
2060 mm->lupd_mnc = cs->sel_mnc;
2061 mm->lupd_lac = cs->sel_lac;
2063 LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %s, MNC %s "
2064 "LAC 0x%04x)\n", gsm_print_mcc(mm->lupd_mcc),
2065 gsm_print_mnc(mm->lupd_mnc), mm->lupd_lac);
2067 return gsm48_mm_tx_loc_upd_req(ms);
2070 /* initiate a normal location update / imsi attach */
2071 static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg)
2073 struct gsm48_mmlayer *mm = &ms->mmlayer;
2074 struct gsm_subscriber *subscr = &ms->subscr;
2075 struct gsm322_cellsel *cs = &ms->cellsel;
2076 struct gsm48_sysinfo *s = &cs->sel_si;
2079 /* in case we already have a location update going on */
2080 if (mm->lupd_pending) {
2081 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2086 /* no location update, if limited service */
2087 if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
2088 LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed.\n");
2090 /* send message to PLMN search process */
2091 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2094 gsm322_plmn_sendmsg(ms, nmsg);
2099 /* if location update is not required */
2100 if (subscr->ustate == GSM_SIM_U1_UPDATED
2102 && cs->sel_mcc == subscr->mcc
2103 && cs->sel_mnc == subscr->mnc
2104 && cs->sel_lac == subscr->lac
2105 && (subscr->imsi_attached
2106 || !s->att_allowed)) {
2107 LOGP(DMM, LOGL_INFO, "Loc. upd. not required.\n");
2108 subscr->imsi_attached = 1;
2110 /* send message to PLMN search process */
2111 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2114 gsm322_plmn_sendmsg(ms, nmsg);
2119 /* 4.4.3 is attachment required? */
2120 if (subscr->ustate == GSM_SIM_U1_UPDATED
2122 && cs->sel_mcc == subscr->mcc
2123 && cs->sel_mnc == subscr->mnc
2124 && cs->sel_lac == subscr->lac
2125 && !subscr->imsi_attached
2126 && s->att_allowed) {
2127 /* do location update for IMSI attach */
2128 LOGP(DMM, LOGL_INFO, "Do Loc. upd. for IMSI attach.\n");
2131 /* do normal location update */
2132 LOGP(DMM, LOGL_INFO, "Do normal Loc. upd.\n");
2136 /* start location update */
2137 mm->lupd_attempt = 0;
2138 mm->lupd_pending = 1;
2139 mm->lupd_ra_failure = 0;
2141 return gsm48_mm_loc_upd(ms, msg);
2144 /* initiate a periodic location update */
2145 static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg)
2147 struct gsm48_mmlayer *mm = &ms->mmlayer;
2149 /* in case we already have a location update going on */
2150 if (mm->lupd_pending) {
2151 LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
2155 /* start periodic location update */
2157 mm->lupd_pending = 1;
2158 mm->lupd_ra_failure = 0;
2160 return gsm48_mm_loc_upd(ms, msg);
2163 /* ignore location update */
2164 static int gsm48_mm_loc_upd_ignore(struct osmocom_ms *ms, struct msgb *msg)
2169 /* 9.2.15 send LOCATION UPDATING REQUEST message */
2170 static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
2172 struct gsm48_mmlayer *mm = &ms->mmlayer;
2173 struct gsm_support *sup = &ms->support;
2174 struct gsm_subscriber *subscr = &ms->subscr;
2175 struct gsm48_rrlayer *rr = &ms->rrlayer;
2177 struct gsm48_hdr *ngh;
2178 struct gsm48_loc_upd_req *nlu; /* NOTE: mi_len is part of struct */
2182 LOGP(DMM, LOGL_INFO, "LOCATION UPDATING REQUEST\n");
2184 nmsg = gsm48_l3_msgb_alloc();
2187 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2188 nlu = (struct gsm48_loc_upd_req *)msgb_put(nmsg, sizeof(*nlu));
2190 ngh->proto_discr = GSM48_PDISC_MM;
2191 ngh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
2193 /* location updating type */
2194 nlu->type = mm->lupd_type;
2196 nlu->key_seq = subscr->key_seq;
2197 /* LAI (last SIM stored LAI)
2199 * NOTE: The TMSI is only valid within a LAI!
2201 gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
2203 if (rr->cd_now.arfcn >= 512 && rr->cd_now.arfcn <= 885)
2204 pwr_lev = sup->pwr_lev_1800;
2206 pwr_lev = sup->pwr_lev_900;
2207 gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind,
2208 sup->a5_1, pwr_lev);
2210 if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
2211 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2212 LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
2214 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2215 LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
2217 msgb_put(nmsg, buf[1]); /* length is part of nlu */
2218 memcpy(&nlu->mi_len, buf + 1, 1 + buf[1]);
2220 new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
2222 /* push RR header and send down */
2223 mm->est_cause = RR_EST_CAUSE_LOC_UPD;
2224 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, mm->est_cause);
2227 /* 4.4.4.1 RR is esablised during location update */
2228 static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
2230 struct gsm48_mmlayer *mm = &ms->mmlayer;
2232 /* start location update timer */
2235 new_mm_state(mm, GSM48_MM_ST_LOC_UPD_INIT, 0);
2240 /* 4.4.4.6 LOCATION UPDATING ACCEPT is received */
2241 static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
2243 struct gsm48_mmlayer *mm = &ms->mmlayer;
2244 struct gsm_subscriber *subscr = &ms->subscr;
2245 struct gsm48_hdr *gh = msgb_l3(msg);
2246 struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
2247 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2248 struct tlv_parsed tp;
2251 if (payload_len < sizeof(struct gsm48_loc_area_id)) {
2253 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING ACCEPT "
2254 "message error.\n");
2257 tlv_parse(&tp, &gsm48_mm_att_tlvdef,
2258 gh->data + sizeof(struct gsm48_loc_area_id),
2259 payload_len - sizeof(struct gsm48_loc_area_id), 0, 0);
2261 /* update has finished */
2262 mm->lupd_pending = 0;
2264 /* RA was successfull */
2265 mm->lupd_ra_failure = 0;
2267 /* stop periodic location updating timer */
2268 stop_mm_t3212(mm); /* 4.4.2 */
2271 gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
2273 /* stop location update timer */
2276 /* reset attempt counter */
2277 mm->lupd_attempt = 0;
2279 /* mark SIM as attached */
2280 subscr->imsi_attached = 1;
2282 /* set the status in the sim to updated */
2283 new_sim_ustate(subscr, GSM_SIM_U1_UPDATED);
2285 /* store LOCI on sim */
2286 gsm_subscr_write_loci(ms);
2288 /* set last registered PLMN */
2289 if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
2290 subscr->plmn_valid = 1;
2291 subscr->plmn_mcc = subscr->mcc;
2292 subscr->plmn_mnc = subscr->mnc;
2295 LOGP(DSUM, LOGL_INFO, "Location update accepted\n");
2296 LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %s mnc %s "
2297 "lac 0x%04x)\n", gsm_print_mcc(subscr->mcc),
2298 gsm_print_mnc(subscr->mnc), subscr->lac);
2300 /* remove LA from forbidden list */
2301 gsm322_del_forbidden_la(ms, subscr->mcc, subscr->mnc, subscr->lac);
2304 if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
2309 mi = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)-1;
2312 mi_type = mi[1] & GSM_MI_TYPE_MASK;
2314 case GSM_MI_TYPE_TMSI:
2315 if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
2318 memcpy(&tmsi, mi+2, 4);
2319 subscr->tmsi = ntohl(tmsi);
2320 LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x (%u)\n",
2321 subscr->tmsi, subscr->tmsi);
2323 /* store LOCI on sim */
2324 gsm_subscr_write_loci(ms);
2326 /* send TMSI REALLOCATION COMPLETE */
2327 gsm48_mm_tx_tmsi_reall_cpl(ms);
2329 case GSM_MI_TYPE_IMSI:
2330 LOGP(DMM, LOGL_INFO, "TMSI removed\n");
2331 subscr->tmsi = 0xffffffff;
2333 /* store LOCI on sim */
2334 gsm_subscr_write_loci(ms);
2336 /* send TMSI REALLOCATION COMPLETE */
2337 gsm48_mm_tx_tmsi_reall_cpl(ms);
2340 LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown "
2341 "MI type %d.\n", mi_type);
2345 /* send message to PLMN search process */
2346 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
2349 gsm322_plmn_sendmsg(ms, nmsg);
2351 /* follow on proceed */
2352 if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID))
2353 LOGP(DMM, LOGL_NOTICE, "follow-on proceed not supported.\n");
2355 /* start RR release timer */
2358 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2363 /* 4.4.4.7 LOCATION UPDATING REJECT is received */
2364 static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2366 struct gsm48_mmlayer *mm = &ms->mmlayer;
2367 struct gsm48_hdr *gh = msgb_l3(msg);
2368 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2370 if (payload_len < 1) {
2371 LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING REJECT "
2372 "message error.\n");
2376 /* RA was successfull */
2377 mm->lupd_ra_failure = 0;
2379 /* stop periodic location updating timer */
2380 stop_mm_t3212(mm); /* 4.4.2 */
2382 /* stop location update timer */
2385 /* store until RR is released */
2386 mm->lupd_rej_cause = *gh->data;
2388 /* start RR release timer */
2391 new_mm_state(mm, GSM48_MM_ST_LOC_UPD_REJ, 0);
2396 /* 4.4.4.7 RR is released after location update reject */
2397 static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
2399 struct gsm48_mmlayer *mm = &ms->mmlayer;
2400 struct gsm_subscriber *subscr = &ms->subscr;
2402 struct gsm322_msg *ngm;
2404 LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n",
2405 mm->lupd_rej_cause);
2407 /* stop RR release timer */
2411 switch (mm->lupd_rej_cause) {
2412 case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2413 case GSM48_REJECT_ILLEGAL_MS:
2414 case GSM48_REJECT_ILLEGAL_ME:
2415 /* reset attempt counter */
2416 mm->lupd_attempt = 0;
2419 subscr->sim_valid = 0;
2422 case GSM48_REJECT_PLMN_NOT_ALLOWED:
2423 case GSM48_REJECT_LOC_NOT_ALLOWED:
2424 case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2425 /* TMSI and LAI invalid */
2426 subscr->tmsi = 0xffffffff;
2427 subscr->lac = 0x0000;
2429 /* key is invalid */
2430 subscr->key_seq = 7;
2433 new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
2435 /* store LOCI on sim */
2436 gsm_subscr_write_loci(ms);
2438 /* update has finished */
2439 mm->lupd_pending = 0;
2442 /* send event to PLMN search process */
2443 switch(mm->lupd_rej_cause) {
2444 case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2445 nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
2447 case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2448 case GSM48_REJECT_ILLEGAL_MS:
2449 case GSM48_REJECT_ILLEGAL_ME:
2450 nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM);
2453 nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
2457 ngm = (struct gsm322_msg *)nmsg->data;
2458 ngm->reject = mm->lupd_rej_cause;
2459 gsm322_plmn_sendmsg(ms, nmsg);
2461 /* forbidden list */
2462 switch (mm->lupd_rej_cause) {
2463 case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
2464 LOGP(DSUM, LOGL_INFO, "Location update failed (IMSI unknown "
2467 case GSM48_REJECT_ILLEGAL_MS:
2468 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal MS)\n");
2470 case GSM48_REJECT_ILLEGAL_ME:
2471 LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n");
2473 case GSM48_REJECT_PLMN_NOT_ALLOWED:
2474 gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc,
2475 mm->lupd_mnc, mm->lupd_rej_cause);
2476 LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not "
2479 case GSM48_REJECT_LOC_NOT_ALLOWED:
2480 case GSM48_REJECT_ROAMING_NOT_ALLOWED:
2481 gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc,
2482 mm->lupd_lac, mm->lupd_rej_cause);
2483 LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not "
2487 /* 4.4.4.9 continue with failure handling */
2488 return gsm48_mm_loc_upd_failed(ms, NULL);
2491 /* CS proc triggers: return to IDLE, case 13 is also handled there */
2495 /* 4.2.2 delay a location update */
2496 static int gsm48_mm_loc_upd_delay_per(struct osmocom_ms *ms, struct msgb *msg)
2498 struct gsm48_mmlayer *mm = &ms->mmlayer;
2500 LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2501 mm->lupd_periodic = 1;
2506 /* delay a location update retry */
2507 static int gsm48_mm_loc_upd_delay_retry(struct osmocom_ms *ms, struct msgb *msg)
2509 struct gsm48_mmlayer *mm = &ms->mmlayer;
2511 LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
2517 /* process failues as described in the lower part of 4.4.4.9 */
2518 static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
2520 struct gsm48_mmlayer *mm = &ms->mmlayer;
2521 struct gsm_subscriber *subscr = &ms->subscr;
2523 LOGP(DSUM, LOGL_INFO, "Location update failed\n");
2525 /* stop location update timer, if running */
2528 if (subscr->ustate == GSM_SIM_U1_UPDATED
2529 && mm->lupd_mcc == subscr->mcc
2530 && mm->lupd_mnc == subscr->mnc
2531 && mm->lupd_lac == subscr->lac) {
2532 if (mm->lupd_attempt < 4) {
2533 LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2534 LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
2537 /* start update retry timer */
2540 /* CS process will trigger: return to MM IDLE */
2543 LOGP(DMM, LOGL_INFO, "Loc. upd. failed too often.\n");
2546 /* TMSI and LAI invalid */
2547 subscr->tmsi = 0xffffffff;
2548 subscr->lac = 0x0000;
2550 /* key is invalid */
2551 subscr->key_seq = 7;
2554 new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2556 /* store LOCI on sim */
2557 gsm_subscr_write_loci(ms);
2559 /* start update retry timer (RR connection is released) */
2560 if (mm->lupd_attempt < 4) {
2561 mm->start_t3211 = 1;
2562 LOGP(DSUM, LOGL_INFO, "Try location update later\n");
2565 /* CS process will trigger: return to MM IDLE */
2569 /* abort a location update due to radio failure or release */
2570 static int gsm48_mm_rel_loc_upd_abort(struct osmocom_ms *ms, struct msgb *msg)
2572 struct gsm48_mmlayer *mm = &ms->mmlayer;
2573 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
2575 /* stop RR release timer */
2578 if (rrh->msg_type == GSM48_RR_REL_IND) {
2579 LOGP(DMM, LOGL_INFO, "RR link released after loc. upd.\n");
2581 /* continue with failure handling */
2582 return gsm48_mm_loc_upd_failed(ms, NULL);
2585 LOGP(DMM, LOGL_INFO, "Loc. upd. aborted by radio (cause #%d)\n",
2588 /* random access failure, but not two successive failures */
2589 if (rrh->cause == RR_REL_CAUSE_RA_FAILURE && !mm->lupd_ra_failure) {
2590 mm->lupd_ra_failure = 1;
2592 /* start RA failure timer */
2598 /* RA was successfull or sent twice */
2599 mm->lupd_ra_failure = 0;
2601 /* continue with failure handling */
2602 return gsm48_mm_loc_upd_failed(ms, NULL);
2605 /* location update has timed out */
2606 static int gsm48_mm_loc_upd_timeout(struct osmocom_ms *ms, struct msgb *msg)
2609 struct gsm48_rr_hdr *nrrh;
2611 /* abort RR connection */
2612 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
2615 nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
2616 nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
2617 gsm48_rr_downmsg(ms, nmsg);
2619 /* continue with failure handling */
2620 return gsm48_mm_loc_upd_failed(ms, NULL);
2624 * process handlers for MM connections
2627 /* cm reestablish request message from upper layer */
2628 static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
2631 struct gsm48_mmlayer *mm = &ms->mmlayer;
2632 struct gsm_subscriber *subscr = &ms->subscr;
2633 struct gsm_settings *set = &ms->settings;
2635 struct gsm48_hdr *ngh;
2636 struct gsm48_service_request *nsr; /* NOTE: includes MI length */
2640 LOGP(DMM, LOGL_INFO, "CM SERVICE REQUEST (cause %d)\n", mm->est_cause);
2642 nmsg = gsm48_l3_msgb_alloc();
2645 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2646 nsr = (struct gsm48_service_request *)msgb_put(nmsg, sizeof(*nsr));
2647 cm2lv = (uint8_t *)&nsr->classmark;
2649 ngh->proto_discr = GSM48_PDISC_MM;
2650 ngh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
2653 nsr->cm_service_type = cm_serv;
2654 nsr->cipher_key_seq = subscr->key_seq;
2656 cm2lv[0] = sizeof(struct gsm48_classmark2);
2657 gsm48_rr_enc_cm2(ms, (struct gsm48_classmark2 *)(cm2lv + 1));
2659 if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0]) {
2660 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s for emergency\n",
2661 set->emergency_imsi);
2662 gsm48_generate_mid_from_imsi(buf, set->emergency_imsi);
2664 if (!subscr->sim_valid) { /* have no SIM ? */
2665 LOGP(DMM, LOGL_INFO, "-> Using IMEI %s\n",
2667 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMEI);
2669 if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
2670 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
2671 LOGP(DMM, LOGL_INFO, "-> Using TMSI\n");
2673 gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
2674 LOGP(DMM, LOGL_INFO, "-> Using IMSI %s\n",
2677 msgb_put(nmsg, buf[1]); /* length is part of nsr */
2678 memcpy(&nsr->mi_len, buf + 1, 1 + buf[1]);
2679 /* prio is optional for eMLPP */
2681 /* push RR header and send down */
2682 return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
2685 /* cm service abort message from upper layer
2686 * NOTE: T3240 is started by the calling function
2688 static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms)
2691 struct gsm48_hdr *ngh;
2693 LOGP(DMM, LOGL_INFO, "CM SERVICE ABORT\n");
2695 nmsg = gsm48_l3_msgb_alloc();
2698 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
2700 ngh->proto_discr = GSM48_PDISC_MM;
2701 ngh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
2703 /* push RR header and send down */
2704 return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
2707 /* cm service acknowledge is received from lower layer */
2708 static int gsm48_mm_rx_cm_service_acc(struct osmocom_ms *ms, struct msgb *msg)
2710 struct gsm48_mmlayer *mm = &ms->mmlayer;
2712 /* stop MM connection timer */
2715 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2717 return gsm48_mm_conn_go_dedic(ms);
2720 /* 9.2.6 CM SERVICE REJECT message received */
2721 static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
2723 struct gsm48_mmlayer *mm = &ms->mmlayer;
2724 struct gsm_subscriber *subscr = &ms->subscr;
2725 struct gsm48_hdr *gh = msgb_l3(msg);
2726 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
2727 uint8_t abort_any = 0;
2728 uint8_t reject_cause;
2730 if (payload_len < 1) {
2731 LOGP(DMM, LOGL_NOTICE, "Short read of cm service reject "
2732 "message error.\n");
2737 reject_cause = *gh->data;
2739 LOGP(DMM, LOGL_INFO, "CM SERVICE REJECT (cause %d)\n", reject_cause);
2741 /* stop MM connection timer */
2744 /* selection action on cause value */
2745 switch (reject_cause) {
2746 case GSM48_REJECT_IMSI_UNKNOWN_IN_VLR:
2747 case GSM48_REJECT_ILLEGAL_ME:
2750 /* TMSI and LAI invalid */
2751 subscr->tmsi = 0xffffffff;
2752 subscr->lac = 0x0000;
2754 /* key is invalid */
2755 subscr->key_seq = 7;
2758 new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
2760 /* store LOCI on sim */
2761 gsm_subscr_write_loci(ms);
2763 /* change to WAIT_NETWORK_CMD state impied by abort_any == 1 */
2765 if (reject_cause == GSM48_REJECT_ILLEGAL_ME)
2766 subscr->sim_valid = 0;
2770 /* state implied by the number of remaining connections */
2774 /* release MM connection(s) */
2775 gsm48_mm_release_mm_conn(ms, abort_any, 16, 0);
2777 /* state depends on the existance of remaining MM connections */
2778 if (llist_empty(&mm->mm_conn))
2779 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2781 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
2786 /* initiate an MM connection 4.5.1.1
2788 * this function is called when:
2789 * - no RR connection exists
2790 * - an RR connection exists, but this is the first MM connection
2791 * - an RR connection exists, and there are already MM connection(s)
2793 static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
2796 struct gsm48_mmlayer *mm = &ms->mmlayer;
2797 struct gsm_subscriber *subscr = &ms->subscr;
2798 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
2799 int msg_type = mmh->msg_type;
2801 uint8_t cause = 0, cm_serv = 0, proto = 0;
2803 struct gsm48_mmxx_hdr *nmmh;
2804 struct gsm48_mm_conn *conn, *conn_found = NULL;
2806 /* reset loc. upd. counter on CM service request */
2807 mm->lupd_attempt = 0;
2809 /* find if there is already a pending connection */
2810 llist_for_each_entry(conn, &mm->mm_conn, list) {
2811 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
2817 /* if pending connection */
2819 LOGP(DMM, LOGL_INFO, "Init MM Connection, but already have "
2820 "pending MM Connection.\n");
2825 case GSM48_MMCC_EST_REQ:
2826 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND,
2827 mmh->ref, mmh->transaction_id);
2829 case GSM48_MMSS_EST_REQ:
2830 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND,
2831 mmh->ref, mmh->transaction_id);
2833 case GSM48_MMSMS_EST_REQ:
2834 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND,
2835 mmh->ref, mmh->transaction_id);
2840 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
2841 nmmh->cause = cause;
2842 gsm48_mmxx_upmsg(ms, nmsg);
2846 /* in case of an emergency setup */
2847 if (msg_type == GSM48_MMCC_EST_REQ && mmh->emergency)
2850 /* if sim is not updated */
2851 if (!emergency && subscr->ustate != GSM_SIM_U1_UPDATED) {
2852 LOGP(DMM, LOGL_INFO, "Init MM Connection, but SIM not "
2858 if (mm->state == GSM48_MM_ST_MM_IDLE) {
2859 /* current MM idle state */
2860 switch (mm->substate) {
2861 case GSM48_MM_SST_NORMAL_SERVICE:
2862 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
2863 LOGP(DMM, LOGL_INFO, "Init MM Connection.\n");
2864 break; /* allow when normal */
2865 case GSM48_MM_SST_LOC_UPD_NEEDED:
2866 case GSM48_MM_SST_ATTEMPT_UPDATE:
2867 /* store mm request if attempting to update */
2869 LOGP(DMM, LOGL_INFO, "Init MM Connection, but "
2870 "attempting to update.\n");
2873 /* TODO: implement delay and start loc upd. */
2877 /* reject if not emergency */
2879 LOGP(DMM, LOGL_INFO, "Init MM Connection, not "
2880 "in normal state.\n");
2887 LOGP(DMM, LOGL_INFO, "Init another MM Connection.\n");
2889 /* set cause, service, proto */
2891 case GSM48_MMCC_EST_REQ:
2893 cause = RR_EST_CAUSE_EMERGENCY;
2894 cm_serv = GSM48_CMSERV_EMERGENCY;
2896 cause = RR_EST_CAUSE_ORIG_TCHF;
2897 cm_serv = GSM48_CMSERV_MO_CALL_PACKET;
2899 proto = GSM48_PDISC_CC;
2901 case GSM48_MMSS_EST_REQ:
2902 cause = RR_EST_CAUSE_OTHER_SDCCH;
2903 cm_serv = GSM48_CMSERV_SUP_SERV;
2904 proto = GSM48_PDISC_NC_SS;
2906 case GSM48_MMSMS_EST_REQ:
2907 cause = RR_EST_CAUSE_OTHER_SDCCH;
2908 cm_serv = GSM48_CMSERV_SMS;
2909 proto = GSM48_PDISC_SMS;
2913 /* create MM connection instance */
2914 conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
2918 new_conn_state(conn, GSM48_MMXX_ST_CONN_PEND);
2920 /* send CM SERVICE REQUEST */
2922 mm->est_cause = cause;
2923 return gsm48_mm_tx_cm_serv_req(ms, rr_prim, cm_serv);
2928 /* 4.5.1.1 a) MM connection request triggers RR connection */
2929 static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, struct msgb *msg)
2931 struct gsm48_mmlayer *mm = &ms->mmlayer;
2934 /* start MM connection by requesting RR connection */
2935 rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_EST_REQ);
2939 new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
2944 /* 4.5.1.1 a) RR is esablised during mm connection, wait for CM accepted */
2945 static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct msgb *msg)
2947 struct gsm48_mmlayer *mm = &ms->mmlayer;
2949 /* 4.5.1.7 if there is no more MM connection */
2950 if (llist_empty(&mm->mm_conn)) {
2951 LOGP(DMM, LOGL_INFO, "MM Connection, are already gone.\n");
2953 /* start RR release timer */
2956 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
2959 return gsm48_mm_tx_cm_service_abort(ms);
2962 /* start MM connection timer */
2965 new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2970 /* 4.5.1.1 b) MM connection request on existing RR connection */
2971 static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, struct msgb *msg)
2973 struct gsm48_mmlayer *mm = &ms->mmlayer;
2976 /* start MM connection by sending data */
2977 rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
2981 /* stop "RR connection release not allowed" timer */
2984 /* start MM connection timer */
2987 new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
2992 /* 4.5.1.1 b) another MM connection request on existing RR connection */
2993 static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, struct msgb *msg)
2995 struct gsm48_mmlayer *mm = &ms->mmlayer;
2998 /* start MM connection by sending data */
2999 rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
3003 /* start MM connection timer */
3006 new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
3011 /* 4.5.1.1 b) delay on WAIT FOR NETWORK COMMAND state */
3012 static int gsm48_mm_init_mm_wait(struct osmocom_ms *ms, struct msgb *msg)
3015 gsm48_mm_init_mm_reject(ms, msg);
3017 this requires handling when leaving this state...
3019 struct gsm48_mmlayer *mm = &ms->mmlayer;
3022 /* just create the MM connection in pending state */
3023 rc = gsm48_mm_init_mm(ms, msg, 0);
3027 /* start MM connection timer */
3030 new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
3036 /* initiate an mm connection other cases */
3037 static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
3039 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3040 int msg_type = mmh->msg_type;
3042 struct gsm48_mmxx_hdr *nmmh;
3047 case GSM48_MMCC_EST_REQ:
3048 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
3049 mmh->transaction_id);
3051 case GSM48_MMSS_EST_REQ:
3052 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
3053 mmh->transaction_id);
3055 case GSM48_MMSMS_EST_REQ:
3056 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
3057 mmh->transaction_id);
3062 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3064 gsm48_mmxx_upmsg(ms, nmsg);
3069 /* accepting pending connection, got dedicated mode
3071 * this function is called:
3072 * - when ciphering command is received
3073 * - when cm service is accepted
3075 static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
3077 struct gsm48_mmlayer *mm = &ms->mmlayer;
3078 struct gsm48_mm_conn *conn, *conn_found = NULL;
3080 struct gsm48_mmxx_hdr *nmmh;
3082 /* the first and only pending connection is the recent requested */
3083 llist_for_each_entry(conn, &mm->mm_conn, list) {
3084 if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
3090 /* if no pending connection (anymore) */
3092 LOGP(DMM, LOGL_INFO, "No pending MM Connection.\n");
3097 new_conn_state(conn, GSM48_MMXX_ST_DEDICATED);
3099 /* send establishment confirm */
3101 switch(conn_found->protocol) {
3102 case GSM48_PDISC_CC:
3103 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF, conn->ref,
3104 conn->transaction_id);
3106 case GSM48_PDISC_NC_SS:
3107 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF, conn->ref,
3108 conn->transaction_id);
3110 case GSM48_PDISC_SMS:
3111 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF, conn->ref,
3112 conn->transaction_id);
3117 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3119 gsm48_mmxx_upmsg(ms, nmsg);
3124 /* a RR-SYNC-IND is received during MM connection establishment */
3125 static int gsm48_mm_sync_ind_wait(struct osmocom_ms *ms, struct msgb *msg)
3127 struct gsm48_mmlayer *mm = &ms->mmlayer;
3128 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3130 if (rrh->cause != RR_SYNC_CAUSE_CIPHERING) {
3131 LOGP(DMM, LOGL_NOTICE, "Ignore sync indication, not waiting "
3132 "for CM service\n");
3136 /* stop MM connection timer */
3139 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3141 return gsm48_mm_conn_go_dedic(ms);
3144 /* a RR-SYNC-IND is received during MM connection active */
3145 static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
3147 struct gsm48_mmlayer *mm = &ms->mmlayer;
3148 struct gsm48_mm_conn *conn;
3150 struct gsm48_mmxx_hdr *nmmh;
3152 /* stop MM connection timer */
3155 /* broadcast all MMCC connection(s) */
3156 llist_for_each_entry(conn, &mm->mm_conn, list) {
3157 /* send MMCC-SYNC-IND */
3159 switch(conn->protocol) {
3160 case GSM48_PDISC_CC:
3161 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_SYNC_IND,
3162 conn->ref, conn->transaction_id);
3166 continue; /* skip if not of CC type */
3167 nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
3169 /* copy L3 message */
3170 nmsg->l3h = msgb_put(nmsg, msgb_l3len(msg));
3171 memcpy(nmsg->l3h, msg->l3h, msgb_l3len(msg));
3172 gsm48_mmxx_upmsg(ms, nmsg);
3178 /* 4.5.1.2 RR abort/release is received during MM connection establishment */
3179 static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3181 struct gsm48_mmlayer *mm = &ms->mmlayer;
3182 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3185 /* stop RR release timer */
3188 /* this conversion is not of any standard */
3189 switch(rrh->cause) {
3190 case RR_REL_CAUSE_NOT_AUTHORIZED:
3191 case RR_REL_CAUSE_EMERGENCY_ONLY:
3192 case RR_REL_CAUSE_TRY_LATER:
3195 case RR_REL_CAUSE_NORMAL:
3202 /* stop MM connection timer */
3205 /* release all connections */
3206 gsm48_mm_release_mm_conn(ms, 1, cause, 1);
3208 /* no RR connection, so we return to MM IDLE */
3209 if (mm->state == GSM48_MM_ST_WAIT_RR_CONN_MM_CON)
3210 return gsm48_mm_return_idle(ms, NULL);
3212 /* CS process will trigger: return to MM IDLE */
3216 /* 4.5.1.2 timeout is received during MM connection establishment */
3217 static int gsm48_mm_timeout_mm_con(struct osmocom_ms *ms, struct msgb *msg)
3219 struct gsm48_mmlayer *mm = &ms->mmlayer;
3221 /* release pending connection */
3222 gsm48_mm_release_mm_conn(ms, 0, 102, 0);
3224 /* state depends on the existance of remaining MM connections */
3225 if (llist_empty(&mm->mm_conn)) {
3226 /* start RR release timer */
3229 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3231 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3236 /* respond to paging */
3237 static int gsm48_mm_est(struct osmocom_ms *ms, struct msgb *msg)
3239 struct gsm48_mmlayer *mm = &ms->mmlayer;
3241 mm->est_cause = RR_EST_CAUSE_ANS_PAG_ANY;
3242 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3248 static int gsm48_mm_data(struct osmocom_ms *ms, struct msgb *msg)
3250 struct gsm48_mmlayer *mm = &ms->mmlayer;
3251 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3252 struct gsm48_mm_conn *conn;
3253 int msg_type = mmh->msg_type;
3255 /* get connection, if not exist (anymore), release */
3256 conn = mm_conn_by_ref(mm, mmh->ref);
3258 LOGP(DMM, LOGL_INFO, "MMXX_DATA_REQ with unknown (already "
3259 "released) ref=%x, sending MMXX_REL_IND\n", mmh->ref);
3260 switch(msg_type & GSM48_MMXX_MASK) {
3261 case GSM48_MMCC_CLASS:
3262 mmh->msg_type = GSM48_MMCC_REL_IND;
3264 case GSM48_MMSS_CLASS:
3265 mmh->msg_type = GSM48_MMSS_REL_IND;
3267 case GSM48_MMSMS_CLASS:
3268 mmh->msg_type = GSM48_MMSMS_REL_IND;
3273 /* mirror message with REL_IND + cause */
3274 return gsm48_mmxx_upmsg(ms, msg);
3277 /* pull MM header */
3278 msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
3280 /* push RR header and send down */
3281 return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, 0);
3284 /* release of MM connection (active state) */
3285 static int gsm48_mm_release_active(struct osmocom_ms *ms, struct msgb *msg)
3287 struct gsm48_mmlayer *mm = &ms->mmlayer;
3288 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3289 struct gsm48_mm_conn *conn;
3291 /* get connection, if not exist (anymore), release */
3292 conn = mm_conn_by_ref(mm, mmh->ref);
3296 /* state depends on the existance of remaining MM connections */
3297 if (llist_empty(&mm->mm_conn)) {
3298 /* start RR release timer */
3301 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3303 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3308 /* release of MM connection (wait for additional state) */
3309 static int gsm48_mm_release_wait_add(struct osmocom_ms *ms, struct msgb *msg)
3311 struct gsm48_mmlayer *mm = &ms->mmlayer;
3312 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3313 struct gsm48_mm_conn *conn;
3315 /* get connection, if not exist (anymore), release */
3316 conn = mm_conn_by_ref(mm, mmh->ref);
3323 /* release of MM connection (wait for active state) */
3324 static int gsm48_mm_release_wait_active(struct osmocom_ms *ms, struct msgb *msg)
3326 struct gsm48_mmlayer *mm = &ms->mmlayer;
3327 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3328 struct gsm48_mm_conn *conn;
3330 /* get connection, if not exist (anymore), release */
3331 conn = mm_conn_by_ref(mm, mmh->ref);
3335 /* 4.5.1.7 if there is no MM connection during wait for active state */
3336 if (llist_empty(&mm->mm_conn)) {
3337 LOGP(DMM, LOGL_INFO, "No MM Connection during 'wait for "
3338 "active' state.\n");
3340 /* start RR release timer */
3343 new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
3346 return gsm48_mm_tx_cm_service_abort(ms);
3352 /* release of MM connection (wait for RR state) */
3353 static int gsm48_mm_release_wait_rr(struct osmocom_ms *ms, struct msgb *msg)
3355 struct gsm48_mmlayer *mm = &ms->mmlayer;
3356 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3357 struct gsm48_mm_conn *conn;
3359 /* get connection, if not exist (anymore), release */
3360 conn = mm_conn_by_ref(mm, mmh->ref);
3364 /* later, if RR connection is established, the CM SERIVE ABORT
3365 * message will be sent
3370 /* abort RR connection (due to T3240) */
3371 static int gsm48_mm_abort_rr(struct osmocom_ms *ms, struct msgb *msg)
3374 struct gsm48_rr_hdr *nrrh;
3376 /* send abort to RR */
3377 nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
3380 nrrh = (struct gsm48_rr_hdr *) msgb_put(nmsg, sizeof(*nrrh));
3381 nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
3382 gsm48_rr_downmsg(ms, nmsg);
3384 /* CS process will trigger: return to MM IDLE / No SIM */
3392 /* RR is released in other states */
3393 static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct msgb *msg)
3395 struct gsm48_mmlayer *mm = &ms->mmlayer;
3397 /* stop RR release timer (if running) */
3400 /* CS process will trigger: return to MM IDLE */
3408 /* state trasitions for MMxx-SAP messages from upper layers */
3409 static struct downstate {
3413 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3414 } downstatelist[] = {
3415 /* 4.2.2.1 Normal service */
3416 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3417 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3419 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3420 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3422 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3423 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3425 /* 4.2.2.2 Attempt to update / Loc. Upd. needed */
3426 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3427 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3428 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr}, /* emergency only */
3430 /* 4.2.2.3 Limited service */
3431 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3432 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3434 /* 4.2.2.4 No IMSI */
3435 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
3436 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3438 /* 4.2.2.5 PLMN search, normal service */
3439 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3440 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3442 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3443 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
3445 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3446 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
3448 /* 4.2.2.6 PLMN search */
3449 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3450 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
3452 /* 4.5.1.1 MM Connection (EST) */
3453 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3454 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_first},
3456 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3457 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_first},
3459 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
3460 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_first},
3462 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3463 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_more},
3465 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3466 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_more},
3468 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3469 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_more},
3471 {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3472 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_wait},
3474 {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3475 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_wait},
3477 {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
3478 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_wait},
3480 {ALL_STATES, ALL_STATES,
3481 GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_reject},
3483 {ALL_STATES, ALL_STATES,
3484 GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_reject},
3486 {ALL_STATES, ALL_STATES,
3487 GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_reject},
3489 /* 4.5.2.1 MM Connection (DATA) */
3490 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3491 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3492 GSM48_MMCC_DATA_REQ, gsm48_mm_data},
3494 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3495 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3496 GSM48_MMSS_DATA_REQ, gsm48_mm_data},
3498 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3499 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3500 GSM48_MMSMS_DATA_REQ, gsm48_mm_data},
3502 /* 4.5.2.1 MM Connection (REL) */
3503 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3504 GSM48_MMCC_REL_REQ, gsm48_mm_release_active},
3506 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3507 GSM48_MMSS_REL_REQ, gsm48_mm_release_active},
3509 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
3510 GSM48_MMSMS_REL_REQ, gsm48_mm_release_active},
3512 {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3513 GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_add},
3515 {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3516 GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_add},
3518 {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
3519 GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_add},
3521 {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3522 GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_active},
3524 {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3525 GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_active},
3527 {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
3528 GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_active},
3530 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3531 GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_rr},
3533 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3534 GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_rr},
3536 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
3537 GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_rr},
3541 (sizeof(downstatelist) / sizeof(struct downstate))
3543 int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg)
3545 struct gsm48_mmlayer *mm = &ms->mmlayer;
3546 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
3547 int msg_type = mmh->msg_type;
3548 struct gsm48_mm_conn *conn;
3551 /* keep up to date with the transaction ID */
3552 conn = mm_conn_by_ref(mm, mmh->ref);
3554 conn->transaction_id = mmh->transaction_id;
3556 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
3557 ms->name, get_mmxx_name(msg_type),
3558 gsm48_mm_state_names[mm->state]);
3559 if (mm->state == GSM48_MM_ST_MM_IDLE)
3560 LOGP(DMM, LOGL_INFO, "-> substate %s\n",
3561 gsm48_mm_substate_names[mm->substate]);
3562 LOGP(DMM, LOGL_INFO, "-> callref %x, transaction_id %d\n",
3563 mmh->ref, mmh->transaction_id);
3565 /* Find function for current state and message */
3566 for (i = 0; i < DOWNSLLEN; i++)
3567 if ((msg_type == downstatelist[i].type)
3568 && ((1 << mm->state) & downstatelist[i].states)
3569 && ((1 << mm->substate) & downstatelist[i].substates))
3571 if (i == DOWNSLLEN) {
3572 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3577 rc = downstatelist[i].rout(ms, msg);
3579 if (downstatelist[i].rout != gsm48_mm_data)
3585 /* state trasitions for radio ressource messages (lower layer) */
3586 static struct rrdatastate {
3589 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3590 } rrdatastatelist[] = {
3592 {SBIT(GSM48_MM_ST_MM_IDLE),
3593 GSM48_RR_EST_IND, gsm48_mm_est},
3596 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 */
3597 GSM48_RR_EST_CNF, gsm48_mm_imsi_detach_sent},
3599 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (unsuc.) */
3600 GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3601 /* also this may happen if SABM is ackwnowledged with DISC */
3603 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (lost) */
3604 GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3606 {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (unsuc.) */
3607 GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
3609 {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (lost) */
3610 GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
3612 /* location update */
3613 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
3614 GSM48_RR_EST_CNF, gsm48_mm_est_loc_upd},
3616 {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3617 SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3618 GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_abort},
3620 {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
3621 SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
3622 GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_abort},
3624 {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3625 GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
3627 {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
3628 GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_rej},
3630 /* MM connection (EST) */
3631 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
3632 GSM48_RR_EST_CNF, gsm48_mm_est_mm_con},
3634 /* MM connection (DATA) */
3636 GSM48_RR_DATA_IND, gsm48_mm_data_ind},
3638 /* MM connection (SYNC) */
3639 {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3640 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.1 */
3641 GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_wait},
3643 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE),
3644 GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_active},
3646 /* MM connection (REL/ABORT) */
3647 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3648 SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3649 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3650 GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3652 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
3653 SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
3654 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
3655 GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3657 /* MM connection (REL/ABORT with re-establishment possibility) */
3658 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), /* not supported */
3659 GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
3661 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
3662 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* not supported */
3663 GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
3665 /* other (also wait for network command) */
3667 GSM48_RR_REL_IND, gsm48_mm_rel_other},
3670 GSM48_RR_ABORT_IND, gsm48_mm_rel_other},
3673 #define RRDATASLLEN \
3674 (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
3676 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
3678 struct gsm48_mmlayer *mm = &ms->mmlayer;
3679 struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
3680 int msg_type = rrh->msg_type;
3683 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s\n",
3684 ms->name, get_rr_name(msg_type),
3685 gsm48_mm_state_names[mm->state]);
3687 /* find function for current state and message */
3688 for (i = 0; i < RRDATASLLEN; i++)
3689 if ((msg_type == rrdatastatelist[i].type)
3690 && ((1 << mm->state) & rrdatastatelist[i].states))
3692 if (i == RRDATASLLEN) {
3693 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
3698 rc = rrdatastatelist[i].rout(ms, msg);
3700 if (rrdatastatelist[i].rout != gsm48_mm_data_ind)
3706 /* state trasitions for mobile managemnt messages (lower layer) */
3707 static struct mmdatastate {
3710 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3711 } mmdatastatelist[] = {
3712 {ALL_STATES, /* 4.3.1.2 */
3713 GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
3715 {ALL_STATES, /* 4.3.2.2 */
3716 GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
3718 {ALL_STATES, /* 4.3.2.5 */
3719 GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
3721 {ALL_STATES, /* 4.3.3.2 */
3722 GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
3724 {ALL_STATES, /* 4.3.5.2 */
3725 GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
3727 {ALL_STATES, /* 4.3.6.2 */
3728 GSM48_MT_MM_INFO, gsm48_mm_rx_info},
3730 {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.6 */
3731 GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
3733 {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.7 */
3734 GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
3736 {ALL_STATES, /* 4.5.1.1 */
3737 GSM48_MT_MM_CM_SERV_ACC, gsm48_mm_rx_cm_service_acc},
3739 {ALL_STATES, /* 4.5.1.1 */
3740 GSM48_MT_MM_CM_SERV_REJ, gsm48_mm_rx_cm_service_rej},
3743 #define MMDATASLLEN \
3744 (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
3746 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
3748 struct gsm48_mmlayer *mm = &ms->mmlayer;
3749 struct gsm48_hdr *gh = msgb_l3(msg);
3750 uint8_t pdisc = gh->proto_discr & 0x0f;
3751 uint8_t msg_type = gh->msg_type & 0xbf;
3752 struct gsm48_mmxx_hdr *mmh;
3753 int msg_supported = 0; /* determine, if message is supported at all */
3754 int rr_prim = -1, rr_est = -1; /* no prim set */
3759 if (msg_type == GSM48_MT_MM_NULL)
3762 if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
3763 LOGP(DMM, LOGL_NOTICE, "DATA IND ignored during IMSI "
3767 /* pull the RR header */
3768 msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
3770 /* create transaction (if not exists) and push message */
3772 case GSM48_PDISC_CC:
3773 rr_prim = GSM48_MMCC_DATA_IND;
3774 rr_est = GSM48_MMCC_EST_IND;
3777 case GSM48_PDISC_NC_SS:
3778 rr_prim = GSM48_MMSS_DATA_IND;
3779 rr_est = GSM48_MMSS_EST_IND;
3781 case GSM48_PDISC_SMS:
3782 rr_prim = GSM48_MMSMS_DATA_IND;
3783 rr_est = GSM48_MMSMS_EST_IND;
3787 if (rr_prim != -1) {
3788 uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
3790 struct gsm48_mm_conn *conn;
3792 /* find transaction, if any */
3793 conn = mm_conn_by_id(mm, pdisc, transaction_id);
3795 /* create MM connection instance */
3797 conn = mm_conn_new(mm, pdisc, transaction_id,
3804 /* push new header */
3805 msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
3806 mmh = (struct gsm48_mmxx_hdr *)msg->data;
3807 mmh->msg_type = rr_prim;
3808 mmh->ref = conn->ref;
3810 /* go MM CONN ACTIVE state */
3811 if (mm->state == GSM48_MM_ST_WAIT_NETWORK_CMD
3812 || mm->state == GSM48_MM_ST_RR_CONN_RELEASE_NA) {
3813 /* stop RR release timer */
3816 /* stop "RR connection release not allowed" timer */
3819 new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
3823 /* forward message */
3825 case GSM48_PDISC_MM:
3826 skip_ind = (gh->proto_discr & 0xf0) >> 4;
3828 /* ignore if skip indicator is not B'0000' */
3831 break; /* follow the selection proceedure below */
3833 case GSM48_PDISC_CC:
3834 return gsm48_rcv_cc(ms, msg);
3837 case GSM48_PDISC_NC_SS:
3838 return gsm48_rcv_ss(ms, msg);
3840 case GSM48_PDISC_SMS:
3841 return gsm48_rcv_sms(ms, msg);
3845 LOGP(DMM, LOGL_NOTICE, "Protocol type 0x%02x unsupported.\n",
3848 return gsm48_mm_tx_mm_status(ms,
3849 GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3852 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
3853 get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
3855 stop_mm_t3212(mm); /* 4.4.2 */
3857 /* 11.2 re-start pending RR release timer */
3858 if (bsc_timer_pending(&mm->t3240)) {
3863 /* find function for current state and message */
3864 for (i = 0; i < MMDATASLLEN; i++) {
3865 if (msg_type == mmdatastatelist[i].type)
3867 if ((msg_type == mmdatastatelist[i].type)
3868 && ((1 << mm->state) & mmdatastatelist[i].states))
3871 if (i == MMDATASLLEN) {
3873 if (msg_supported) {
3874 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this "
3876 return gsm48_mm_tx_mm_status(ms,
3877 GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
3879 LOGP(DMM, LOGL_NOTICE, "Message not supported.\n");
3880 return gsm48_mm_tx_mm_status(ms,
3881 GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
3885 rc = mmdatastatelist[i].rout(ms, msg);
3892 /* state trasitions for mobile management events */
3893 static struct eventstate {
3897 int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
3898 } eventstatelist[] = {
3899 /* 4.2.3 return to MM IDLE */
3900 {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3901 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found},
3903 {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
3904 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_return_idle},
3906 /* 4.2.2.1 Normal service */
3907 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3908 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3910 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3911 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3913 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3914 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3916 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3917 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3919 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3920 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3922 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
3923 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3925 /* 4.2.2.2 Attempt to update / Loc. upd. needed */
3926 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3927 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3928 GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3930 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3931 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3932 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3934 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
3935 SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
3936 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
3938 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3939 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
3941 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3942 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
3944 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
3945 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
3947 /* 4.2.2.3 Limited service */
3948 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3949 GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3951 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3952 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_plmn_search}, /* 4.2.1.2 */
3954 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3955 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* if allow. */
3957 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
3958 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3960 /* 4.2.2.4 No IMSI */
3961 /* 4.2.2.5 PLMN search, normal service */
3962 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3963 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3965 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3966 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3968 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3969 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd_delay_retry},
3971 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3972 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_delay_retry},
3974 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3975 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3977 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
3978 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
3980 /* 4.2.2.6 PLMN search */
3981 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3982 GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
3984 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3985 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3987 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
3988 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3990 /* No cell available */
3991 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3992 GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
3994 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
3995 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
3997 /* IMSI detach in other cases */
3998 {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES, /* silently detach */
3999 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_end},
4001 {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
4002 SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
4003 SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
4004 SBIT(GSM48_MM_ST_WAIT_REEST) |
4005 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON) |
4006 SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
4007 SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES, /* we can release */
4008 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_release},
4010 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D) |
4011 SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
4012 SBIT(GSM48_MM_ST_IMSI_DETACH_PEND), ALL_STATES, /* ignore */
4013 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_ignore},
4015 {ALL_STATES, ALL_STATES,
4016 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
4018 {GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
4019 GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
4021 /* location update in other cases */
4022 {ALL_STATES, ALL_STATES,
4023 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_ignore},
4025 {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4026 GSM48_MM_EVENT_TIMEOUT_T3210, gsm48_mm_loc_upd_timeout},
4028 {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
4029 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_failed},
4030 /* 4.4.4.9 c) (but without retry) */
4033 {ALL_STATES, ALL_STATES,
4034 GSM48_MM_EVENT_SYSINFO, gsm48_mm_sysinfo},
4036 /* T3240 timed out */
4037 {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
4038 SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES, /* 4.4.4.8 */
4039 GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
4041 /* T3230 timed out */
4042 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
4043 GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
4045 /* SIM reports SRES */
4046 {ALL_STATES, ALL_STATES, /* 4.3.2.2 */
4047 GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
4050 /* change in classmark is reported */
4051 {ALL_STATES, ALL_STATES,
4052 GSM48_MM_EVENT_CLASSMARK_CHG, gsm48_mm_classm_chg},
4056 #define EVENTSLLEN \
4057 (sizeof(eventstatelist) / sizeof(struct eventstate))
4059 static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg)
4061 struct gsm48_mmlayer *mm = &ms->mmlayer;
4064 if (mm->state == GSM48_MM_ST_MM_IDLE)
4065 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4066 "MM IDLE, %s\n", ms->name, get_mmevent_name(msg_type),
4067 gsm48_mm_substate_names[mm->substate]);
4069 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
4070 "%s\n", ms->name, get_mmevent_name(msg_type),
4071 gsm48_mm_state_names[mm->state]);
4073 /* Find function for current state and message */
4074 for (i = 0; i < EVENTSLLEN; i++)
4075 if ((msg_type == eventstatelist[i].type)
4076 && ((1 << mm->state) & eventstatelist[i].states)
4077 && ((1 << mm->substate) & eventstatelist[i].substates))
4079 if (i == EVENTSLLEN) {
4080 LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
4084 rc = eventstatelist[i].rout(ms, msg);
4090 * MM Register (SIM insert and remove)
4093 /* register new SIM card and trigger attach */
4094 static int gsm48_mmr_reg_req(struct osmocom_ms *ms)
4096 struct gsm48_mmlayer *mm = &ms->mmlayer;
4099 /* schedule insertion of SIM */
4100 nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_INSERT);
4103 gsm322_plmn_sendmsg(ms, nmsg);
4105 /* 4.2.1.2 SIM is inserted in state NO IMSI */
4106 if (mm->state == GSM48_MM_ST_MM_IDLE
4107 && mm->substate == GSM48_MM_SST_NO_IMSI)
4108 new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
4109 gsm48_mm_set_plmn_search(ms));
4114 /* trigger detach of sim card */
4115 static int gsm48_mmr_nreg_req(struct osmocom_ms *ms)
4117 struct gsm48_mmlayer *mm = &ms->mmlayer;
4120 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
4123 gsm48_mmevent_msg(mm->ms, nmsg);
4128 static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg)
4130 struct gsm48_mmr *mmr = (struct gsm48_mmr *)msg->data;
4131 int msg_type = mmr->msg_type;
4134 LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event\n", ms->name,
4135 get_mmr_name(msg_type));
4137 case GSM48_MMR_REG_REQ:
4138 rc = gsm48_mmr_reg_req(ms);
4140 case GSM48_MMR_NREG_REQ:
4141 rc = gsm48_mmr_nreg_req(ms);
4144 LOGP(DMM, LOGL_NOTICE, "Message unhandled.\n");