comparison g23m-gsm/mm/mm_mms.c @ 0:75a11d740a02

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