comparison gsm-fw/g23m-gsm/mm/mm_mms.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 9e777968b08f
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_FORP
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This Modul defines the functions for the mob. management
18 | capability of the module Mobility Managemant.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_MMS_C
23 #define MM_MMS_C
24
25 #define ENTITY_MM
26
27 /*==== INCLUDES ===================================================*/
28 #if defined (NEW_FRAME)
29
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stddef.h>
33 #include "typedefs.h"
34 #include "pcm.h"
35 #include "pconst.cdg"
36 #include "mconst.cdg"
37 #include "message.h"
38 #include "ccdapi.h"
39 #include "vsi.h"
40 #include "custom.h"
41 #include "gsm.h"
42 #include "prim.h"
43 #include "cnf_mm.h"
44 #include "mon_mm.h"
45 #include "pei.h"
46 #include "tok.h"
47 #include "mm.h"
48 #include "mm_em.h"
49
50 #else
51
52 #include <string.h>
53 #include <stdlib.h>
54 #include <stddef.h>
55 #include "stddefs.h"
56 #include "pcm.h"
57 #include "pconst.cdg"
58 #include "mconst.cdg"
59 #include "message.h"
60 #include "ccdapi.h"
61 #include "custom.h"
62 #include "gsm.h"
63 #include "prim.h"
64 #include "cnf_mm.h"
65 #include "mon_mm.h"
66 #include "vsi.h"
67 #include "pei.h"
68 #include "tok.h"
69 #include "mm.h"
70 #include "mm_em.h"
71
72 #endif
73
74 /*==== EXPORT =====================================================*/
75
76 /*==== PRIVAT =====================================================*/
77
78 /*==== TEST =====================================================*/
79
80 /*==== VARIABLES ==================================================*/
81 /* added by TISH 0418 to write simloci to FFS */
82 extern T_loc_info loc_info_ffs;
83 extern T_imsi_struct imsi_in_ffs;
84 /* added by TISH 0418 to write simloci to FFS */
85
86 /*==== FUNCTIONS ==================================================*/
87
88 LOCAL void mm_send_rr_data_ind (T_RR_DATA_IND *rr_data_ind,
89 UBYTE comp,
90 T_PRIM_TYPE snd_prim_type);
91 LOCAL void mm_cpy_net_name (T_full_net_name *net_name,
92 T_full_name *name,
93 UBYTE v_net_name);
94
95 /*
96 * -------------------------------------------------------------------
97 * SIGNAL Processing functions
98 * -------------------------------------------------------------------
99 */
100
101 /*
102 +--------------------------------------------------------------------+
103 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
104 | STATE : code ROUTINE : mm_store_tmsi |
105 +--------------------------------------------------------------------+
106
107 PURPOSE : Convert the mobile identity to the internal TMSI
108 representation.
109
110 */
111
112 LOCAL void mm_store_tmsi (const T_mob_id *moi)
113 {
114 GET_INSTANCE_DATA;
115 TRACE_FUNCTION ("mm_store_tmsi()");
116
117 mm_data->reg.tmsi =
118 (((ULONG)moi->tmsi.b_tmsi[0]) << 24) +
119 (((ULONG)moi->tmsi.b_tmsi[1]) << 16) +
120 (((ULONG)moi->tmsi.b_tmsi[2]) << 8) +
121 (ULONG)moi->tmsi.b_tmsi[3];
122 }
123
124 /*
125 +--------------------------------------------------------------------+
126 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
127 | STATE : code ROUTINE : mm_abort |
128 +--------------------------------------------------------------------+
129
130 PURPOSE : Process the signal ABORT.
131 The abort procedure may be invoked by the network to abort any
132 on-going MM connection establishment or already established MM
133 connection. The mobile station shall treat ABORT message as
134 compatible with current protocol state only if it is received
135 when at least one MM connection exists or an MM connection is
136 being established. [GSM 04.08 clause 4.3.5]
137
138 */
139
140 GLOBAL void mm_abort (T_D_ABORT *d_abort)
141 {
142 GET_INSTANCE_DATA;
143 TRACE_FUNCTION ("mm_abort()");
144
145 switch (GET_STATE (STATE_MM))
146 {
147 case MM_WAIT_FOR_OUTG_MM_CONN:
148 case MM_CONN_ACTIVE:
149 case MM_PROCESS_PROMPT:
150 TIMERSTOP (T3230);
151 /*FALLTHROUGH*/
152 //lint -fallthrough
153 case MM_WAIT_FOR_NW_CMD:
154
155 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD,
156 ORIGSIDE_NET,
157 MM_CAUSE,
158 d_abort->rej_cause);
159
160 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
161 {
162 /*
163 * T3212 is stopped if the first MM message is received, or
164 * ciphering mode setting is completed in the case of MM
165 * connection establishment, except when the most recent service
166 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
167 */
168 TIMERSTOP (T3212);
169 mm_data->t3212_timeout = FALSE;
170 }
171
172 switch (mm_data->rej_cause)
173 {
174 case MMCS_NETWORK_FAILURE:
175 mm_mmxx_rel_ind (RC_NETWORK_FAILURE, CM_NOT_IDLE);
176 break;
177 case MMCS_ILLEGAL_ME:
178 /*
179 * "At the receipt of the ABORT message the mobile station shall
180 * abort any MM connection establishment or call re-establishment
181 * procedure and release all MM connections (if any).
182 * If cause value #6 is received the mobile station shall
183 * delete any TMSI, LAI and ciphering key sequence number stored
184 * in the SIM, set the update status to ROAMING NOT ALLOWED (and
185 * store it in the SIM according to section 4.1.2.2) and consider
186 * the SIM invalid until switch off or the SIM is removed.
187 * As a consequence the mobile station enters state MM IDLE,
188 * substate NO IMSI after the release of the RR connection.
189 * The mobile station shall then wait for the network to release
190 * the RR connection - see section 4.5.3.1." [GSM 04.08 4.3.5]
191 */
192 /* Release all connections with appropriate cause */
193 mm_mmxx_rel_ind (mm_data->rej_cause, CM_NOT_IDLE);
194 /* Inform RR about loss of registration until power cycle */
195 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG);
196 /* Delete registration data and update SIM */
197 #ifdef REL99
198 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE);
199 #else
200 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED);
201 #endif
202 /* Delete IMSI - consider SIM as invalid */
203 mm_clear_mob_ident (&mm_data->reg.imsi_struct);
204 mm_clear_reg_data ();
205 /* Remember limited service cause for MMI information */
206 mm_data->limited_cause = mm_data->rej_cause;
207 // Debug patch >>>
208 if (mm_data->mm_idle_no_imsi_marker EQ 0)
209 mm_data->mm_idle_no_imsi_marker = 23;
210 // Debug patch <<<
211
212 break;
213 default:
214 break;
215 }
216 TIMERSTART (T3240, T_3240_VALUE);
217 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
218 break;
219
220 case MM_LUP_REJECTED:
221 case MM_LUP_INITIATED:
222 #ifdef REL99
223 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
224 #endif
225 mm_for_set_error (RC_MESSAGE_INCOMPAT);
226 break;
227
228 default:
229 break;
230 }
231 }
232
233 /*
234 +--------------------------------------------------------------------+
235 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
236 | STATE : code ROUTINE : mm_auth_rej |
237 +--------------------------------------------------------------------+
238
239 PURPOSE : Process the signal AUTH_REJ.
240
241 */
242
243 GLOBAL void mm_auth_rej (void)
244 {
245 GET_INSTANCE_DATA;
246 TRACE_FUNCTION ("mm_auth_rej()");
247
248 switch (GET_STATE (STATE_MM))
249 {
250 case MM_LUP_INITIATED:
251 case MM_WAIT_FOR_OUTG_MM_CONN:
252 case MM_CONN_ACTIVE:
253 case MM_PROCESS_PROMPT:
254 case MM_WAIT_FOR_NW_CMD:
255 #ifdef REL99
256 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
257 #endif
258 /*
259 * Upon receipt of an AUTHENTICATION REJECT message,
260 * the mobile station shall set the update status in the SIM to
261 * U2 ROAMING NOT ALLOWED, delete from the SIM the stored TMSI,
262 * LAI and ciphering key sequence number.
263 * The SIM shall be considered as invalid until switching off
264 * or the SIM is removed.
265 * If the AUTHENTICATION REJECT message is received in the state
266 * IMSI DETACH INITIATED the mobile station shall follow
267 * section 4.3.4.3. [Means: Ignore it].
268 * If the AUTHENTICATION REJECT message is received in any other
269 * state the mobile station shall abort any MM specific, MM connection
270 * establishment or call re-establishment procedure, stop any of the
271 * timers T3210 or T3230 (if running), release all MM connections
272 * (if any), start timer T3240 and enter the state WAIT FOR NETWORK
273 * COMMAND, expecting the release of the RR connection. If the RR
274 * connection is not released within a given time controlled by the
275 * timer T3240, the mobile station shall abort the RR connection.
276 * In both cases, either after a RR connection release triggered from
277 * the network side or after a RR connection abort requested by the
278 * MS-side, the MS enters state MM IDLE, substate NO IMSI.
279 * [GSM 04.08 subclause 4.3.2.5]
280 */
281
282 mm_mmxx_rel_ind (MMCS_AUTHENTICATION_REJECTED, CM_NOT_IDLE);
283
284 /*
285 * T3212 is stopped if an AUTHENTICATION REJECT message
286 * is received [GSM 04.08 subclause 4.4.2]
287 */
288 TIMERSTOP (T3212);
289 mm_data->t3212_timeout = FALSE;
290
291 TIMERSTOP (T3210);
292 TIMERSTOP (T3211);
293 TIMERSTOP (T3230);
294
295 // As this will set later MM_IDLE_NO_IMSI_STATE, we will remember
296 mm_data->mm_idle_no_imsi_marker = 129;
297
298 /*
299 * Upon receipt of an AUTHENTICATION REJECT message, the mobile station
300 * shall set the update status in the SIM to U2 ROAMING NOT ALLOWED,
301 * delete from the SIM the stored TMSI, LAI and ciphering key sequence
302 * number. [GSM 04.08 subclause 4.3.2.5]
303 */
304
305 /* Inform RR about the invalidation of the SIM */
306 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG);
307
308 /* Invalidate the SIM in MM until switch off and inform the SIM */
309 #ifdef REL99
310 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE);
311 #else
312 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED);
313 #endif
314
315 /* Invalidate SIM data after indirect call to reg_build_sim_update() */
316 mm_clear_mob_ident (&mm_data->reg.imsi_struct);
317 mm_clear_reg_data ();
318
319 /* Remember limited service reason for MMI information */
320 mm_data->limited_cause = MMCS_AUTHENTICATION_REJECTED;
321
322 /* Delete EPLMN list */
323 if (reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE))
324 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST);
325
326 #ifdef GPRS
327 /*
328 * Notify GMM about the AUTHENTICATION REJECT, not regarding whether
329 * it is active or not. For details, see GSM 04.08 subclause 4.1.1.2.
330 */
331 mm_mmgmm_auth_rej_ind ();
332 #endif
333 #ifdef REL99
334 /*Stop timer t3241 if it is ruuning.
335 *As per the spec 24.008, Timer T3241 is stopped and reset (but not started)
336 *when the MM state RR CONNECTION RELEASE NOT ALLOWED is left.
337 */
338 TIMERSTOP(T3241);
339 #endif
340 /* Enter state MM_WAIT_FOR_NW_CMD */
341 TIMERSTART (T3240, T_3240_VALUE);
342 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
343
344 EM_AUTHENTICATION(EM_REJECT);
345
346 break;
347
348 case MM_LUP_REJECTED:
349 {
350 mm_for_set_error(RC_MESSAGE_INCOMPAT);
351 }
352 break;
353
354 default:
355 break;
356 }
357 }
358
359 /*
360 +--------------------------------------------------------------------+
361 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
362 | STATE : code ROUTINE : mm_auth_req |
363 +--------------------------------------------------------------------+
364
365 PURPOSE : Process the signal AUTH_REQ.
366
367 */
368
369 GLOBAL void mm_auth_req (T_D_AUTH_REQ *auth_req)
370 {
371 GET_INSTANCE_DATA;
372 TRACE_FUNCTION ("mm_auth_req()");
373
374 switch (GET_STATE (STATE_MM))
375 {
376
377 case MM_WAIT_FOR_OUTG_MM_CONN:
378 case MM_CONN_ACTIVE:
379 case MM_WAIT_FOR_NW_CMD:
380 {
381 if ( mm_data->idle_substate EQ MM_IDLE_NO_IMSI )
382 {
383 mm_for_set_error( RC_MESSAGE_TYPE_INCOMPAT );
384 break;
385 }
386
387 }
388 /*Fall Through*/
389
390 case MM_LUP_INITIATED:
391 case MM_PROCESS_PROMPT:
392 #ifdef REL99
393 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
394 #endif
395 {
396 PALLOC (sim_auth_req, SIM_AUTHENTICATION_REQ);
397 TIMERSTOP (T3211);
398
399 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
400 {
401 /*
402 * T3212 is stopped if the first MM message is received, or
403 * ciphering mode setting is completed in the case of MM
404 * connection establishment, except when the most recent service
405 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
406 */
407 TIMERSTOP (T3212);
408 mm_data->t3212_timeout = FALSE;
409 }
410
411 TIMERSTOP (T3213);
412 mm_data->t3213_restart = 0;
413 mm_data->reg.cksn = auth_req->ciph_key_num.key_seq;
414 memcpy (sim_auth_req, auth_req,
415 sizeof (T_SIM_AUTHENTICATION_REQ));
416 reg_mmr_auth_ind (sim_auth_req);
417 if (TIMERACTIVE(T3240))
418 {
419 TIMERSTOP (T3240);
420 TIMERSTART (T3240, T_3240_VALUE);
421 }
422
423 EM_AUTHENTICATION(EM_REQUEST);
424
425 }
426 break;
427
428 case MM_LUP_REJECTED:
429 {
430 mm_for_set_error(RC_MESSAGE_INCOMPAT);
431 break;
432 }
433 default:
434 break;
435 }
436 }
437
438 /*
439 +--------------------------------------------------------------------+
440 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
441 | STATE : code ROUTINE : mm_cm_message |
442 +--------------------------------------------------------------------+
443
444 PURPOSE : Process the signal CM_MESSAGE. Normally, this means
445 that a L3 message which is for one of the CM entities
446 is forwarded to the appropriate CM entity, either as
447 MMXX_ESTABLISH_IND or MMXX_DATA_IND.
448 The following can be assumed to be true:
449 PD is either PD_CC, PD_SS or PD_SMS.
450 The ti has already been transformed by the formatter into
451 the range 0..6 for mobile originated transactions and
452 the range 8..14 for mobile terminated transactions.
453
454 */
455
456 GLOBAL void mm_cm_message (UBYTE pd,
457 UBYTE ti,
458 T_RR_DATA_IND *rr_data_ind)
459 {
460 GET_INSTANCE_DATA;
461 UBYTE comp;
462
463 TRACE_FUNCTION ("mm_cm_message()");
464
465 switch (pd)
466 {
467 case PD_CC:
468 comp = CC_COMP;
469 break;
470 case PD_SS:
471 comp = SS_COMP;
472 break;
473 case PD_SMS:
474 comp = SMS_COMP;
475 break;
476 default:
477 PFREE (rr_data_ind);
478 return;
479 }
480
481 switch (GET_STATE (STATE_MM))
482 {
483 case MM_WAIT_FOR_OUTG_MM_CONN:
484 case MM_CONN_ACTIVE:
485 case MM_PROCESS_PROMPT:
486 case MM_WAIT_FOR_NW_CMD:
487 #ifdef REL99
488 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
489 #endif
490 switch (CM_GET_STATE (comp, ti))
491 {
492 case CM_IDLE:
493 CM_SET_STATE (comp, ti, CM_ACTIVE);
494 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_EST_IND);
495
496 TIMERSTOP (T3211);
497 TIMERSTOP (T3213);
498 mm_data->t3213_restart = 0;
499 TIMERSTOP (T3240);
500 #ifdef REL99
501 /*Stop timer t3241 if it is ruuning.
502 *As per the spec 24.008, Timer T3241 is stopped and reset (but not started)
503 *when the MM state RR CONNECTION RELEASE NOT ALLOWED is left.
504 */
505 TIMERSTOP(T3241);
506 #endif
507
508 /*
509 * T3212 is stopped if the mobile station has responded to paging
510 * and thereafter has received the first correct layer 3 message
511 * except RR message. [GSM 04.08 subclause 4.4.2]
512 */
513 TIMERSTOP (T3212);
514 mm_data->t3212_timeout = FALSE;
515
516 SET_STATE (STATE_MM, MM_CONN_ACTIVE);
517 USE_STORED_ENTRIES();
518 break;
519
520 case CM_PENDING:
521 /*
522 * The connection is pending, and instead of MMXX_ESTABLISH_CNF
523 * the CM entity receives MMXX_ESTABLISH_IND. No state change
524 * in the connection table is performed.
525 * The special problem which was intended to solve here
526 * was to pass multilayer testcase MCC 100.
527 * Problem: From which GSM 11.10 testcase is MCC 100 derived?
528 * A transaction which is mobile originated has assigned ti=0..6
529 * here, a transactions which is mobile terminated has assigned
530 * ti=8..14 here.
531 * => It is impossible to have a MMXX_ESTABLISH_IND for a pending
532 * connection with a correctly working network.
533 */
534 TIMERSTOP (T3213);
535 mm_data->t3213_restart = 0;
536 TIMERSTOP (T3240);
537 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_EST_IND);
538
539 /*
540 * T3212 is stopped if the mobile station has responded to paging
541 * and thereafter has received the first correct layer 3 message
542 * except RR message. [GSM 04.08 subclause 4.4.2]
543 */
544 TIMERSTOP (T3212);
545 mm_data->t3212_timeout = FALSE;
546 break; /* case CM_PENDING */
547
548 case CM_ACTIVE:
549 TIMERSTOP (T3213);
550 mm_data->t3213_restart = 0;
551 TIMERSTOP (T3240);
552 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_DATA_IND);
553 break; /* case CM_ACTIVE */
554
555 default:
556 {
557 /* Implements Measure 29 and streamline encoding */
558 mm_send_status(RC_IDENTIFIY);
559 }
560 PFREE (rr_data_ind);
561 break;
562 }
563 break;
564
565 case MM_LUP_REJECTED:
566 case MM_LUP_INITIATED:
567 {
568 mm_for_set_error(RC_MESSAGE_INCOMPAT);
569 }
570 PFREE (rr_data_ind);
571 break;
572
573 default:
574 PFREE (rr_data_ind);
575 break;
576 }
577 }
578
579 /*
580 +--------------------------------------------------------------------+
581 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
582 | STATE : code ROUTINE : mm_cm_serv_accept |
583 +--------------------------------------------------------------------+
584
585 PURPOSE : Process the signal CM_SERV_ACCEPT.
586
587 */
588
589 GLOBAL void mm_cm_serv_accept (void)
590 {
591 GET_INSTANCE_DATA;
592 TRACE_FUNCTION ("mm_cm_serv_accept()");
593
594 switch (GET_STATE (STATE_MM))
595 {
596 case MM_WAIT_FOR_REESTABLISH:
597 case MM_LUP_INITIATED:
598 case MM_WAIT_FOR_OUTG_MM_CONN:
599 case MM_CONN_ACTIVE:
600 case MM_WAIT_FOR_NW_CMD:
601 if (mm_data->wait_for_accept)
602 {
603 mm_mmxx_est_cnf ();
604
605 /*
606 * Ensure we are not fooled by a forgotten reset of the location
607 * updating type, so check also the service state. Should not
608 * be necessary for a perfect world.
609 */
610 if (mm_data->idle_substate NEQ MM_IDLE_LIMITED_SERVICE AND
611 mm_data->idle_substate NEQ MM_IDLE_NO_IMSI AND
612 (mm_data->loc_upd_type.lut EQ PERIODIC_LUP OR
613 mm_data->loc_upd_type.lut EQ IMSI_ATTACH_LUP))
614 {
615 /*
616 * Implicit location updating accept for periodic or
617 * IMSI attach location updating request.
618 * This cannot be found in GSM 04.08,
619 * but otherwise GSM 11.10 26.7.4.3.4 would fail.
620 * For details, see GSM 11.10 subclause 26.7.4.3.4.1
621 * 1.) and 2.)
622 */
623 mm_data->loc_upd_type.lut = NOT_RUNNING;
624
625 if (mm_data->first_attach)
626 {
627 mm_data->first_attach_mem = mm_data->first_attach;
628 mm_data->first_attach = FALSE;
629 }
630 #ifdef GPRS
631 if (!mm_gsm_alone())
632 mm_data->gprs.reg_cnf_on_idle_entry = TRUE;
633 #endif /* GPRS */
634 reg_mm_success (FULL_SERVICE);
635 }
636
637 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
638 {
639 /*
640 * T3212 is stopped if the first MM message is received, or
641 * ciphering mode setting is completed in the case of MM
642 * connection establishment, except when the most recent service
643 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
644 */
645 TIMERSTOP (T3212);
646 mm_data->t3212_timeout = FALSE;
647 }
648
649 TIMERSTOP (T3211);
650 TIMERSTOP (T3213);
651 mm_data->t3213_restart = 0;
652 TIMERSTOP (T3230);
653 mm_data->wait_for_accept = FALSE;
654 SET_STATE (STATE_MM, MM_CONN_ACTIVE);
655
656 EM_CM_SERVICE_ACCEPTED(EM_CIPHERING);
657
658 USE_STORED_ENTRIES();
659 }
660 else
661 {
662 /* CM_SERV_ACCEPT not expected, send MM_STATUS */
663 mm_for_set_error(RC_MESSAGE_INCOMPAT);
664 }
665 break;
666
667 case MM_PROCESS_PROMPT:
668 case MM_LUP_REJECTED:
669 #ifdef REL99
670 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
671 #endif
672 /* CM_SERV_ACCEPT not expected, send MM_STATUS */
673 mm_for_set_error(RC_MESSAGE_INCOMPAT);
674 break;
675
676 default:
677 break;
678 }
679 }
680
681 /*
682 +--------------------------------------------------------------------+
683 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
684 | STATE : code ROUTINE : mm_cm_serv_rej |
685 +--------------------------------------------------------------------+
686
687 PURPOSE : Process the signal CM_SERV_REJ.
688
689 */
690
691 GLOBAL void mm_cm_serv_rej (T_D_CM_SERV_REJ *cm_serv_rej)
692 {
693 GET_INSTANCE_DATA;
694 TRACE_FUNCTION ("mm_cm_serv_rej()");
695
696 /* Semantical checks and preprocessing */
697 cm_serv_rej->rej_cause = for_check_reject_cause (cm_serv_rej->rej_cause);
698
699 TRACE_EVENT_P1 ("CM_SERV_REJ cause = %d", cm_serv_rej->rej_cause);
700
701 /*
702 * The behaviour is described in GSM 04.08 subclause 4.5.1.1
703 * For further details, see this recommendation.
704 */
705 switch (GET_STATE (STATE_MM))
706 {
707 case MM_WAIT_FOR_REESTABLISH:
708 case MM_WAIT_FOR_OUTG_MM_CONN:
709 case MM_CONN_ACTIVE:
710 case MM_PROCESS_PROMPT:
711 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
712 {
713 /*
714 * T3212 is stopped if the first MM message is received, or
715 * ciphering mode setting is completed in the case of MM
716 * connection establishment, except when the most recent service
717 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
718 */
719 TIMERSTOP (T3212);
720 mm_data->t3212_timeout = FALSE;
721 }
722
723 TIMERSTOP (T3211);
724 TIMERSTOP (T3213);
725 mm_data->t3213_restart = 0;
726
727 /* T3230 stopped on reception of CM_SERV_REJ or CM_SERV_ACC */
728 TIMERSTOP (T3230);
729
730 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD,
731 ORIGSIDE_NET,
732 MM_CAUSE,
733 cm_serv_rej->rej_cause);
734 switch (mm_data->rej_cause)
735 {
736 case MMCS_IMSI_IN_VLR:
737 /*
738 * CM SERVICE REJECT by the network, cause #4: For some
739 * reason the IMSI is not attached in the VLR. This may happen
740 * if there was a failure in the VLR's database.
741 * This is expected to happen seldom.
742 * GSM 11.10 subclause 26.7.5.5 doesn't expect that a call is saved
743 * and established is performed later in this condition. Choosing this
744 * implementation option complicates the protocol here too much.
745 * (danger of introducing bugs, especially if GPRS is also present)
746 * The next thing to do is a NORMAL UPDATE.
747 */
748
749
750 /*
751 * If cause value #4 is received, the mobile station aborts any
752 * MM connection, deletes any TMSI, LAI and ciphering key
753 * sequence number in the SIM, changes the update status to
754 * NOT UPDATED (and stores it in the SIM according to section
755 * 4.1.2.2), and enters the MM sublayer state WAIT FOR NETWORK
756 * COMMAND. If subsequently the RR connection is released or
757 * aborted, this will force the mobile station to initiate a
758 * normal location updating). Whether the CM request shall be
759 * memorized during the location updating procedure, is a
760 * choice of implementation.
761 * [GSM 04.08 subclause 4.5.1.1]
762 */
763
764 /* Indicate connection release to CM */
765 mm_mmxx_rel_ind (mm_data->rej_cause, CM_NOT_IDLE);
766
767 /* Invalidate update state and synchronize SIM */
768 #ifdef REL99
769 reg_invalidate_upd_state (MS_NOT_UPDATED, FALSE);
770 #else
771 reg_invalidate_upd_state (MS_NOT_UPDATED);
772 #endif
773
774 /* Invalidate TMSI in RR and lower layers */
775 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL);
776
777 /*
778 * Ensure that the conditions are set in a way that after release
779 * of the RR connection a normal update will be performed.
780 */
781 mm_data->attempt_cnt = 0;
782 mm_data->loc_upd_type.lut = NORMAL_LUP;
783
784 /* Await network release in state MM_WAIT_FOR_NW_CMD */
785 TIMERSTART (T3240, T_3240_VALUE);
786 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
787 break;
788
789 case MMCS_ILLEGAL_ME:
790 /*
791 * If cause value #6 is received, the mobile station aborts any
792 * MM connection, deletes any TMSI, LAI and ciphering key sequence
793 * number in the SIM, changes the update status to ROAMING NOT
794 * ALLOWED (and stores it in the SIM according to section
795 * 4.1.2.2), and enters the MM sublayer state WAIT FOR NETWORK
796 * COMMAND. The mobile station shall consider the SIM as invalid
797 * until switch-off or the SIM is removed.
798 * [GSM 04.08 subclause 4.5.1.1]
799 */
800
801 /* Indicate connection release to CM */
802 mm_mmxx_rel_ind (mm_data->rej_cause, CM_PENDING);
803
804 /* Invalidate update state and synchronize SIM */
805 #ifdef REL99
806 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE);
807 #else
808 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED);
809 #endif
810
811 /* Delete IMSI - consider SIM as invalid */
812 mm_clear_mob_ident (&mm_data->reg.imsi_struct);
813 mm_clear_reg_data ();
814
815 /* Inform RR about loss of registration until power cycle */
816 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG);
817
818 /* Remember limited service cause for MMI information */
819 mm_data->limited_cause = mm_data->rej_cause;
820
821 // Debug patch >>>
822 if (mm_data->mm_idle_no_imsi_marker EQ 0)
823 mm_data->mm_idle_no_imsi_marker = 6;
824 // Debug patch <<<
825
826 TIMERSTART (T3240, T_3240_VALUE);
827 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
828 break;
829
830 default:
831 /*
832 * Pending connections are only expected
833 * in state MM_CONN_ACTIVE if mm_data->wait_for_accept.
834 */
835 mm_data->wait_for_accept = FALSE;
836 if ((GET_STATE (STATE_MM) EQ MM_CONN_ACTIVE) AND
837 (mm_count_connections (CM_ACTIVE) EQ 0))
838 {
839 /*
840 * Special clash case.
841 * Seen in field for the SMS protocol when test engineers are
842 * sending SMS like crazy to themselfes, using scripts.
843 * For the CC protocol the following scenario is probably to
844 * happen, for SMS this must be something analogous:
845 * The MS sent the RELEASE message via the air interface to
846 * the network. The MSC receives this RELEASE message and
847 * sends the RELEASE_COMPLETE to the MS via the BSS and the
848 * CLEAR COMMAND message to the BSC in one single transaction.
849 * Now we have a pending clearance of the assigned radio
850 * resources. For details see "GSM Signalisierung", page 246.
851 * If there is in this situation a CM SERVICE REQUEST is
852 * received at the MSC this cannot be accepted as the
853 * clearance of the assigned radio resources are underway,
854 * so the MSC answers with a CM_SERVICE_REJECT.
855 * The only thing which can be done here is to repeat the
856 * CM_SERVICE_REQ besides the specification after entering
857 * IDLE stateto make the protocol bullet proof.
858 */
859 TRACE_EVENT ("CM_SERV_REQ clashed with CLR_CMD");
860 mm_write_entry (mm_data->pend_conn.comp,
861 mm_data->pend_conn.ti,
862 mm_data->pend_conn.cause,
863 EVENT_ENTRY,
864 NULL,
865 UNSPEC);
866 #if defined (FF_EOTD) AND defined (REL99)
867 /*
868 *If there is no MM connection & rrlp is started, start the timer3241
869 *and move MM to state MM_RR_CONN_RELEASE_NOT_ALLOWED
870 */
871 if(mm_data->rrlp_lcs_started EQ TRUE)
872 {
873 TIMERSTART(T3241,T_3241_VALUE);
874 SET_STATE(STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
875 }
876 else
877 #endif /* (FF_EOTD) AND defined (REL99) */
878 {
879 TIMERSTART (T3240, T_3240_VALUE);
880 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
881 }
882 }
883 else
884 {
885 /*
886 * Handle the CM_SERVICE_REJECT as specified in
887 * [GSM 04.08 subclause 4.5.1.1]
888 */
889 mm_mmxx_rel_ind (mm_data->rej_cause, CM_PENDING);
890 if (mm_count_connections (CM_ACTIVE) EQ 0)
891 {
892 #if defined (FF_EOTD) AND defined (REL99)
893 /*
894 *If there is no MM connection & rrlp is started, start the timer3241
895 *and move MM to state MM_RR_CONN_RELEASE_NOT_ALLOWED
896 */
897 if(mm_data->rrlp_lcs_started EQ TRUE)
898 {
899 TIMERSTART(T3241,T_3241_VALUE);
900 SET_STATE(STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
901 }
902 else
903 #endif /* (FF_EOTD) AND defined (REL99) */
904 {
905 TIMERSTART (T3240, T_3240_VALUE);
906 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
907 }
908 }
909 USE_STORED_ENTRIES();
910 }
911 break;
912 }
913
914 EM_CM_SERVICE_REJECT;
915
916 break;
917
918 case MM_LUP_REJECTED:
919 #ifdef REL99
920 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
921 #endif
922 case MM_LUP_INITIATED:
923 mm_for_set_error(RC_MESSAGE_INCOMPAT);
924 break;
925
926 default:
927 break;
928 }
929 }
930
931 /*
932 +--------------------------------------------------------------------+
933 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
934 | STATE : code ROUTINE : mm_ident_req |
935 +--------------------------------------------------------------------+
936
937 PURPOSE : Process the signal IDENT_REQ.
938
939 */
940
941 GLOBAL void mm_ident_req (T_D_IDENT_REQ *ident_req)
942 {
943 GET_INSTANCE_DATA;
944 TRACE_FUNCTION ("mm_ident_req()");
945
946 /* Message processing starts with semantical checks now */
947 if (!for_check_identity_type (MSG(D_IDENT_REQ)->ident.ident_type))
948 {
949 mm_for_set_error (RC_INVALID_MAND_MESSAGE);
950 return;
951 }
952
953
954 switch (GET_STATE (STATE_MM))
955 {
956 case MM_LUP_INITIATED:
957 case MM_WAIT_FOR_OUTG_MM_CONN:
958 case MM_CONN_ACTIVE:
959 case MM_PROCESS_PROMPT:
960 case MM_WAIT_FOR_NW_CMD:
961 #ifdef REL99
962 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
963 #endif
964 {
965 MCAST (ident_res, U_IDENT_RES); /* T_U_IDENT_RES */
966 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
967 {
968 /*
969 * T3212 is stopped if the first MM message is received, or
970 * ciphering mode setting is completed in the case of MM
971 * connection establishment, except when the most recent service
972 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
973 */
974 TIMERSTOP (T3212);
975 mm_data->t3212_timeout = FALSE;
976 }
977
978 TIMERSTOP (T3211);
979 TIMERSTOP (T3213);
980 mm_data->t3213_restart = 0;
981 mm_build_ident_res (ident_req->ident.ident_type, ident_res);
982 for_data_req (BSIZE_U_IDENT_RES);
983
984 EM_IDENTITY_REQUEST_RESPONSE;
985
986 if (TIMERACTIVE(T3240))
987 {
988 TIMERSTOP (T3240);
989 TIMERSTART (T3240, T_3240_VALUE);
990 }
991 }
992 break;
993
994 case MM_LUP_REJECTED:
995 mm_for_set_error(RC_MESSAGE_INCOMPAT);
996 break;
997
998 default:
999
1000 break;
1001 }
1002 }
1003
1004 /*
1005 +--------------------------------------------------------------------+
1006 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1007 | STATE : code ROUTINE : mm_loc_upd_acc |
1008 +--------------------------------------------------------------------+
1009
1010 PURPOSE : Process the signal LOC_UPD_ACC.
1011
1012 */
1013
1014 GLOBAL void mm_loc_upd_acc (T_D_LOC_UPD_ACCEPT *loc_upd_accept)
1015 {
1016 GET_INSTANCE_DATA;
1017 TRACE_FUNCTION ("mm_loc_upd_acc()");
1018
1019
1020 /* Semantical checks and preprocessing */
1021 if (loc_upd_accept->loc_area_ident.c_mnc EQ 2)
1022 {
1023 loc_upd_accept->loc_area_ident.mnc[2] = 0xf;
1024 }
1025
1026
1027
1028 switch (GET_STATE (STATE_MM))
1029 {
1030 case MM_LUP_INITIATED:
1031 TRACE_EVENT ("*** LUP ACCEPTED ***");
1032
1033 #ifdef WIN32
1034
1035 /*
1036 * Check whether the simulation testcases send the
1037 * LOCATION UPDATING ACCEPT message for the location area
1038 * of the cell where the mobile currently is camped on.
1039 * Receiving a non appropritate location area in the LOCATION
1040 * UPDATING ACCEPT message in the simulation environment
1041 * is probably a bug in the simulation testcase.
1042 */
1043 vsi_o_ttrace (VSI_CALLER TC_FUNC,
1044 " ACC: MCC=%x%x%x MNC=%x%x%x LAC=%04x",
1045 loc_upd_accept->loc_area_ident.mcc[0],
1046 loc_upd_accept->loc_area_ident.mcc[1],
1047 loc_upd_accept->loc_area_ident.mcc[2],
1048 loc_upd_accept->loc_area_ident.mnc[0],
1049 loc_upd_accept->loc_area_ident.mnc[1],
1050 loc_upd_accept->loc_area_ident.mnc[2],
1051 loc_upd_accept->loc_area_ident.lac);
1052
1053 assert (mm_check_lai (&loc_upd_accept->loc_area_ident,
1054 &mm_data->mm.lai));
1055
1056 #endif /* #ifdef WIN32 */
1057
1058 /*
1059 * T3212 is stopped if a LOCATION UPDATING ACCEPT or
1060 * LOCATION UPDATING REJECT message is received.
1061 * [GSM 04.08 subclause 4.4.2]
1062 */
1063 TIMERSTOP (T3212);
1064 mm_data->t3212_timeout = FALSE;
1065
1066 TIMERSTOP (T3210);
1067 mm_data->reg.update_stat = MS_UPDATED;
1068 mm_data->rej_cause = 0;
1069 mm_data->attempt_cnt = 0;
1070 if (loc_upd_accept->v_mob_id NEQ 0)
1071 {
1072 switch (loc_upd_accept->mob_id.ident_type)
1073 {
1074 case TYPE_TMSI:
1075 {
1076 MCAST (tmsi_realloc_comp, U_TMSI_REALLOC_COMP);
1077
1078 /* No IMSI ATTACH neccessary anymore */
1079 if (mm_data->first_attach)
1080 {
1081 mm_data->first_attach_mem = mm_data->first_attach;
1082 mm_data->first_attach = FALSE;
1083 }
1084
1085 /* No running location updating procedure anymore */
1086 mm_data->loc_upd_type.lut = NOT_RUNNING;
1087
1088 /* Save TMSI in MM registration data */
1089 mm_store_tmsi (&loc_upd_accept->mob_id);
1090
1091 /* Send RR_DATA_REQ (TMSI_REALLOC_COMPLETE) */
1092 tmsi_realloc_comp->msg_type = U_TMSI_REALLOC_COMP;
1093 for_data_req (BSIZE_U_TMSI_REALLOC_COMP);
1094
1095 EM_LOCATION_UPDATING;
1096
1097 /* Structure copy */
1098 mm_data->reg.lai = loc_upd_accept->loc_area_ident;
1099
1100 /*
1101 * We assume the network has updated us for the currently
1102 * selected cell, otherwise we will run into trouble.
1103 */
1104 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai));
1105
1106 /* Send RR_SYNC_REQ */
1107 mm_build_rr_sync_req_tmsi ();
1108
1109 /* Send RR_SYNC_REQ (Location Area allowed) */
1110 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
1111
1112 EM_TMSI_REALLOCATION_COMPLETE;
1113
1114 break;
1115 }
1116 case TYPE_IMSI:
1117 {
1118 /* No IMSI ATTACH neccessary anymore */
1119 if (mm_data->first_attach)
1120 {
1121 mm_data->first_attach_mem = mm_data->first_attach;
1122 mm_data->first_attach = FALSE;
1123 }
1124
1125 /* No running location updating procedure anymore */
1126 mm_data->loc_upd_type.lut = NOT_RUNNING;
1127
1128 mm_data->reg.tmsi = TMSI_INVALID_VALUE;
1129 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL);
1130
1131 /* Structure copy */
1132 mm_data->reg.lai = loc_upd_accept->loc_area_ident;
1133
1134 /*
1135 * We assume the network has updated us for the currently
1136 * selected cell, otherwise we will run into trouble.
1137 */
1138 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai));
1139
1140 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
1141
1142 EM_LOCATION_UPDATING;
1143
1144 break;
1145 }
1146 case 2: /*TYPE_IMEI:*/
1147 {
1148 /* Implements Measure 29 and streamline encoding */
1149 mm_send_status(RC_INCORRECT_MESSAGE);
1150 /* Implementation problem: This should be handled like
1151 LOCATION UPDATING REJECT received with cause NETWORK FAILURE.
1152 The same may be true for all negative asserts in the field
1153 in the whole function */
1154 break;
1155 }
1156 default:
1157 /* No IMSI ATTACH neccessary anymore */
1158 if (mm_data->first_attach)
1159 {
1160 mm_data->first_attach_mem = mm_data->first_attach;
1161 mm_data->first_attach = FALSE;
1162 }
1163
1164 /* No running location updating procedure anymore */
1165 mm_data->loc_upd_type.lut = NOT_RUNNING;
1166
1167 /* Structure copy */
1168 mm_data->reg.lai = loc_upd_accept->loc_area_ident;
1169
1170 /*
1171 * We assume the network has updated us for the currently
1172 * selected cell, otherwise we will run into trouble.
1173 */
1174 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai));
1175
1176 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
1177 break;
1178 }
1179 }
1180 else
1181 {
1182 /*
1183 * Location updating accept without mobile ID, keep old TMSI
1184 * stored in MM data structures.
1185 */
1186
1187 /* No IMSI ATTACH neccessary anymore */
1188 if (mm_data->first_attach)
1189 {
1190 mm_data->first_attach_mem = mm_data->first_attach;
1191 mm_data->first_attach = FALSE;
1192 }
1193
1194 /* No running location updating procedure anymore */
1195 mm_data->loc_upd_type.lut = NOT_RUNNING;
1196
1197 /* Structure copy */
1198 mm_data->reg.lai = loc_upd_accept->loc_area_ident;
1199
1200 /*
1201 * We assume the network has updated us for the currently
1202 * selected cell, otherwise we will run into trouble.
1203 */
1204 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai));
1205
1206 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
1207 }
1208
1209 /* remove from forbidden PLMN list if stored */
1210 reg_plmn_bad_del (mm_data->reg.forb_plmn,
1211 MAX_FORB_PLMN_ID,
1212 &mm_data->reg.actual_plmn);
1213
1214
1215 /* Store equivalent PLMNs (if received) */
1216 if (loc_upd_accept->v_eqv_plmn_list NEQ 0)
1217 {
1218 if(reg_store_eqv_plmns(&loc_upd_accept->eqv_plmn_list, &mm_data->reg.actual_plmn))
1219 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST);
1220 }
1221
1222 /* Copy actual BCCH data before SIM update */
1223 memcpy (mm_data->reg.bcch, mm_data->mm.bcch, SIZE_BCCH);
1224
1225 /* Indicate successfull end of registration to GMM/MMI */
1226 #ifdef GPRS
1227 if (!mm_gsm_alone())
1228 mm_data->gprs.reg_cnf_on_idle_entry = TRUE;
1229 #endif
1230 /* Inform MMI about full service condition (with side effects) */
1231 reg_mm_success (FULL_SERVICE);
1232
1233 /* Update all EFs on SIM */
1234 mm_data->ef_indicator = 0xFF;
1235 /* Update SIM */
1236 reg_build_sim_update ();
1237 /* added by TISH 0418 to write simloci to FFS */
1238 mm_write_simloci_to_ffs();
1239 mm_write_imsi_to_ffs();
1240 /* added by TISH 0418 to write simloci to FFS */
1241
1242 #if defined (WIN32)
1243 {
1244 TRACE_EVENT_P1 ("Follow On decoded = %d", loc_upd_accept->v_follow_proceed);
1245 }
1246 #endif /* #if defined (WIN32) */
1247
1248
1249 if (loc_upd_accept->v_follow_proceed NEQ 0 AND
1250 mm_set_follow_on_request())
1251 {
1252 SET_STATE (STATE_MM, MM_CONN_ACTIVE);
1253 mm_data->loc_upd_type.follow = FOR_PENDING_NO;
1254 mm_data->wait_for_accept = FALSE;
1255 TIMERSTART (T3230, T_3230_VALUE);
1256 TRACE_FUNCTION ("mm_loc_upd_acc () follow on - use_entry");
1257 USE_STORED_ENTRIES();
1258 }
1259 else
1260 {
1261 mm_data->loc_upd_type.follow = FOR_PENDING_NO;
1262 /* PATCH LE 02.12.99
1263 *
1264 * Don´t stop connection if not follow on proceed
1265 *
1266 * mm_mmxx_rel_ind (RELCS_UNSPECIFIED, CM_PENDING);
1267 * mm_mmxx_rel_ind (RELCS_UNSPECIFIED, CM_NOT_IDLE);
1268 *
1269 * END PATCH LE 02.12.99
1270 */
1271 TIMERSTART (T3240, T_3240_VALUE);
1272 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
1273 }
1274 break;
1275 case MM_WAIT_FOR_OUTG_MM_CONN:
1276 case MM_CONN_ACTIVE:
1277 case MM_PROCESS_PROMPT:
1278 case MM_WAIT_FOR_NW_CMD:
1279 case MM_LUP_REJECTED:
1280 #ifdef REL99
1281 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1282 #endif
1283 {
1284 mm_for_set_error(RC_MESSAGE_INCOMPAT);
1285 break;
1286 }
1287 default:
1288 break;
1289 }
1290 }
1291
1292 /*
1293 +--------------------------------------------------------------------+
1294 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1295 | STATE : code ROUTINE : mm_lup_rej |
1296 +--------------------------------------------------------------------+
1297
1298 PURPOSE : Process the signal LUP_REJ. Here the reject cause is a well
1299 defined MM cause and no garbage. Even if the network sent
1300 garbage, here this has already been corrected.
1301
1302 */
1303
1304 GLOBAL void mm_lup_rej (T_D_LOC_UPD_REJ *loc_upd_rej)
1305 {
1306 GET_INSTANCE_DATA;
1307 TRACE_FUNCTION ("mm_lup_rej()");
1308
1309 /* Semantical checks and preprocessing */
1310 loc_upd_rej->rej_cause = for_check_reject_cause (loc_upd_rej->rej_cause);
1311
1312 // Variable solely used for debugging purposes
1313 mm_data->debug_last_rej_cause = loc_upd_rej->rej_cause;
1314
1315 /* Remember cause value for MMI information */
1316 mm_data->limited_cause = CAUSE_MAKE (DEFBY_STD,
1317 ORIGSIDE_NET,
1318 MM_CAUSE,
1319 loc_upd_rej->rej_cause);
1320
1321 EM_LOCATION_UPDATING_REJECT;
1322
1323 switch (GET_STATE (STATE_MM))
1324 {
1325 case MM_LUP_INITIATED:
1326 /*
1327 * T3212 is stopped if a LOCATION UPDATING ACCEPT or
1328 * LOCATION UPDATING REJECT message is received.
1329 * [GSM 04.08 subclause 4.4.2]
1330 */
1331 TIMERSTOP (T3212);
1332 mm_data->t3212_timeout = FALSE;
1333
1334 TIMERSTOP (T3210);
1335
1336 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD,
1337 ORIGSIDE_NET,
1338 MM_CAUSE,
1339 loc_upd_rej->rej_cause);
1340
1341 TIMERSTART (T3240, T_3240_VALUE);
1342 SET_STATE (STATE_MM, MM_LUP_REJECTED);
1343 break;
1344
1345 case MM_WAIT_FOR_OUTG_MM_CONN:
1346 case MM_CONN_ACTIVE:
1347 case MM_PROCESS_PROMPT:
1348 case MM_WAIT_FOR_NW_CMD:
1349 case MM_LUP_REJECTED:
1350 #ifdef REL99
1351 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1352 #endif
1353 {
1354 mm_for_set_error(RC_MESSAGE_INCOMPAT);
1355 break;
1356 }
1357 default:
1358 break;
1359 }
1360 }
1361
1362 /*
1363 +--------------------------------------------------------------------+
1364 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1365 | STATE : code ROUTINE : mm_mm_status |
1366 +--------------------------------------------------------------------+
1367
1368 PURPOSE : Process the signal MM_STATUS.
1369
1370 */
1371
1372 GLOBAL void mm_mm_status (void)
1373 {
1374 GET_INSTANCE_DATA;
1375 TRACE_FUNCTION ("mm_mm_status()");
1376 /* Semantical checks and preprocessing */
1377 /* MSG(B_MM_STATUS)->rej_cause = for_check_reject_cause (MSG(B_MM_STATUS)->rej_cause); nobody cares */
1378
1379
1380
1381 switch (GET_STATE (STATE_MM))
1382 {
1383 case MM_LUP_INITIATED:
1384 case MM_WAIT_FOR_OUTG_MM_CONN:
1385 case MM_CONN_ACTIVE:
1386 case MM_PROCESS_PROMPT:
1387 case MM_WAIT_FOR_NW_CMD:
1388 case MM_LUP_REJECTED:
1389 #ifdef REL99
1390 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1391 #endif
1392 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
1393 {
1394 /*
1395 * T3212 is stopped if the first MM message is received, or
1396 * ciphering mode setting is completed in the case of MM
1397 * connection establishment, except when the most recent service
1398 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
1399 */
1400 TIMERSTOP (T3212);
1401 mm_data->t3212_timeout = FALSE;
1402 }
1403
1404 if (TIMERACTIVE(T3240))
1405 {
1406 TIMERSTOP (T3240);
1407 TIMERSTART (T3240, T_3240_VALUE);
1408 }
1409 break;
1410
1411 default:
1412 break;
1413 }
1414 }
1415
1416 /*
1417 +--------------------------------------------------------------------+
1418 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1419 | STATE : code ROUTINE : mm_mmr_auth_cnf |
1420 +--------------------------------------------------------------------+
1421
1422 PURPOSE : Process the signal MMR_AUTH_CNF.
1423
1424 */
1425
1426 GLOBAL void mm_mmr_auth_cnf (T_SIM_AUTHENTICATION_CNF *sim_auth_cnf)
1427 {
1428 GET_INSTANCE_DATA;
1429 TRACE_FUNCTION ("mm_mmr_auth_cnf()");
1430
1431 /* Handle the response only if it is for the last sent SIM_AUTHENTICATION_REQ */
1432 if (mm_data->last_auth_req_id EQ sim_auth_cnf->req_id)
1433 {
1434 switch (GET_STATE (STATE_MM))
1435 {
1436 case MM_LUP_INITIATED:
1437 case MM_WAIT_FOR_OUTG_MM_CONN:
1438 case MM_CONN_ACTIVE:
1439 case MM_PROCESS_PROMPT:
1440 case MM_WAIT_FOR_NW_CMD:
1441 #ifdef REL99
1442 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1443 #endif
1444 {
1445 MCAST (auth_res, U_AUTH_RES);
1446 if(memcmp(mm_data->reg.kc, sim_auth_cnf->kc, MAX_KC))
1447 {
1448 /* Set bit 4 in ef_indicator to indicate kc change to SIM for next SIM_MM_UPDATE_REQ */
1449 mm_data->ef_indicator|=(0x01 << 3);
1450 }
1451 memcpy (mm_data->reg.kc, sim_auth_cnf->kc, MAX_KC);
1452 mm_build_auth_res (sim_auth_cnf, auth_res);
1453 for_data_req (BSIZE_U_AUTH_RES);
1454 mm_build_rr_sync_req(MSG_MM_CIPH);
1455 if (TIMERACTIVE(T3240))
1456 {
1457 TIMERSTOP (T3240);
1458 TIMERSTART (T3240, T_3240_VALUE);
1459 }
1460
1461 EM_AUTHENTICATION(EM_RESPONSE);
1462
1463 }
1464 break;
1465
1466 default:
1467 break;
1468 }
1469 /* Reset the variable since there are no more auth_rsp expected from SIM */
1470 mm_data->last_auth_req_id = NOT_PRESENT_8BIT;
1471 }
1472 PFREE (sim_auth_cnf);
1473 }
1474
1475
1476 /*
1477 +--------------------------------------------------------------------+
1478 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1479 | STATE : code ROUTINE : mm_mmr_nreg_req |
1480 +--------------------------------------------------------------------+
1481
1482 PURPOSE : Process the signal MMR_NREG_REQ.
1483 The cause for the deregistration attempt may be
1484 CS_SIM_REM, CS_POW_OFF or CS_SOFT_OFF.
1485
1486 */
1487
1488 GLOBAL void mm_mmr_nreg_req (UBYTE nreg_cause,
1489 UBYTE detach_done)
1490 {
1491 GET_INSTANCE_DATA;
1492 TRACE_FUNCTION ("mm_mmr_nreg_req()");
1493
1494 switch (GET_STATE (STATE_MM))
1495 {
1496 case MM_NULL:
1497 /* No DL is active */
1498 switch (nreg_cause)
1499 {
1500 case CS_POW_OFF:
1501 case CS_SOFT_OFF:
1502 mm_write_eplmn_to_ffs();
1503 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1504 break;
1505
1506 case CS_SIM_REM:
1507 mm_write_eplmn_to_ffs();
1508 mm_clear_reg_data ();
1509 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1510 break;
1511
1512 #ifdef GPRS
1513 case CS_DISABLE: /* Remote controlled IMSI DETACH */
1514 mm_mmgmm_nreg_cnf (nreg_cause);
1515 break;
1516 #endif /* GPRS */
1517
1518 default:
1519 TRACE_ERROR (UNEXPECTED_PARAMETER);
1520 break;
1521 }
1522 break;
1523
1524 case MM_LUP_INITIATED:
1525 case MM_LUP_REJECTED:
1526 /*
1527 * We do not know the answer to the running location updating procedure.
1528 * Therefore the update state is set to MS_NOT_UPDATED here,
1529 * so MM is on the safe side if assuming it is not updated anymore.
1530 * This also leads to the situation that in this
1531 * states an IMSI DETACH will not be performed, but this is ok
1532 * according to GSM 04.08 subclause 4.3.4.1:
1533 * "The IMSI detach procedure may not be started if a MM specific
1534 * procedure is active. If possible, the IMSI detach procedure is
1535 * then delayed until the MM specific procedure is finished, else
1536 * the IMSI detach is omitted."
1537 */
1538 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL);
1539 #ifdef REL99
1540 reg_invalidate_upd_state (MS_NOT_UPDATED, FALSE);
1541 #else
1542 reg_invalidate_upd_state (MS_NOT_UPDATED);
1543 #endif
1544 /*FALLTHROUGH*/
1545 //lint -fallthrough
1546 case MM_WAIT_FOR_OUTG_MM_CONN:
1547 case MM_CONN_ACTIVE:
1548 case MM_PROCESS_PROMPT:
1549 case MM_WAIT_FOR_NW_CMD:
1550 #ifdef REL99
1551 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1552 #endif
1553 if (mm_data->mm.mm_info.att EQ ATT_ALLOW AND
1554 mm_data->reg.update_stat EQ MS_UPDATED AND
1555 detach_done EQ MMGMM_PERFORM_DETACH)
1556 {
1557 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE);
1558
1559 TIMERSTOP (T3210);
1560 TIMERSTOP (T3211);
1561
1562 /*
1563 * The timer T3212 is stopped if the mobile station is deactivated
1564 * (i.e. equipment powered down or SIM removed.
1565 */
1566 TIMERSTOP (T3212);
1567 mm_data->t3212_timeout = FALSE;
1568
1569 TIMERSTOP (T3213);
1570 mm_data->t3213_restart = 0;
1571 TIMERSTOP (T3230);
1572 TIMERSTOP (T3240);
1573 #ifdef REL99
1574 TIMERSTOP (T3241);
1575 #endif
1576
1577 /*
1578 * Start IMSI Detach procedure
1579 */
1580 if (mm_normal_upd_needed() OR
1581 mm_data->idle_substate EQ MM_IDLE_LIMITED_SERVICE)
1582 {
1583 TRACE_EVENT ("IMSI DETACH questionable");
1584 }
1585 mm_data->nreg_cause = nreg_cause;
1586 mm_create_imsi_detach_message ();
1587 for_data_req (BSIZE_U_IMSI_DETACH_IND);
1588 TIMERSTART (T3220, T_3220_VALUE);
1589 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT);
1590 break;
1591 }
1592 /*FALLTHROUGH*/
1593 //lint -fallthrough
1594 case MM_WAIT_FOR_RR_CONN_LUP:
1595 case MM_WAIT_FOR_RR_CONN_MM:
1596 case MM_WAIT_FOR_REESTABLISH:
1597 /*
1598 * No IMSI Detach procedure.
1599 * See also comment for state MM_WAIT_FOR_RR_ACTIVE.
1600 */
1601 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE);
1602
1603 TIMERSTOP (T3210);
1604 TIMERSTOP (T3211);
1605
1606 /*
1607 * The timer T3212 is stopped if the mobile station is deactivated
1608 * (i.e. equipment powered down or SIM removed.
1609 */
1610 TIMERSTOP (T3212);
1611 mm_data->t3212_timeout = FALSE;
1612
1613 TIMERSTOP (T3213);
1614 mm_data->t3213_restart = 0;
1615 TIMERSTOP (T3230);
1616 TIMERSTOP (T3240);
1617
1618 switch (nreg_cause)
1619 {
1620 case CS_POW_OFF:
1621 case CS_SOFT_OFF:
1622 #ifdef GPRS
1623 case CS_DISABLE: /* Remote controlled IMSI DETACH */
1624 #endif /* GPRS */
1625 mm_data->nreg_cause = nreg_cause;
1626 mm_abort_connection (ABCS_NORM);
1627
1628 /*
1629 * Entering state MM_IMSI_DETACH_INIT is a trick.
1630 * We know RR will confirm the RR_ABORT_REQ by RR_RELEASE_IND,
1631 * and in this state the appropriate actions will be taken then.
1632 */
1633 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT);
1634 break;
1635
1636 case CS_SIM_REM:
1637 mm_data->nreg_cause = nreg_cause;
1638 mm_abort_connection (ABCS_SIM_REM);
1639 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT);
1640 break;
1641
1642 default:
1643 TRACE_ERROR (UNEXPECTED_DEFAULT);
1644 break;
1645 }
1646 break;
1647
1648 case MM_IMSI_DETACH_INIT:
1649 case MM_WAIT_FOR_RR_CONN_DETACH:
1650 mm_data->nreg_cause = nreg_cause;
1651 break;
1652
1653 case MM_WAIT_FOR_RR_ACTIVE: /* RR is searching for a cell */
1654 /*
1655 * GSM 04.08 subclause 4.3.4.1 requires the following:
1656 * "If no RR connection exists, the MM sublayer within the mobile
1657 * station will request the RR sublayer to establish a RR
1658 * connection. If establishment of the RR connection is not possible
1659 * because a suitable cell is not (or not yet) available then, the
1660 * mobile station shall try for a period of at least 5 seconds and for
1661 * not more than a period of 20 seconds to find a suitable cell. If a
1662 * suitable cell is found during this time then, the mobile station shall
1663 * request the RR sublayer to establish an RR connection, otherwise the
1664 * IMSI detach is aborted.
1665 * [Here the situation is that RR is searching for a cell and no cell is
1666 * yet available, but one may be found in a period lesser than 20 seconds
1667 * and according to the standard an IMSI DETACH shall be performed.
1668 * This MM implementation is more simple here, if still searching for a cell,
1669 * the IMSI detach is not done. This may not cause any harm to the
1670 * mobile user, however, it is a minor violation of GSM 04.08.]
1671 */
1672 switch (nreg_cause)
1673 {
1674 case CS_POW_OFF: /* switch off mobile */
1675 case CS_SOFT_OFF:
1676 mm_mdl_rel_req ();
1677 mm_power_off (); /* deactivate lower layer */
1678 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1679 break;
1680
1681 case CS_SIM_REM:
1682 mm_abort_connection (ABCS_SIM_REM);
1683 mm_clear_reg_data ();
1684 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1685 break;
1686
1687 #ifdef GPRS
1688 case CS_DISABLE:
1689 /* Remember MM may have to IMSI ATTACH if reactivated */
1690 mm_data->first_attach = TRUE;
1691
1692 /* Confirm the GMM requested deregistration */
1693 mm_mmgmm_nreg_cnf (nreg_cause);
1694
1695 /* No state change */
1696 break;
1697 #endif /* GPRS */
1698
1699 default:
1700 TRACE_ERROR (UNEXPECTED_DEFAULT);
1701 break;
1702 }
1703 break;
1704
1705 #ifdef GPRS
1706 case MM_LOCATION_UPDATING_PENDING:
1707 case MM_IMSI_DETACH_PENDING:
1708 case MM_IDLE_LUP_NEEDED:
1709 #endif /* GPRS */
1710 case MM_IDLE_NORMAL_SERVICE:
1711 case MM_IDLE_ATTEMPT_TO_UPDATE:
1712 TIMERSTOP (T3211);
1713
1714 /*
1715 * The timer T3212 is stopped if the mobile station is deactivated
1716 * (i.e. equipment powered down or SIM removed.
1717 */
1718 TIMERSTOP (T3212);
1719 mm_data->t3212_timeout = FALSE;
1720
1721 TIMERSTOP (T3213);
1722 mm_data->t3213_restart = 0;
1723
1724 if (mm_data->mm.mm_info.att EQ ATT_ALLOW AND
1725 mm_data->reg.update_stat EQ MS_UPDATED AND
1726 detach_done EQ MMGMM_PERFORM_DETACH)
1727 {
1728 /* Start IMSI Detach procedure */
1729
1730 if (mm_normal_upd_needed())
1731 {
1732 TRACE_EVENT ("IMSI DETACH questionable");
1733 }
1734 mm_data->nreg_cause = nreg_cause;
1735 mm_create_imsi_detach_message ();
1736 for_est_req (ESTCS_MOB_ORIG_CAL_BY_SS_SMS, BSIZE_U_IMSI_DETACH_IND);
1737 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_DETACH);
1738 break;
1739 }
1740 /*
1741 * No IMSI DETACH procedure
1742 */
1743 /*FALLTHROUGH*/
1744 //lint -fallthrough
1745 case MM_IDLE_LIMITED_SERVICE:
1746 case MM_IDLE_NO_IMSI:
1747 TIMERSTOP (T3211);
1748
1749 /*
1750 * The timer T3212 is stopped if the mobile station is deactivated
1751 * (i.e. equipment powered down or SIM removed.
1752 */
1753 TIMERSTOP (T3212);
1754 mm_data->t3212_timeout = FALSE;
1755
1756 TIMERSTOP (T3213);
1757 mm_data->t3213_restart = 0;
1758 switch (nreg_cause)
1759 {
1760 case CS_POW_OFF:
1761 case CS_SOFT_OFF:
1762 mm_mdl_rel_req ();
1763 mm_power_off ();
1764 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1765 break;
1766
1767 case CS_SIM_REM:
1768 mm_mdl_rel_req();
1769 mm_abort_connection (ABCS_SIM_REM);
1770 mm_clear_reg_data ();
1771 // Debugging patch >>>
1772 if (mm_data->mm_idle_no_imsi_marker EQ 0)
1773 mm_data->mm_idle_no_imsi_marker = 17;
1774 // Debugging patch <<<
1775 SET_STATE (STATE_MM, MM_IDLE_NO_IMSI);
1776 reg_end_of_deregistration (nreg_cause, LIMITED_SERVICE);
1777 break;
1778
1779 #ifdef GPRS
1780 case CS_DISABLE:
1781 /* Remember MM may have to IMSI ATTACH if reactivated */
1782 mm_data->first_attach = TRUE;
1783
1784 /* Confirm the GMM requested deregistration */
1785 mm_mmgmm_nreg_cnf (nreg_cause);
1786
1787 /* No state change */
1788 break;
1789 #endif /* GPRS */
1790
1791 default: /* Not expected */
1792 TRACE_ERROR (UNEXPECTED_PARAMETER);
1793 break;
1794 }
1795 break;
1796
1797 case MM_IDLE_NO_CELL_AVAILABLE:
1798 switch (nreg_cause)
1799 {
1800 case CS_POW_OFF:
1801 case CS_SOFT_OFF:
1802 mm_mdl_rel_req ();
1803 mm_power_off ();
1804 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1805 break;
1806
1807 case CS_SIM_REM:
1808 mm_mdl_rel_req();
1809 mm_abort_connection (ABCS_SIM_REM);
1810 mm_clear_reg_data ();
1811 reg_end_of_deregistration (nreg_cause, NO_SERVICE);
1812 /* No state transition to MM_IDLE_NO_IMSI here,
1813 * as state MM_IDLE_NO_CELL_AVAILABLE has precedence. */
1814 break;
1815
1816 #ifdef GPRS
1817 case CS_DISABLE:
1818 /* Remember MM may have to IMSI ATTACH if reactivated */
1819 mm_data->first_attach = TRUE;
1820
1821 /* Confirm the GMM requested deregistration */
1822 mm_mmgmm_nreg_cnf (nreg_cause);
1823
1824 /* No state transition to MM_IDLE_NO_IMSI here,
1825 * as state MM_IDLE_NO_CELL_AVAILABLE has precedence. */
1826 break;
1827 #endif /* GPRS */
1828
1829 default: /* Not expected */
1830 TRACE_ERROR (UNEXPECTED_PARAMETER);
1831 break;
1832 }
1833 break;
1834
1835 case MM_IDLE_PLMN_SEARCH:
1836 case MM_PLMN_SEARCH_NORMAL_SERVICE:
1837 /* Back to IDLE state before network search was started,
1838 * as deregistration will stop network search in RR. */
1839 SET_STATE (STATE_MM, mm_data->idle_substate);
1840
1841 /* Repeat the deregistration attempt in new MM state */
1842 mm_mmr_nreg_req (nreg_cause, detach_done);
1843 return;
1844
1845 default: /* Not expected as all states are handled implicitely */
1846 TRACE_ERROR (UNEXPECTED_DEFAULT);
1847 break;
1848 }
1849 }
1850
1851 /*
1852 +--------------------------------------------------------------------+
1853 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1854 | STATE : code ROUTINE : mm_mmr_reg_req |
1855 +--------------------------------------------------------------------+
1856
1857 PURPOSE : Process the signal MMR_REG_REQ.
1858
1859 */
1860
1861 GLOBAL void mm_mmr_reg_req (UBYTE func)
1862 {
1863 GET_INSTANCE_DATA;
1864 TRACE_EVENT ("mm_mmr_reg_req()");
1865
1866 /* Check input parameter */
1867 assert (func EQ FUNC_LIM_SERV_ST_SRCH OR
1868 func EQ FUNC_PLMN_SRCH OR
1869 func EQ FUNC_NET_SRCH_BY_MMI);
1870
1871 mm_data->reg.op.v_op = V_OP_PRES;
1872 mm_data->reg.op.func = func;
1873
1874 /* (Re)Start MM's watchdog timer, next state is different from MM_NULL. */
1875 TIMERSTART (T_REGISTRATION, T_REG_VALUE);
1876
1877 switch (GET_STATE (STATE_MM))
1878 {
1879 case MM_NULL:
1880 case MM_IDLE_NORMAL_SERVICE:
1881 case MM_IDLE_ATTEMPT_TO_UPDATE:
1882 case MM_IDLE_LIMITED_SERVICE:
1883 case MM_IDLE_NO_IMSI:
1884 case MM_IDLE_NO_CELL_AVAILABLE:
1885 #ifdef GPRS
1886 case MM_IDLE_LUP_NEEDED:
1887 case MM_LOCATION_UPDATING_PENDING:
1888 case MM_IMSI_DETACH_PENDING:
1889 #endif /* GPRS */
1890 if (func EQ FUNC_NET_SRCH_BY_MMI)
1891 mm_start_net_req ();
1892 else
1893 {
1894 mm_rr_act_req ();
1895 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE);
1896 }
1897 break;
1898
1899 case MM_IDLE_PLMN_SEARCH:
1900 case MM_PLMN_SEARCH_NORMAL_SERVICE:
1901 if (func NEQ FUNC_NET_SRCH_BY_MMI)
1902 {
1903 /* Network search aborted by GMM. Inform MMI */
1904 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
1905
1906 mm_rr_act_req ();
1907 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE);
1908 }
1909 break;
1910
1911 case MM_LUP_INITIATED:
1912 case MM_IMSI_DETACH_INIT:
1913 case MM_PROCESS_PROMPT:
1914 case MM_WAIT_FOR_NW_CMD:
1915 #ifdef REL99
1916 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1917 #endif
1918 case MM_LUP_REJECTED:
1919 case MM_WAIT_FOR_RR_CONN_LUP:
1920 case MM_WAIT_FOR_RR_CONN_DETACH:
1921 if (func EQ FUNC_NET_SRCH_BY_MMI)
1922 {
1923 /*
1924 * If the MM state is not IDLE and this is caused by an MM specific
1925 * procedure, we store MMI's net request until MM becomes IDLE again.
1926 */
1927 mm_write_entry (REG_COMP, 0, 0, EVENT_ENTRY, NULL, UNSPEC);
1928 break;
1929 }
1930 /*FALLTHROUGH*/
1931 //lint -fallthrough
1932 case MM_WAIT_FOR_OUTG_MM_CONN:
1933 case MM_CONN_ACTIVE:
1934 case MM_WAIT_FOR_RR_CONN_MM:
1935 case MM_WAIT_FOR_REESTABLISH:
1936 if (func EQ FUNC_NET_SRCH_BY_MMI)
1937 {
1938 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
1939 }
1940 else
1941 {
1942 /* func is either FUNC_LIM_SERV_ST_SRCH or FUNC_PLMN_SRCH */
1943 mm_mmxx_rel_ind (MMCS_INT_NOT_PRESENT, CM_NOT_IDLE);
1944 mm_abort_connection (ABCS_NORM);
1945 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
1946 {
1947 mm_rr_act_req ();
1948 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE);
1949 }
1950 }
1951 break;
1952
1953 case MM_WAIT_FOR_RR_ACTIVE:
1954 if (func EQ FUNC_NET_SRCH_BY_MMI)
1955 mm_start_net_req ();
1956 else
1957 {
1958 mm_rr_act_req ();
1959 /* State remains */
1960 }
1961 break;
1962
1963 default:
1964 /* As all states are already handled by case, this must not happen */
1965 TRACE_ERROR (UNEXPECTED_DEFAULT);
1966 break;
1967 }
1968 }
1969
1970 /*
1971 +--------------------------------------------------------------------+
1972 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1973 | STATE : code ROUTINE : mm_tmsi_realloc_cmd |
1974 +--------------------------------------------------------------------+
1975
1976 PURPOSE : Process the signal TMSI_REALLOC_CMD.
1977
1978 */
1979
1980 GLOBAL void mm_tmsi_realloc_cmd (T_D_TMSI_REALLOC_CMD *tmsi_realloc_cmd)
1981 {
1982 GET_INSTANCE_DATA;
1983 TRACE_FUNCTION ("mm_tmsi_realloc_cmd()");
1984
1985 /* semantical checks and preprocessing*/
1986 if (!for_check_mobile_identity (&MSG(D_TMSI_REALLOC_CMD)->mob_id))
1987 {
1988 mm_for_set_error (RC_INVALID_MAND_MESSAGE);
1989 return;
1990 }
1991
1992 if (tmsi_realloc_cmd->loc_area_ident.c_mnc EQ 2)
1993 {
1994 tmsi_realloc_cmd->loc_area_ident.mnc[2] = 0xf;
1995 }
1996
1997 {
1998 MCAST (tmsi_realloc_comp, U_TMSI_REALLOC_COMP);
1999 switch (tmsi_realloc_cmd->mob_id.ident_type)
2000 {
2001 case TYPE_TMSI:
2002 mm_store_tmsi (&tmsi_realloc_cmd->mob_id);
2003 mm_build_rr_sync_req_tmsi ();
2004 /* EF LOCI value has changed, hence write it on SIM */
2005 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/
2006 mm_data->ef_indicator|=0x01;
2007 break;
2008 case TYPE_IMSI:
2009 mm_data->reg.tmsi = TMSI_INVALID_VALUE;
2010 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL);
2011 /* EF LOCI value has changed, hence write it on SIM */
2012 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/
2013 mm_data->ef_indicator|=0x01;
2014 break;
2015 default:
2016 TRACE_EVENT ("Unexpected mobile id");
2017 break;
2018 }
2019
2020 /*
2021 * The mobile station shall consider the new TMSI and new LAI,
2022 * if any, as valid and the old TMSI and old LAI as deleted as
2023 * soon as a TMSI REALLOCATION COMMAND or another message
2024 * containing a new TMSI (e.g. LOCATION UPDATING ACCEPT) is
2025 * correctly received." [GSM 04.08 clause 4.3.1.4].
2026 * It can *not* be assumed the new update state is U1 "UPDATED",
2027 * even if the description of the update state in GSM 04.08 4.1.2.2
2028 * says a TMSI can only exists in "UPDATED". GSM 04.08 4.1.2.2 says
2029 * that normally a TMSI etc. only exists in updated, but first the
2030 * presence of other values shall not be considered as an error and
2031 * second this subclause states clearly that the update status shall
2032 * only be changed by LUP ACCEPT and some other explicitly mentioned
2033 * procedures, TMSI REALLOCATION COMMAND not beeing one of them.
2034 */
2035 if (memcmp(mm_data->reg.lai.mnc, tmsi_realloc_cmd->loc_area_ident.mnc, SIZE_MNC)
2036 OR memcmp (mm_data->reg.lai.mcc, tmsi_realloc_cmd->loc_area_ident.mcc, SIZE_MCC)
2037 OR (mm_data->reg.lai.lac NEQ tmsi_realloc_cmd->loc_area_ident.lac))
2038 {
2039 /* EF LOCI value has changed, hence write it on SIM */
2040 /* EF Indicator for EF LOCI - bit 1 */
2041 mm_data->ef_indicator|=0x01;
2042 }
2043 mm_data->reg.lai = tmsi_realloc_cmd->loc_area_ident; /* Struct copy */
2044 tmsi_realloc_comp->msg_type = U_TMSI_REALLOC_COMP;
2045 for_data_req (BSIZE_U_TMSI_REALLOC_COMP);
2046
2047 EM_TMSI_REALLOCATION_COMPLETE;
2048
2049 TIMERSTOP (T3212);
2050 mm_data->t3212_timeout = FALSE;
2051
2052 if (TIMERACTIVE(T3240))
2053 {
2054 TIMERSTOP (T3240);
2055 TIMERSTART (T3240, T_3240_VALUE);
2056 }
2057 reg_build_sim_update ();
2058 }
2059 }
2060
2061 /*
2062 +--------------------------------------------------------------------+
2063 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2064 | STATE : code ROUTINE : mm_cm_service_prompt |
2065 +--------------------------------------------------------------------+
2066
2067 PURPOSE : Process the signal CM_SERVICE_PROMPT. Only called from
2068 for_rr_data_ind if cmsp in classmark 2 is set.
2069
2070 */
2071
2072 GLOBAL void mm_cm_service_prompt (T_D_CM_SERVICE_PROMPT *cm_service_prompt)
2073 {
2074 GET_INSTANCE_DATA;
2075 TRACE_FUNCTION ("mm_cm_service_prompt()");
2076
2077 switch (GET_STATE (STATE_MM))
2078 {
2079 case MM_LUP_INITIATED: /* MM specific procedure, reject */
2080 case MM_LUP_REJECTED: /* MM specific procedure, reject */
2081 case MM_PROCESS_PROMPT:
2082 case MM_WAIT_FOR_OUTG_MM_CONN:
2083 mm_for_set_error(RC_MESSAGE_INCOMPAT);
2084 break;
2085
2086 case MM_CONN_ACTIVE:
2087 if (mm_data->wait_for_accept)
2088 {
2089 /* This is state WAIT_FOR_ADD_OUTGOING_MM_CONN */
2090 mm_for_set_error(RC_MESSAGE_INCOMPAT);
2091 }
2092 else
2093 {
2094 /* This is really MM_CONN_ACTIVE */
2095 if ((cm_service_prompt->pd_and_sapi.pd EQ PD_CC) AND
2096 (cm_service_prompt->pd_and_sapi.sapi EQ SAPI_0))
2097 {
2098 /* Send MMCM_PROMPT_IND to CC */
2099 PALLOC (prompt_ind, MMCM_PROMPT_IND);
2100 PSENDX (CC, prompt_ind);
2101 SET_STATE (STATE_MM, MM_PROCESS_PROMPT);
2102 }
2103 else
2104 {
2105 /* Send MM_STATUS until CCBS fully supported by ACI and MMI */
2106 mm_for_set_error(RC_SERVICE_NOT_SUPPORTED);
2107 }
2108 }
2109 break;
2110
2111 case MM_WAIT_FOR_NW_CMD:
2112 #ifdef REL99
2113 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
2114 #endif
2115 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
2116 {
2117 /*
2118 * T3212 is stopped if the first MM message is received, or
2119 * ciphering mode setting is completed in the case of MM
2120 * connection establishment, except when the most recent service
2121 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
2122 */
2123 TIMERSTOP (T3212);
2124 mm_data->t3212_timeout = FALSE;
2125 }
2126
2127 if ((cm_service_prompt->pd_and_sapi.pd EQ PD_CC) AND
2128 (cm_service_prompt->pd_and_sapi.sapi EQ SAPI_0))
2129 {
2130 #ifdef REL99
2131 /* if timer T3240 is active, Restart T3240 */
2132 if(TIMERACTIVE(T3240))
2133 #endif
2134 {
2135 TIMERSTART (T3240, T_3240_VALUE);
2136 }
2137 /* Send MMCM_PROMPT_IND to CC */
2138 {
2139 PALLOC (prompt_ind, MMCM_PROMPT_IND); /* T_MMCM_PROMPT_IND */
2140 PSENDX (CC, prompt_ind);
2141 }
2142 #ifdef REL99
2143 /*
2144 *Stop timer t3241 if it is ruuning. *As per the spec 24.008, Timer T3241
2145 *is stopped and reset (but not started) when the MM state
2146 *RR CONNECTION RELEASE NOT ALLOWED is left.
2147 */
2148 TIMERSTOP(T3241);
2149 #endif
2150
2151 SET_STATE (STATE_MM, MM_PROCESS_PROMPT);
2152 }
2153 else
2154 {
2155 /* Send MM_STATUS message, only CC and SAPI=0 supported */
2156 mm_for_set_error(RC_SERVICE_NOT_SUPPORTED);
2157 }
2158 break;
2159
2160 default: /* States without RR connection */
2161 break;
2162 }
2163 }
2164
2165
2166 /*
2167 +--------------------------------------------------------------------+
2168 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2169 | STATE : code ROUTINE : mm_mm_information |
2170 +--------------------------------------------------------------------+
2171
2172 PURPOSE : Process the signal MM_INFORMATION. This signal may be
2173 received any time a RR connection to the network exists
2174 and is always been considered as compatible with the
2175 protocol state.
2176 */
2177
2178 GLOBAL void mm_mm_information (T_D_MM_INFORMATION *mm_information)
2179 {
2180 GET_INSTANCE_DATA;
2181
2182 #ifdef GPRS
2183 PALLOC (mmr_info_ind,MMGMM_INFO_IND);
2184 #else
2185 PALLOC (mmr_info_ind,MMR_INFO_IND);
2186 #endif /* GPRS */
2187
2188 TRACE_FUNCTION ("mm_mm_information()");
2189
2190 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
2191 {
2192 /*
2193 * T3212 is stopped if the first MM message is received, or
2194 * ciphering mode setting is completed in the case of MM
2195 * connection establishment, except when the most recent service
2196 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
2197 */
2198 TIMERSTOP (T3212);
2199 mm_data->t3212_timeout = FALSE;
2200 }
2201
2202 /* Set PLMN, this will be used if network name is given */
2203 mmr_info_ind->plmn.v_plmn = TRUE;
2204 memcpy (mmr_info_ind->plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
2205 memcpy (mmr_info_ind->plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
2206
2207 /* Set full network name, if present */
2208 mm_cpy_net_name(&mm_information->full_net_name, &mmr_info_ind->full_name,
2209 mm_information->v_full_net_name);
2210
2211 /* Set short network name, if present */
2212 mm_cpy_net_name(&mm_information->short_net_name, &mmr_info_ind->short_name,
2213 mm_information->v_short_net_name);
2214
2215 /* Set network time zone, if present */
2216 if (mm_information->v_net_tz NEQ 0)
2217 {
2218 mmr_info_ind->ntz.v_tz = TRUE;
2219 mmr_info_ind->ntz.tz = mm_information->net_tz.tz;
2220 }
2221 else
2222 mmr_info_ind->ntz.v_tz = FALSE;
2223
2224 /* Set network time zone and time, if present */
2225 if (mm_information->v_net_tz_and_time NEQ 0)
2226 {
2227 mmr_info_ind->ntz.v_tz = TRUE;
2228 mmr_info_ind->ntz.tz = mm_information->net_tz_and_time.tz;
2229 mmr_info_ind->time.v_time = TRUE;
2230 mmr_info_ind->time.year =
2231 10 * mm_information->net_tz_and_time.year[0] +
2232 mm_information->net_tz_and_time.year[1];
2233 mmr_info_ind->time.month =
2234 10 * mm_information->net_tz_and_time.month[0] +
2235 mm_information->net_tz_and_time.month[1];
2236 mmr_info_ind->time.day =
2237 10 * mm_information->net_tz_and_time.day[0] +
2238 mm_information->net_tz_and_time.day[1];
2239 mmr_info_ind->time.hour =
2240 10 * mm_information->net_tz_and_time.hour[0] +
2241 mm_information->net_tz_and_time.hour[1];
2242 mmr_info_ind->time.minute =
2243 10 * mm_information->net_tz_and_time.minute[0] +
2244 mm_information->net_tz_and_time.minute[1];
2245 mmr_info_ind->time.second =
2246 10 * mm_information->net_tz_and_time.second[0] +
2247 mm_information->net_tz_and_time.second[1];
2248 }
2249 else
2250 {
2251 mmr_info_ind->time.v_time = FALSE;
2252 }
2253 #ifdef REL99
2254 if (mm_information->v_daylight_save_time)
2255 {
2256 mmr_info_ind->daylight_save_time =
2257 mm_information->daylight_save_time.save_time_value;
2258 }
2259 else
2260 {
2261 mmr_info_ind->daylight_save_time = MMR_ADJ_NO;
2262 }
2263 #endif
2264 #ifdef GPRS
2265 PSENDX (GMM, mmr_info_ind);
2266 #else
2267 PSENDX (MMI, mmr_info_ind);
2268 #endif
2269 }
2270
2271 /*
2272 +--------------------------------------------------------------------+
2273 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2274 | STATE : code ROUTINE : mm_send_rr_data_ind |
2275 +--------------------------------------------------------------------+
2276
2277 PURPOSE : The function passes the RR_DATA_IND depending on the parameters
2278 'comp' and 'snd_prim_type' to the respective entity.
2279 'comp' gives either CC or SS or SMS entity
2280 'snd_prim_type' gives either ESTABLISH_IND or DATA_IND
2281 */
2282
2283 LOCAL void mm_send_rr_data_ind (T_RR_DATA_IND *rr_data_ind,
2284 UBYTE comp,
2285 T_PRIM_TYPE snd_prim_type)
2286 {
2287 TRACE_FUNCTION ("mm_send_rr_data_ind()");
2288
2289 switch (comp)
2290 {
2291 case CC_COMP:
2292 {
2293 if(snd_prim_type EQ PRIM_EST_IND)
2294 {
2295 PPASS (rr_data_ind, est, MMCM_ESTABLISH_IND);
2296 PSENDX (CC, est);
2297 }
2298 else
2299 {
2300 PPASS (rr_data_ind, data, MMCM_DATA_IND);
2301 PSENDX (CC, data);
2302 }
2303 }
2304 break;
2305
2306 case SS_COMP:
2307 {
2308 if(snd_prim_type EQ PRIM_EST_IND)
2309 {
2310 PPASS (rr_data_ind, est, MMSS_ESTABLISH_IND);
2311 PSENDX (SS, est);
2312 }
2313 else
2314 {
2315 PPASS (rr_data_ind, data, MMSS_DATA_IND);
2316 PSENDX (SS, data);
2317 }
2318 }
2319 break;
2320
2321 case SMS_COMP:
2322 {
2323 if(snd_prim_type EQ PRIM_EST_IND)
2324 {
2325 PPASS (rr_data_ind, est, MMSMS_ESTABLISH_IND);
2326 PSENDX (SMS, est);
2327 }
2328 else
2329 {
2330 PPASS (rr_data_ind, data, MMSMS_DATA_IND);
2331 PSENDX (SMS, data);
2332 }
2333 }
2334 break;
2335
2336 default:
2337 PFREE (rr_data_ind);
2338 return;
2339 } /* switch (comp) */
2340 }
2341
2342 /*
2343 +--------------------------------------------------------------------+
2344 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2345 | STATE : code ROUTINE : mm_cpy_net_name |
2346 +--------------------------------------------------------------------+
2347
2348 PURPOSE : The function sets the network name.
2349 */
2350
2351 LOCAL void mm_cpy_net_name (T_full_net_name *net_name,
2352 T_full_name *name,
2353 UBYTE v_net_name)
2354 {
2355 TRACE_FUNCTION ("mm_cpy_net_name()");
2356 if (v_net_name NEQ 0)
2357 {
2358 name->v_name = TRUE;
2359 name->dcs = net_name->cs;
2360 name->add_ci = net_name->add_ci;
2361 name->num_spare = net_name->num_spare;
2362 memset(name->text, 0, MMR_MAX_TEXT_LEN);
2363 name->c_text = MINIMUM (MMR_MAX_TEXT_LEN, net_name->c_text);
2364 memcpy (name->text, net_name->text,name->c_text);
2365 }
2366 else
2367 name->v_name = FALSE;
2368 }
2369
2370 #endif