comparison gsm-fw/g23m-gsm/mm/mm_regp.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 87cef40cf601
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_REGP
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 registration
18 | capability of the module Mobility Management.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_REGP_C
23 #define MM_REGP_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 /*==== VARIABLES ==================================================*/
77
78 /*==== FUNCTIONS ==================================================*/
79
80 /*==== PRIVAT =====================================================*/
81
82 /*
83 +--------------------------------------------------------------------+
84 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
85 | STATE : code ROUTINE : mm_auto_net_reg |
86 +--------------------------------------------------------------------+
87
88 PURPOSE : Register in automatic mode.
89
90 */
91
92 GLOBAL void mm_auto_net_reg(void)
93 {
94 GET_INSTANCE_DATA;
95 T_plmn last_plmn;
96
97 TRACE_FUNCTION("mm_auto_net_reg");
98
99 last_plmn.v_plmn = V_PLMN_PRES;
100 memcpy (last_plmn.mcc, mm_data->reg.lai.mcc, SIZE_MCC);
101 memcpy (last_plmn.mnc, mm_data->reg.lai.mnc, SIZE_MNC);
102
103 /*
104 * start full PLMN search in automatic mode
105 */
106 mm_data->attempt_cnt = 0;
107
108 mm_data->reg.bcch_encode =
109 (mm_data->reg.update_stat EQ MS_UPDATED AND !reg_plmn_empty (&last_plmn));
110 /*
111 * It exists an updated last PLMN if bcch_encode is TRUE here
112 */
113
114 mm_data->reg.plmn_cnt = 0; /* Delete list of available PLMNs */
115 if (mm_data->reg.bcch_encode AND !reg_plmn_equal_hplmn (&last_plmn))
116 {
117 TRACE_EVENT ("Start with LPLMN");
118
119 /* LPLMN available and not equal HPLMN => start with LPLMN */
120 mm_data->reg.actual_plmn = last_plmn; /* Struct copy */
121 }
122 else
123 {
124 TRACE_EVENT ("Start with HPLMN");
125
126 /* LPLMN not available or not updated => start with HPLMN */
127 reg_extract_hplmn (&mm_data->reg.actual_plmn);
128 }
129
130 EM_START_REGISTRATION_AUTO_MODE;
131
132 mm_mmr_reg_req (FUNC_PLMN_SRCH);
133 }
134
135
136 #ifdef GPRS
137 /*
138 +--------------------------------------------------------------------+
139 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
140 | STATE : code ROUTINE : reg_set_gprs_reg_type |
141 +--------------------------------------------------------------------+
142
143 PURPOSE : Set the new registration type as delivered by GMM.
144 This may also affect the CM_GPRS_EST state machine.
145
146 */
147
148
149 LOCAL void reg_set_gprs_reg_type (UBYTE reg_type)
150 {
151 GET_INSTANCE_DATA;
152 TRACE_FUNCTION ("reg_set_gprs_reg_type()");
153
154 switch (reg_type)
155 {
156 case REG_GPRS_INACTIVE:
157 /* CM establishment always allowed if GPRS is not present */
158 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
159 break;
160
161 case REG_REMOTE_CONTROLLED:
162 /* Remote controlled location updating not possible with GSM only */
163 assert (GET_STATE (STATE_REG_TYPE) NEQ REG_GPRS_INACTIVE);
164
165 /* During RC for non GPRS only mobile CM services are allowed */
166 if (mm_data->gprs.mobile_class NEQ MMGMM_CLASS_CG)
167 {
168 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
169 }
170 break;
171
172 case REG_CELL_SEARCH_ONLY:
173 if (mm_gsm_alone())
174 {
175 /* CM establishment not allowed anymore if GPRS was switched on */
176 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
177 }
178 break;
179
180 default:
181 TRACE_ERROR (UNEXPECTED_PARAMETER);
182 return;
183 }
184
185 /* Remember new MM working type */
186 SET_STATE (STATE_REG_TYPE, reg_type);
187 }
188 #endif /* GPRS */
189
190 /*==== VARIABLES ==================================================*/
191
192 /*==== FUNCTIONS ==================================================*/
193
194 /*
195 +----------------------------------------------------------------------------+
196 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
197 | STATE : code ROUTINE : mm_reg_gsm_only_req |
198 +----------------------------------------------------------------------------+
199
200 PURPOSE : This function perform registration in GSM mode only.
201 (What about cell selection only?) ###
202
203 */
204
205 LOCAL void mm_reg_gsm_only_req (UBYTE service_mode)
206 {
207 GET_INSTANCE_DATA;
208 TRACE_FUNCTION ("mm_reg_gsm_only_req()");
209
210 mm_data->reg.full_service_indicated = FALSE;
211
212 /*
213 * If SIM is inserted, make it valid for MM if
214 * IMSI is present and full service required,
215 * otherwise invalidate SIM for MM
216 */
217 switch (service_mode)
218 {
219 case SERVICE_MODE_FULL:
220 if (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES)
221 {
222 mm_data->reg.op.sim_ins = SIM_INSRT;
223 mm_data->limited_cause = MMCS_INT_NOT_PRESENT;
224 }
225 break;
226
227 case SERVICE_MODE_LIMITED:
228 if (mm_data->reg.op.sim_ins NEQ SIM_NO_INSRT)
229 {
230 mm_data->reg.op.sim_ins = SIM_NO_INSRT;
231 mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_MMIREQ */
232 }
233 break;
234
235 default:
236 TRACE_ERROR (UNEXPECTED_PARAMETER);
237 break;
238 }
239
240 if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)
241 {
242 /*
243 * No valid SIM inserted
244 */
245 mm_data->reg.bcch_encode = FALSE;
246 mm_data->reg.op.v_op = V_OP_PRES;
247 mm_data->reg.op.m = M_AUTO;
248 mm_mmr_reg_req (FUNC_LIM_SERV_ST_SRCH);
249 }
250 else
251 {
252 /*
253 * Valid SIM inserted
254 */
255 if (mm_data->reg.op.m EQ M_AUTO)
256 {
257 mm_auto_net_reg ();
258 }
259 else
260 {
261 /*
262 * PLMN search in manual mode: Request PLMN list from RR
263 */
264 // Patch HM >>>
265 mm_data->plmn_scan_mmi = TRUE;
266 // Patch HM <<<
267 mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI);
268
269 EM_START_REGISTRATION_MANUAL_MODE;
270
271 }
272 }
273 }
274
275 /*==== TEST =====================================================*/
276
277 /*
278 * -------------------------------------------------------------------
279 * PRIMITIVE Processing functions
280 * -------------------------------------------------------------------
281 */
282
283 /*
284 +----------------------------------------------------------------------------+
285 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
286 | STATE : code ROUTINE : mm_func_mmgmm_net_req |
287 +----------------------------------------------------------------------------+
288
289 PURPOSE : This function handles the MMGMM_NET_REQ primitive.
290 MMGMM_NET_REQ is always used to start a network search.
291
292 */
293
294 GLOBAL void mm_func_mmgmm_net_req (void)
295 {
296 GET_INSTANCE_DATA;
297 TRACE_FUNCTION ("mm_func_mmgmm_net_req()");
298
299 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
300 {
301 /*
302 * SIM present
303 */
304 switch (GET_STATE (STATE_MM))
305 {
306 case MM_NULL:
307 /* prepare environement for further processing by RR */
308
309 mm_data->reg.op.m = MODE_MAN;
310 reg_clear_plmn (&mm_data->reg.actual_plmn);
311
312 mm_mmr_reg_req (FUNC_PLMN_SRCH);
313 break;
314
315 default:
316 mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI);
317 break;
318 }
319
320 EM_START_PLMN_LIST_REQUEST;
321
322 }
323 else
324 {
325 /*
326 * SIM not present
327 */
328 /*If Dual SIM is supported by MS then initially before SIM activation
329 Network search should be done.Also, anytime network search is asked for
330 MM should start with PLMN scan and return proper PLMN list*/
331 #ifdef FF_DUAL_SIM
332 TRACE_EVENT("Dual sim is supported and no sim");
333 mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI);
334 #else
335 mm_mmgmm_plmn_ind (MMCS_SIM_REMOVED, NULL);
336 #endif
337 }
338 }
339
340
341 /*
342 +----------------------------------------------------------------------------+
343 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
344 | STATE : code ROUTINE : mm_func_mmgmm_nreg_req |
345 +----------------------------------------------------------------------------+
346
347 PURPOSE : This function handles the MMGMM_NREG_REQ primitive.
348
349 */
350
351 GLOBAL void mm_func_mmgmm_nreg_req (UBYTE detach_cause,
352 UBYTE detach_done,
353 USHORT cs)
354 {
355 GET_INSTANCE_DATA;
356 TRACE_FUNCTION ("mm_func_mmgmm_nreg_req()");
357
358 /*
359 * Parameter check from ACI/GMM
360 */
361 #ifdef GPRS
362
363 #ifdef WIN32
364 TRACE_EVENT_P1 ("detach_cause = %02X", detach_cause);
365 TRACE_EVENT_P1 ("detach_done = %02X", detach_done);
366 TRACE_EVENT_P1 ("cs = %04X", cs);
367 #endif /* #ifdef WIN32 */
368
369 /* Check for correct originating entity */
370 assert (GET_CAUSE_ORIGIN_ENTITY (cs) EQ
371 GMM_ORIGINATING_ENTITY);
372
373 /* Check for correct detach_done parameter */
374 assert ((detach_done EQ MMGMM_PERFORM_DETACH) OR
375 (detach_done EQ MMGMM_DETACH_DONE));
376 #else
377 assert (detach_done EQ MMGMM_PERFORM_DETACH);
378 #endif /* GPRS */
379
380 /* Remember that the deregistration was requested by MMI */
381 mm_data->nreg_request = TRUE;
382
383 /* Remember the cause of the deregistration */
384 mm_data->nreg_cause = detach_cause;
385
386 /*
387 * Timer T3212 is stopped if the mobile station is deactivated
388 * (i.e. equipment powered down or SIM removed.
389 */
390 TIMERSTOP (T3212);
391 mm_data->t3212_timeout = FALSE;
392
393 if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)
394 {
395 /*
396 * No valid SIM inserted
397 */
398 switch (detach_cause)
399 {
400 case CS_POW_OFF:
401 case CS_SOFT_OFF:
402 mm_mmr_nreg_req (detach_cause, detach_done);
403 break;
404
405 case CS_SIM_REM:
406 mm_mmgmm_nreg_cnf (detach_cause); /* SIM already removed */
407 break;
408
409 #ifdef GPRS
410 case CS_DISABLE:
411 mm_mmgmm_nreg_cnf (detach_cause); /* Already detached */
412 break;
413 #endif /* GPRS */
414
415 default:
416 TRACE_ERROR (UNEXPECTED_DEFAULT);
417 break;
418 }
419 }
420 else
421 {
422 /*
423 * Valid SIM inserted
424 */
425 switch (detach_cause)
426 {
427 case CS_SIM_REM:
428 mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_MMIREQ */
429 //lint -fallthrough
430 case CS_POW_OFF:
431 case CS_SOFT_OFF:
432 mm_mmr_nreg_req (detach_cause, detach_done);
433 break;
434
435 #ifdef GPRS
436 case CS_DISABLE:
437 /*
438 * Check deregistration cause from GMM
439 */
440 switch (cs)
441 {
442 case GMMCS_IMSI_UNKNOWN: /* #2 */
443 case GMMCS_ILLEGAL_MS: /* #3 */
444 case GMMCS_ILLEGAL_ME: /* #6 */
445 case GMMCS_GSM_GPRS_NOT_ALLOWED: /* #8 */
446 case GMMCS_PLMN_NOT_ALLOWED: /* #11 */
447 case GMMCS_LA_NOT_ALLOWED: /* #12 */
448 case GMMCS_ROAMING_NOT_ALLOWED: /* #13 */
449 #ifdef REL99
450 case GMMCS_ROAMING_NOT_ALLOWED_WITH_RAU_REJ: /* #13 GPRS RAU rejected*/
451 case GMMCS_NO_SUITABLE_CELL_IN_LA: /* #15 GPRS attach rejected*/
452 case GMMCS_NO_SUITABLE_CELL_IN_LA_WITH_RAU_REJ: /* #15 GPRS RAU rejected*/
453 #endif
454 mm_network_initiated_detach (cs);
455 break;
456
457 case GMMCS_GPRS_NOT_ALLOWED: /* #7 */
458 /*
459 * # 7 (GPRS services not allowed)
460 * The MS shall set the GPRS update status to GU3
461 * ROAMING NOT ALLOWED (and shall store it according to
462 * section 4.1.3.2) and shall delete any P-TMSI, P-TMSI signature,
463 * RAI and GPRS ciphering key sequence number. The SIM shall be
464 * considered as invalid for GPRS services until switching off or
465 * the SIM is removed. The new state is GMM-DEREGISTERED.
466 * [GSM 04.08 subclause 4.7.3.1.4].
467 *
468 * This is a GPRS only cause. MM starts automatically T3212
469 * without the need to receive MMGMM_START_T3212_REQ.
470 * It is expected that GMM will send a MMGMM_REG_REQ
471 * (REG_GPRS_INACTIVE) immediately after this to trigger a
472 * registration attempt.
473 */
474
475 /* As this is a GPRS only reason, this should not have any
476 * impact on the update status of GSM. But T3212 has to be
477 * started now.
478 */
479 mm_func_mmgmm_start_t3212_req ();
480 TRACE_EVENT ("No impact on update status");
481 mm_mmgmm_nreg_cnf (detach_cause);
482 break;
483
484 case GMMCS_INT_NOT_PRESENT:
485 /*
486 * Start remote controlled IMSI DETACH operation
487 */
488 mm_mmr_nreg_req (detach_cause, detach_done);
489 break;
490
491 default:
492 TRACE_EVENT ("No impact on update status and nothing done!");
493 mm_mmgmm_nreg_cnf (detach_cause);
494 break;
495 }
496 break; /* CS_DISABLE */
497 #endif /* GPRS */
498
499 default:
500 TRACE_ERROR (UNEXPECTED_DEFAULT);
501 break;
502 }
503 }
504
505 /* Check HPLMN timer state */
506 reg_check_hplmn_tim (mm_data->reg.thplmn);
507 }
508
509
510 /*
511 +----------------------------------------------------------------------------+
512 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
513 | STATE : code ROUTINE : mm_func_mmgmm_plmn_mode_req |
514 +----------------------------------------------------------------------------+
515
516 PURPOSE : This function handles the MMGMM_PLMN_MODE_REQ primitive.
517 MMGMM_PLMN_MODE_REQ is used to switch between automatic and
518 manual mode of registration.
519
520 */
521
522 GLOBAL void mm_func_mmgmm_plmn_mode_req (UBYTE mode)
523 {
524 GET_INSTANCE_DATA;
525 TRACE_FUNCTION ("mm_func_mmgmm_plmn_mode_req()");
526
527 #ifndef NTRACE
528 switch (mode)
529 {
530 case MODE_AUTO:
531 TRACE_EVENT ("automatic mode");
532 break;
533
534 case MODE_MAN:
535 TRACE_EVENT ("manual mode");
536 break;
537
538 default:
539 TRACE_ERROR (UNEXPECTED_PARAMETER);
540 break;
541 }
542 #endif /* NTRACE */
543
544 /*
545 * If SIM is inserted, make it valid for MM if IMSI is present
546 */
547 if (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES)
548 {
549 mm_data->reg.op.sim_ins = SIM_INSRT;
550 mm_data->limited_cause = MMCS_INT_NOT_PRESENT;
551 }
552
553 mm_data->reg.op.m = mode;
554
555 switch (GET_STATE (STATE_MM))
556 {
557 case MM_NULL: /* Mobile is off, do nothing */
558 break;
559
560 // This is just for issue 15605 should be asap removed by an clearly implemented concept for RR_SYNC interface
561 case MM_IDLE_NO_IMSI: /* Mobile has no SIM or received e.g. cause MMCS_IMSI_IN_HLR" ... */
562 if (mode EQ M_MAN)
563 mm_data->reg.op.func = FUNC_LIM_SERV_ST_SRCH;
564 //lint -fallthrough
565 default:
566 mm_build_rr_sync_req(MSG_MM_MODE);
567 break;
568 }
569
570 /* Check HPLMN timer state */
571 reg_check_hplmn_tim (mm_data->reg.thplmn);
572 }
573
574
575 /*
576 +----------------------------------------------------------------------------+
577 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
578 | STATE : code ROUTINE : mm_func_mmgmm_plmn_res |
579 +----------------------------------------------------------------------------+
580
581 PURPOSE : This function handles the MMGMM_PLMN_RES primitive.
582 MMGMM_PLMN_RES is used to select a PLMN manually after
583 network search or to select RPLMN at switch on in manual mode
584
585 */
586
587 GLOBAL void mm_func_mmgmm_plmn_res (const T_plmn *plmn,
588 UBYTE reg_type,
589 UBYTE mobile_class)
590 {
591 GET_INSTANCE_DATA;
592 TRACE_FUNCTION ("mm_func_mmgmm_plmn_res ()");
593
594 mm_data->reg.full_service_indicated = FALSE;
595
596 #ifdef GPRS
597 mm_data->gprs.mobile_class = mobile_class;
598
599 if ((reg_type EQ REG_REMOTE_CONTROLLED) AND
600 (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED))
601 {
602 /*
603 * GMM tries to retrigger a remote controlled RC procedure while
604 * this is already running. MM ignores this and continues updating.
605 */
606 TRACE_EVENT ("No retrigger of RC update");
607 return;
608 }
609
610 reg_set_gprs_reg_type (reg_type);
611 #endif /* GPRS */
612
613 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
614 {
615 /*
616 * A valid SIM is inserted
617 */
618 mm_data->reg.plmn_cnt = 0; /* Delete list of available PLMNs */
619
620 #ifdef GPRS
621 switch (reg_type)
622 {
623 case REG_GPRS_INACTIVE:
624 case REG_CELL_SEARCH_ONLY:
625 reg_select_network(plmn);
626 break;
627
628 case REG_REMOTE_CONTROLLED:
629 {
630 /*
631 * First, we check whether GMM sent a correct PLMN.
632 * All other cases are a protocol failure and MM cannot do much.
633 */
634 T_plmn camped_plmn;
635
636 camped_plmn.v_plmn = V_PLMN_PRES;
637 memcpy (camped_plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
638 memcpy (camped_plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
639
640 assert (reg_plmn_equal_sim (&camped_plmn, plmn));
641 }
642
643 /* Perform a remote controlled location updating procedure */
644 mm_gprs_update_req ();
645 break;
646
647 default:
648 TRACE_ERROR (UNEXPECTED_DEFAULT);
649 break;
650 }
651 #else
652 reg_select_network(plmn);
653 #endif /* GPRS */
654 }
655 else
656 {
657 /*
658 * No valid SIM inserted, selection a network manually makes no sense.
659 */
660 mm_func_mmgmm_reg_req (SERVICE_MODE_FULL, reg_type, MMGMM_CLASS_CC, NORMAL_REG);
661 }
662 }
663
664
665 /*
666 +----------------------------------------------------------------------------+
667 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
668 | STATE : code ROUTINE : mm_func_mmgmm_reg_req |
669 +----------------------------------------------------------------------------+
670
671 PURPOSE : This function handles the MMGMM_REG_REQ primitive,
672 but it is the functional interface.
673
674 */
675
676 GLOBAL void mm_func_mmgmm_reg_req (UBYTE service_mode,
677 UBYTE reg_type,
678 UBYTE mobile_class,
679 UBYTE bootup_act)
680 {
681 GET_INSTANCE_DATA;
682 TRACE_FUNCTION ("mm_func_mmgmm_reg_req()");
683
684 #ifdef TRACE_FUNC
685 /* Implements Measure#32: Row 158 & 159 */
686 TRACE_EVENT_P1 (" service_mode = %d", service_mode);
687 TRACE_EVENT_P1 (" reg_type = %d", reg_type);
688 #endif
689
690 /* Changes for Boot Time Speedup. MM will get dummy REG_REQ indicating QUICK_REG. In this case
691 * MM has to send RR_ACTIVATE_REQ with op.func = FUNC_ST_PWR_SCAN. No need to process this as
692 * it is dummy request and MM will get other REG_REQ indicating NORMAL_REG
693 */
694 if (bootup_act EQ QUICK_REG)
695 {
696 mm_data->reg.op.v_op = V_OP_PRES;
697 mm_data->reg.op.func = FUNC_ST_PWR_SCAN;
698 mm_rr_act_req ();
699 return ;
700 }
701 /*
702 * Check incoming parameters from GMM
703 */
704 assert (service_mode EQ SERVICE_MODE_LIMITED OR
705 service_mode EQ SERVICE_MODE_FULL);
706
707 mm_data->reg.full_service_indicated = FALSE;
708
709 #ifdef GPRS
710
711 mm_data->gprs.mobile_class = mobile_class;
712
713 if ((reg_type EQ REG_REMOTE_CONTROLLED) AND
714 (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED))
715 {
716 /*
717 * GMM tries to retrigger a remote controlled RC procedure while
718 * this is already running. MM ignores this and continues updating.
719 */
720 TRACE_EVENT ("No retrigger of RC update");
721 return;
722 }
723
724 reg_set_gprs_reg_type (reg_type);
725
726 switch (reg_type)
727 {
728 case REG_CELL_SEARCH_ONLY:
729 case REG_GPRS_INACTIVE:
730 mm_reg_gsm_only_req (service_mode);
731 break;
732
733 case REG_REMOTE_CONTROLLED:
734 /*
735 * This is the request not to start a cell selection but to perform a
736 * remote controlled location update procedure for GSM.
737 */
738
739 if (mm_data->gprs.sim_physically_removed)
740 {
741 mm_sim_removed_gprs_active ();
742 return;
743 }
744
745 /* Actually start the location updating procedure */
746 mm_gprs_update_req();
747 break;
748
749 default:
750 TRACE_ERROR (UNEXPECTED_PARAMETER);
751 break;
752 }
753 #else
754 mm_reg_gsm_only_req (service_mode);
755 #endif /* GPRS */
756 }
757
758
759 #ifndef GPRS
760 /*
761 +--------------------------------------------------------------------+
762 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
763 | STATE : code ROUTINE : reg_mmr_net_req |
764 +--------------------------------------------------------------------+
765
766 PURPOSE : Process the primitive MMR_NET_REQ.
767
768 */
769
770 GLOBAL void reg_mmr_net_req (T_MMR_NET_REQ * mmr_net_req)
771 {
772 GET_INSTANCE_DATA;
773 TRACE_FUNCTION ("reg_mmr_net_req()");
774
775 /* Mark the network search as beeing for the MMI */
776 mm_data->plmn_scan_mmi = TRUE;
777
778 /* Start scanning for available PLMNs */
779 mm_func_mmgmm_net_req ();
780
781 PFREE (mmr_net_req);
782 }
783
784
785 /*
786 +--------------------------------------------------------------------+
787 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
788 | STATE : code ROUTINE : reg_mmr_nreg_req |
789 +--------------------------------------------------------------------+
790
791 PURPOSE : Process the primitive MMR_NREG_REQ.
792
793 */
794
795 GLOBAL void reg_mmr_nreg_req (T_MMR_NREG_REQ *mmr_nreg_req)
796 {
797 TRACE_FUNCTION ("reg_mmr_nreg_req()");
798
799 /* Use internal functional interface, set GSM only default parameters */
800 mm_func_mmgmm_nreg_req (mmr_nreg_req->detach_cause,
801 MMGMM_PERFORM_DETACH,
802 MMGMM_NO_ERROR);
803
804 PFREE (mmr_nreg_req);
805 }
806
807 /*
808 +--------------------------------------------------------------------+
809 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
810 | STATE : code ROUTINE : reg_mmr_plmn_mode_req |
811 +--------------------------------------------------------------------+
812
813 PURPOSE : Process the primitive MMR_PLMN_MODE_REQ
814
815 */
816
817 GLOBAL void reg_mmr_plmn_mode_req (T_MMR_PLMN_MODE_REQ *plmn_mode_req)
818 {
819 TRACE_FUNCTION ("reg_mmr_plmn_mode_req()");
820
821 /* Use internal functional interface */
822 mm_func_mmgmm_plmn_mode_req (plmn_mode_req->mode);
823
824 EM_SET_PLMN_SEARCH_MODE;
825 PFREE (plmn_mode_req);
826 }
827
828
829 /*
830 +--------------------------------------------------------------------+
831 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
832 | STATE : code ROUTINE : reg_mmr_plmn_res |
833 +--------------------------------------------------------------------+
834
835 PURPOSE : Process the primitive MMR_PLMN_RES.
836
837 */
838
839 GLOBAL void reg_mmr_plmn_res (T_MMR_PLMN_RES *mmr_plmn_res)
840 {
841 TRACE_FUNCTION ("reg_mmr_plmn_res()");
842
843 /* Use internal functional interface */
844 mm_func_mmgmm_plmn_res (&mmr_plmn_res->plmn,
845 REG_GPRS_INACTIVE,
846 MMGMM_CLASS_CC);
847
848 PFREE (mmr_plmn_res);
849 }
850
851
852 /*
853 +--------------------------------------------------------------------+
854 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
855 | STATE : code ROUTINE : reg_mmr_reg_req |
856 +--------------------------------------------------------------------+
857
858 PURPOSE : Process the primitive MMR_REG_REQ.
859
860 */
861
862 GLOBAL void reg_mmr_reg_req (T_MMR_REG_REQ *mmr_reg_req)
863 {
864 TRACE_FUNCTION ("reg_mmr_reg_req()");
865
866 /* Use internal functional interface */
867 mm_func_mmgmm_reg_req (mmr_reg_req->service_mode,
868 REG_GPRS_INACTIVE,
869 MMGMM_CLASS_CC,
870 mmr_reg_req->bootup_act);
871
872 PFREE (mmr_reg_req);
873 }
874 #endif /* GPRS */
875
876
877 /*
878 +--------------------------------------------------------------------+
879 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
880 | STATE : code ROUTINE : reg_sim_auth_cnf |
881 +--------------------------------------------------------------------+
882
883 PURPOSE : Process the primitive SIM_AUTHENTICATION_CNF.
884
885 */
886
887 GLOBAL void reg_sim_auth_cnf (T_SIM_AUTHENTICATION_CNF *sim_auth_cnf)
888 {
889 TRACE_FUNCTION ("reg_sim_auth_cnf()");
890
891 mm_mmr_auth_cnf (sim_auth_cnf);
892 }
893
894 /*
895 +--------------------------------------------------------------------+
896 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
897 | STATE : code ROUTINE : reg_sim_mm_insert_ind |
898 +--------------------------------------------------------------------+
899
900 PURPOSE : Process the primitive SIM_MM_INSERT.
901
902 */
903
904 GLOBAL void reg_sim_mm_insert_ind (T_SIM_MM_INSERT_IND *sim_mm_insert_ind)
905 {
906 GET_INSTANCE_DATA;
907 TRACE_FUNCTION ("reg_sim_mm_insert()");
908
909 #ifdef GPRS
910 mm_data->gprs.sim_physically_removed = FALSE;
911 #endif /* #ifdef GPRS */
912
913 /*SIM_SYNC_REQ to be sent after reading EFs*/
914 mm_data->reg.sim_sync_req_pending = TRUE;
915
916 if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)
917 {
918 /*
919 * No SIM card was inserted, now it is in and the coresponding handling should happen.
920 */
921 reg_copy_sim_data (sim_mm_insert_ind);
922
923 EM_SIM_INSERT;
924
925 PFREE (sim_mm_insert_ind);
926 }
927 else
928 {
929 /*
930 * This happens by SAT activity while SIM is inserted
931 */
932 T_imsi_struct new_imsi_struct;
933
934 reg_read_imsi(&new_imsi_struct, &sim_mm_insert_ind->imsi_field);
935
936 if (! reg_imsi_equal(&new_imsi_struct, &mm_data->reg.imsi_struct))
937 {
938 /*
939 * IMSI changed. MM Restart procedure, GSM 03.22 subclause 4.10:
940 * "To perform the procedure the MS shall behave as if
941 * the SIM is removed and afterwards a new SIM is inserted"
942 */
943
944 /*
945 * Remember the primitive data. Value sim_mm_insert_info NEQ NULL means
946 * the MM Restart procedure is active. All actions normally performed
947 * if SIM inserted will be done after RR_ABORT_IND, RR_RELEASE_IND or
948 * T3220 timeout received or immediately in mm_mmr_nreg_req().
949 */
950 if (mm_data->reg.sim_insert_info NEQ NULL)
951 PFREE (mm_data->reg.sim_insert_info); /* Not expected to happen */
952 mm_data->reg.sim_insert_info = sim_mm_insert_ind;
953
954 mm_mmr_nreg_req (CS_SIM_REM, MMGMM_PERFORM_DETACH);
955 if (mm_data->reg.sim_insert_info NEQ NULL)
956 {
957 /*
958 * SIM insert not already performed. e.g. IMSI detach running.
959 * Clear the registration data, but remember the pointer to the
960 * new SIM data, the registration mode and the actual plmn.
961 * sim_sync_req_pending which gets reset in reg_init() is set
962 * back to TRUE
963 */
964 T_plmn old_plmn;
965 UBYTE old_mode;
966
967 old_mode = mm_data->reg.op.m;
968 old_plmn = mm_data->reg.actual_plmn; /* Structure copy */
969 reg_init ();
970 mm_data->reg.sim_insert_info = sim_mm_insert_ind;
971 mm_data->reg.op.m = old_mode;
972 mm_data->reg.actual_plmn = old_plmn;
973 mm_data->reg.sim_sync_req_pending = TRUE;
974
975 }
976
977 EM_SIM_INSERT;
978
979 }
980 else
981 {
982 /*
983 * IMSI not changed
984 */
985 USHORT old_acc_class;
986 UBYTE old_thplmn;
987
988 old_acc_class = mm_data->reg.acc_class;
989 old_thplmn = mm_data->reg.thplmn;
990
991 reg_copy_sim_data (sim_mm_insert_ind);
992
993 if (old_acc_class NEQ mm_data->reg.acc_class)
994 {
995 mm_build_rr_sync_req_cause (SYNCCS_ACCC);
996 }
997
998 if (old_thplmn NEQ mm_data->reg.thplmn)
999 {
1000 reg_stop_hplmn_tim ();
1001 reg_check_hplmn_tim (mm_data->reg.thplmn);
1002 }
1003
1004 PFREE (sim_mm_insert_ind);
1005 }
1006 }
1007 check_if_cingular_sim();
1008 }
1009
1010 /*
1011 +--------------------------------------------------------------------+
1012 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1013 | STATE : code ROUTINE : reg_sim_mm_info_ind |
1014 +--------------------------------------------------------------------+
1015
1016 PURPOSE : Process the primitive SIM_MM_INFO_IND.
1017
1018 */
1019
1020 GLOBAL void reg_sim_mm_info_ind (T_SIM_MM_INFO_IND *sim_mm_info_ind)
1021 {
1022 GET_INSTANCE_DATA;
1023 TRACE_FUNCTION ("reg_sim_mm_info_ind()");
1024
1025 switch(sim_mm_info_ind->datafield)
1026 {
1027 #ifdef REL99
1028 case SIM_UCPS_ACTEC:
1029 mm_data->reg.upd_sim_ucps_at = SAT_READ_FILE;
1030 mm_data->reg.sim_ucps_at_len = NOT_PRESENT_16BIT;
1031 /*
1032 * If EFPLMNwAcT is changed, MM must have to re-read EFOPLMNwAcT to
1033 * make a complete list of pref_plmn.
1034 */
1035 mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE;
1036 mm_data->reg.sim_ocps_at_len = NOT_PRESENT_16BIT;
1037 /*
1038 * Read indicated EF in SIM_MM_INFO_IND from SIM.
1039 */
1040 /*Set indicatort sim reading is in progress to true*/
1041 mm_data->reg.sim_read_in_progress = TRUE;
1042 reg_read_next_sim_file();
1043 break;
1044 #endif
1045
1046 case SIM_PLMNSEL:
1047 #ifdef REL99
1048 if (mm_data->reg.sim_uocps_at_used EQ FALSE)
1049 #endif
1050 {
1051 mm_data->reg.upd_sim_plmnsel = SAT_READ_FILE;
1052 mm_data->reg.sim_plmnsel_len = NOT_PRESENT_16BIT;
1053
1054 /*Set indicatort sim reading is in progress to true*/
1055 mm_data->reg.sim_read_in_progress = TRUE;
1056
1057 /*
1058 * Read indicated EF in SIM_MM_INFO_IND from SIM.
1059 */
1060 reg_read_next_sim_file();
1061 }
1062 break;
1063
1064 default:
1065 break;
1066 }
1067
1068 if(GET_STATE (STATE_MM) == MM_IDLE_NORMAL_SERVICE)
1069 {
1070 reg_check_hplmn_tim(mm_data->reg.thplmn);
1071 }
1072 PFREE (sim_mm_info_ind);
1073 }
1074
1075
1076 /*
1077 +--------------------------------------------------------------------+
1078 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1079 | STATE : code ROUTINE : reg_sim_remove_ind |
1080 +--------------------------------------------------------------------+
1081
1082 PURPOSE : Process the primitive SIM_REMOVE_IND.
1083
1084 */
1085
1086 GLOBAL void reg_sim_remove_ind (T_SIM_REMOVE_IND *sim_remove_ind)
1087 {
1088 GET_INSTANCE_DATA;
1089 TRACE_FUNCTION ("reg_sim_remove_ind()");
1090
1091 mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_REMOVED */
1092
1093 // Better now instead after cause concept implementation in SIM also:
1094 // mm_data->limited_cause = sim_remove_ind->cause;
1095 //
1096 // Problem: None. But this affects not only the MM testcases, but
1097 // also ACI code. And as of the time of this writing it's a too
1098 // big risk to incorporate this in both entities. By the way,
1099 // also GMM should be enhanced in the future and at least a comment
1100 // incorporated in the respective SAPs that also SIM causes are transported.
1101
1102 if (mm_data->reg.sim_insert_info NEQ NULL)
1103 {
1104 /*
1105 * Pending MM RESTART procedure and now the SIM is physically removed.
1106 * Forget about the MM RESTART procedure.
1107 */
1108 PFREE (mm_data->reg.sim_insert_info);
1109 mm_data->reg.sim_insert_info = NULL;
1110 }
1111
1112 if (mm_gsm_alone())
1113 {
1114 /*
1115 * Clear SIM data for lower layer, start IMSI Detach,
1116 * indicate limited service etc.
1117 */
1118 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
1119 mm_mmr_nreg_req (CS_SIM_REM, MMGMM_PERFORM_DETACH);
1120 reg_init ();
1121 }
1122 #ifdef GPRS
1123 else
1124 {
1125 /* Remember there was a physical SIM removal */
1126 mm_data->gprs.sim_physically_removed = TRUE;
1127
1128 /* Commenting the OMAPS00048777 changes as it was a incomplete workaround.
1129 Refer the analysis section of the defect 71208 for details */
1130
1131 /* if(GET_STATE (STATE_MM) NEQ MM_CONN_ACTIVE)
1132 {*/
1133 mm_sim_removed_gprs_active ();
1134 /* }*/
1135
1136 /*
1137 * Possible IMSI DETACH and entering of MM_IDLE_NO_IMSI state will happen
1138 * after GMM sends
1139 * MMGMM_NREG_REQ (CS_SIM_REM, MMGMM_PERFORM_DETACH/MMGMM_DETACH_DONE).
1140 * Here no IMSI DETACH and invalidation of SIM data can be done as a
1141 * combined attach maybe performed in network mode I.
1142 */
1143 }
1144 #endif /* GPRS */
1145
1146 EM_SIM_REMOVE;
1147
1148 /* Debug hack. If they have a SIM driver problem, we hopefully will see it */
1149 mm_data->mm_idle_no_imsi_marker = 128;
1150 PFREE (sim_remove_ind);
1151 }
1152
1153 /*
1154 +--------------------------------------------------------------------+
1155 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1156 | STATE : code ROUTINE : reg_sim_sync_cnf |
1157 +--------------------------------------------------------------------+
1158
1159 PURPOSE : Process the primitive SIM_SYNC_CNF.
1160
1161 */
1162
1163 GLOBAL void reg_sim_sync_cnf (T_SIM_SYNC_CNF *sim_sync_cnf)
1164 {
1165 TRACE_FUNCTION ("reg_sim_sync_cnf()");
1166
1167 /*Nothing to be done. Just free the primitive to avoid memory leaks*/
1168 PFREE(sim_sync_cnf);
1169 }
1170
1171 /*
1172 +--------------------------------------------------------------------+
1173 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1174 | STATE : code ROUTINE : reg_sim_file_update_ind |
1175 +--------------------------------------------------------------------+
1176
1177 PURPOSE : Process the primitive SIM_FILE_UPDATE_IND.
1178 The worst case which may by caused by this primitive
1179 is a RR_ACTIVATE_REQ to inform RR about a changed
1180 HPLMN search period or a changed access class.
1181 It is guaranteed by GSM 11.14 subclause 6.4.7.1
1182 that here no field is changed which causes MM Restart procedure.
1183
1184
1185 */
1186 GLOBAL void reg_sim_file_upd_ind (T_SIM_FILE_UPDATE_IND *file_upd)
1187 {
1188 GET_INSTANCE_DATA;
1189 USHORT i;
1190
1191 TRACE_FUNCTION ("reg_sim_file_upd_ind()");
1192 /*
1193 * This flag is required to prevent MM to send Acknowledge completion of file update
1194 * if file reading was because of SIM_MM_INSERT_IND/SIM_MM_INFO_IND.
1195 */
1196 mm_data->reg.sim_file_upd_ind_rec = TRUE;
1197
1198 for (i = 0; i < file_upd->val_nr; i++)
1199 {
1200 if( file_upd->file_info[i].v_path_info EQ TRUE AND
1201 file_upd->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND
1202 file_upd->file_info[i].path_info.v_df_level2 EQ FALSE )
1203 {
1204 switch (file_upd->file_info[i].datafield)
1205 {
1206 case SIM_ACC: /* Access control class */
1207 mm_data->reg.upd_sim_acc = SAT_READ_FILE;
1208 break;
1209
1210 case SIM_PLMNSEL: /* Preferred PLMN list */
1211 mm_data->reg.upd_sim_plmnsel = SAT_READ_FILE;
1212 mm_data->reg.sim_plmnsel_len = NOT_PRESENT_16BIT;
1213 /*Set indicator sim reading is in progress to true*/
1214 mm_data->reg.sim_read_in_progress = TRUE;
1215 break;
1216
1217 case SIM_HPLMN: /* Home PLMN search period */
1218 mm_data->reg.upd_sim_hplmn = SAT_READ_FILE;
1219 break;
1220
1221 case SIM_FPLMN: /* Forbidden PLMN list */
1222 mm_data->reg.upd_sim_fplmn = SAT_READ_FILE;
1223 break;
1224
1225 #ifdef REL99
1226 case SIM_UCPS_ACTEC: /* User controlled PLMN selector with access technology list */
1227 mm_data->reg.upd_sim_ucps_at = SAT_READ_FILE;
1228 mm_data->reg.sim_ucps_at_len = NOT_PRESENT_16BIT;
1229 /*
1230 * If EFPLMNwAcT is changed, MM must have to re-read EFOPLMNwAcT to
1231 * make acomplete list of pref_plmn. Actual length which came in
1232 * SIM_MM_INSERT_IND can be used for EFOPLMNwAcT since file is unchanged.
1233 */
1234 mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE;
1235 /*Set indicator sim reading is in progress to true*/
1236 mm_data->reg.sim_read_in_progress = TRUE;
1237 break;
1238
1239 case SIM_OCPS_ACTEC: /* Operator controlled PLMN selector with access technology list*/
1240 /*If only this file is modified MM need not to re-read EFPLMNwAcT*/
1241 mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE;
1242 mm_data->reg.sim_ocps_at_len = NOT_PRESENT_16BIT;
1243 /*Set indicator sim reading is in progress to true*/
1244 mm_data->reg.sim_read_in_progress = TRUE;
1245 break;
1246 #endif
1247
1248 case SIM_IMSI:
1249 case SIM_LOCI: /* Does not happen this way, this is SIM_MM_INSERT_IND */
1250 /* FALLTHROUGH */
1251 case SIM_BCCH:
1252 case SIM_KC: /* Guaranteed to not happen */
1253 TRACE_ERROR ("File change not handled");
1254 break;
1255
1256 default: /* MM is not interested in this elementary file */
1257 break;
1258 }
1259 }
1260 else if((file_upd->file_info[i].path_info.df_level1 EQ SIM_DF_CING) AND
1261 (file_upd->file_info[i].path_info.v_df_level2 EQ TRUE) AND
1262 (file_upd->file_info[i].path_info.df_level2 EQ SIM_DF2_CING) AND
1263 (file_upd->file_info[i].datafield EQ SIM_CING_AHPLMN))
1264 {
1265 mm_data->reg.upd_sim_act_hplmn = SAT_READ_FILE;
1266 }
1267 }
1268
1269 PFREE (file_upd);
1270
1271 /* Start reading SIM elementary files */
1272 if (reg_read_next_sim_file() EQ FALSE)
1273 {
1274 /*
1275 * Nothing interesting for MM. Acknowledge completion of file update
1276 */
1277 PALLOC (update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */
1278 update_res->source = SRC_MM;
1279 update_res->fu_rsc = SIM_FU_SUCCESS;
1280 PSENDX (SIM, update_res);
1281 mm_data->reg.sim_file_upd_ind_rec = FALSE;
1282
1283 }
1284 }
1285
1286 /*
1287 +--------------------------------------------------------------------+
1288 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1289 | STATE : code ROUTINE : reg_send_sim_sync_req |
1290 +--------------------------------------------------------------------+
1291
1292 PURPOSE : Sends the primitive SIM_SYNC_REQ with cause.
1293
1294 */
1295
1296 GLOBAL void reg_send_sim_sync_req (void)
1297 {
1298 GET_INSTANCE_DATA;
1299 PALLOC (sync_req, SIM_SYNC_REQ);
1300 sync_req->synccs = (U8)SYNC_MM_FINISHED_READING;
1301 PSENDX (SIM, sync_req);
1302 mm_data->reg.sim_sync_req_pending = FALSE;
1303 }
1304
1305 /*
1306 +--------------------------------------------------------------------+
1307 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
1308 | STATE : code ROUTINE : reg_sim_read_cnf |
1309 +--------------------------------------------------------------------+
1310
1311 PURPOSE : Process the primitive SIM_READ_CNF.
1312
1313 */
1314
1315 GLOBAL void reg_sim_read_cnf (T_SIM_READ_CNF *sim_read_cnf)
1316 {
1317 GET_INSTANCE_DATA;
1318 TRACE_FUNCTION ("reg_sim_read_cnf()");
1319
1320 switch (mm_data->sim_read_req_data_field)
1321 {
1322 case SIM_ACC: /* Access control class */
1323 assert ((sim_read_cnf->cause EQ SIM_NO_ERROR) AND
1324 (sim_read_cnf->length >= 2));
1325
1326 mm_data->reg.upd_sim_acc = SAT_PEND_ACT; /* RR_ACTIVATE_REQ later */
1327 mm_data->reg.acc_class = sim_read_cnf->trans_data[0] * 256 +
1328 sim_read_cnf->trans_data[1];
1329 break;
1330
1331 case SIM_PLMNSEL: /* Preferred PLMN list, no further action */
1332 mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED;
1333
1334 if (sim_read_cnf->cause EQ SIM_NO_ERROR)
1335 {
1336 reg_read_pref_plmn(sim_read_cnf->trans_data, sim_read_cnf->length);
1337
1338 #ifdef REL99
1339 /* Set flage user/operator plmn selector with access tech. used to FALSE */
1340 mm_data->reg.sim_uocps_at_used = FALSE;
1341 #endif
1342
1343 }
1344 else
1345 {
1346
1347 TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x",
1348 SIM_PLMNSEL, sim_read_cnf->cause);
1349
1350 }
1351 if (mm_data->reg.sim_sync_req_pending EQ TRUE)
1352 {
1353 /* Allocate and send SIM_SYNC_REQ */
1354 reg_send_sim_sync_req();
1355 }
1356
1357 break;
1358
1359 #ifdef REL99
1360 case SIM_UCPS_ACTEC:
1361 /*user controlled PLMN selector with access technology list, No Further action???*/
1362 mm_data->reg.upd_sim_ucps_at = SAT_UNCHANGED;
1363
1364 if (sim_read_cnf->cause EQ SIM_NO_ERROR)
1365 {
1366 /*
1367 * EF PLMNsel will not be used. PLMNsel only be used if EFs EFPLMNwAcT or EFOPLMNwAcT
1368 * are not used. MM should not read EF SIM_PLMNSEL.
1369 */
1370 mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED;
1371
1372 if ( (mm_data->reg.sim_sync_req_pending == TRUE) &&
1373 (mm_data->reg.upd_sim_ocps_at != SAT_READ_FILE) ) /*EFOPLMNwAcT not read*/
1374 {
1375 /*EFOPLMNwAcT already read. Allocate and send SIM_SYNC_REQ*/
1376 reg_send_sim_sync_req();
1377 }
1378
1379 mm_data->reg.sim_uocps_at_used = TRUE;
1380 reg_read_ucps_acctec(sim_read_cnf->trans_data, sim_read_cnf->length);
1381 }
1382 else
1383 {
1384 TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x",
1385 SIM_UCPS_ACTEC, sim_read_cnf->cause);
1386
1387 mm_data->reg.sim_ucps_at_len = 0;
1388 if (mm_data->reg.upd_sim_ocps_at EQ SAT_UNCHANGED)
1389 {
1390 /*
1391 * EF PLMNsel can be used if indicated because EF EFPLMNwAcT reading error and
1392 * EFOPLMNwAcT is not indicated.
1393 */
1394 mm_data->reg.sim_uocps_at_used = FALSE;
1395 }
1396 }
1397 break;
1398 case SIM_OCPS_ACTEC:
1399 /*
1400 * Read Operator controlled PLMN selector with access technology list.
1401 * This can happens only after SIM insert indication indicates to read file from SIM.
1402 */
1403 mm_data->reg.upd_sim_ocps_at = SAT_UNCHANGED;
1404 if (sim_read_cnf->cause EQ SIM_NO_ERROR)
1405 {
1406 /*
1407 * EF PLMNsel will not be used. PLMNsel only be used if EFs EFPLMNwAcT or EFOPLMNwAcT
1408 * are not used. MM should not read EF SIM_PLMNSEL.
1409 */
1410 mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED;
1411
1412 if ( mm_data->reg.sim_sync_req_pending == TRUE )
1413 {
1414 /*EFPLMNwAcT already read. Allocate and send SIM_SYNC_REQ*/
1415 reg_send_sim_sync_req();
1416 }
1417
1418 mm_data->reg.sim_uocps_at_used = TRUE;
1419 reg_read_ocps_acctec(sim_read_cnf->trans_data, sim_read_cnf->length);
1420 }
1421 else
1422 {
1423 /*
1424 * EF PLMNsel can be used if indicated and if there was any error during reading of
1425 * EF EFPLMNwAcT.
1426 */
1427 TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x",
1428 SIM_OCPS_ACTEC, sim_read_cnf->cause);
1429 }
1430 break;
1431 #endif
1432
1433 case SIM_HPLMN: /* Home PLMN search period */
1434 assert ((sim_read_cnf->cause EQ SIM_NO_ERROR) AND
1435 (sim_read_cnf->length >= 1));
1436
1437 mm_data->reg.upd_sim_hplmn = SAT_PEND_ACT; /* RR_SYNC_REQ later */
1438 mm_data->reg.thplmn = sim_read_cnf->trans_data[0];
1439 if (mm_data->reg.thplmn > HPLMN_MAX_SEARCH_PERIOD)
1440 {
1441 /* 3GPP 22.011 subclause 3.2.2.5 requires to use the default value
1442 * if the value delivered by the SIM exceeds the allowed limit. */
1443 mm_data->reg.thplmn = HPLMN_DEF_SEARCH_PERIOD;
1444 }
1445 break;
1446
1447 case SIM_FPLMN: /* Forbidden PLMN list, no further action */
1448 {
1449 T_forb_plmn forb_plmn; /* Maybe avoidable by unclean cast */
1450
1451 assert(sim_read_cnf->cause EQ SIM_NO_ERROR);
1452
1453 /* Store new forbidden PLMN list, does this happen? */
1454 mm_data->reg.upd_sim_fplmn = SAT_UNCHANGED;
1455 forb_plmn.c_forb = sim_read_cnf->length;
1456 memcpy (forb_plmn.forb,
1457 sim_read_cnf->trans_data,
1458 sizeof (forb_plmn.forb));
1459 reg_read_forb_plmn (&forb_plmn);
1460 }
1461 break;
1462
1463 case SIM_CING_AHPLMN: /* AHPLMN Value read, RR_SYNC_REQ later */
1464 {
1465 U8 ahplmn[3];
1466
1467 assert(sim_read_cnf->cause EQ SIM_NO_ERROR);
1468
1469 mm_data->reg.upd_sim_act_hplmn = SAT_PEND_ACT;
1470 mm_data->reg.reg_plmn_equal_ahplmn = FALSE;
1471
1472 /* If the current RPLMN is AHPLMN then set the flag to true */
1473 if ( mm_data->reg.acting_hplmn.v_plmn AND
1474 reg_plmn_equal_rplmn(&mm_data->reg.acting_hplmn))
1475 {
1476 mm_data->reg.reg_plmn_equal_ahplmn = TRUE;
1477 }
1478
1479 memcpy(ahplmn,
1480 sim_read_cnf->trans_data,
1481 sizeof(ahplmn));
1482 reg_read_acting_hplmn(ahplmn);
1483 }
1484 break;
1485
1486 case SIM_IMSI: /* IMSI */
1487 case SIM_LOCI: /* Location information, not expected without IMSI */
1488 break; /* This will not happen this way */
1489
1490 case SIM_KC:
1491 case SIM_BCCH: /* Guaranteed not to be changed by SAT */
1492 break;
1493
1494 default:
1495 break;
1496 } /* switch */
1497
1498 mm_data->sim_read_req_data_field = NOT_PRESENT_16BIT;
1499
1500 PFREE (sim_read_cnf);
1501
1502 /* Read next changed elementary file */
1503 if (reg_read_next_sim_file() EQ FALSE)
1504 {
1505 /* All changed SIM files read */
1506 /* Acknowledge completion of file update */
1507 /* SIM_FILE_UPDATE_RES should be sent immediately after response
1508 from SIM : Issue 23561*/
1509 if(mm_data->reg.sim_file_upd_ind_rec)
1510 {
1511
1512 PALLOC (update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */
1513 update_res->source = SRC_MM;
1514 update_res->fu_rsc = SIM_FU_SUCCESS;
1515 PSENDX (SIM, update_res);
1516 mm_data->reg.sim_file_upd_ind_rec = FALSE;
1517 }
1518 /*
1519 * Set sim mm read in progress to False since MM has completed reading of
1520 * EFs(PLMNsel/EF EFPLMNwAcT/EFOPLMNwAcT) indicated in primitive SIM_MM_INSERT_IND
1521 * /SIM_MM_INFO_IND/SIM_FILE_UPDATE_IND. Also check if there was any rr_abort_ind
1522 * was received and stored becuaseof SIM reading was in progress.
1523 */
1524 if(mm_data->reg.sim_read_in_progress)
1525 {
1526 mm_data->reg.sim_read_in_progress = FALSE;
1527 USE_STORED_ENTRIES();
1528 }
1529 if (mm_data->reg.upd_sim_acc NEQ SAT_UNCHANGED)
1530 {
1531 /*
1532 * MM has to send a RR_SYNC_REQ
1533 * The actual changes of these fields are not tested by GSM 11.11
1534 */
1535 mm_data->reg.upd_sim_acc = SAT_UNCHANGED;
1536
1537 /* Inform RR about changes by SAT */
1538 mm_build_rr_sync_req_cause (SYNCCS_ACCC);
1539 }
1540
1541
1542 if (mm_data->reg.upd_sim_hplmn NEQ SAT_UNCHANGED)
1543 {
1544 if (mm_data->first_attach_mem AND
1545 mm_data->reg.thplmn NEQ 0)
1546 {
1547 /* do nothing : MM is in initial search period. So, the timer
1548 should not be restarted. The new value is stored and after initial
1549 search the timer should be restarted with this new value*/
1550 }
1551 else
1552 {
1553 /* Start HPLMN search timer with new value */
1554 reg_stop_hplmn_tim ();
1555 reg_check_hplmn_tim(mm_data->reg.thplmn);
1556 }
1557 }/*end of mm_data->reg.upd_sim_hplmn*/
1558
1559
1560 if (mm_data->reg.upd_sim_act_hplmn NEQ SAT_UNCHANGED )
1561 {
1562 BOOL valid_ahplmn= FALSE;
1563 valid_ahplmn = valid_acting_hplmn(&mm_data->reg.acting_hplmn);
1564 mm_build_rr_sync_hplmn_req();
1565 if (valid_ahplmn)
1566 {
1567 /* Delete the AHPLMN entry from the Forbidden list, if present*/
1568 if ( mm_data->reg.acting_hplmn.v_plmn)
1569 {
1570 /* Remove from forbidden PLMN list if stored */
1571 TRACE_FUNCTION(" AHPLMN is being deleted from the Forbidden List");
1572 reg_plmn_bad_del (mm_data->reg.forb_plmn,
1573 MAX_FORB_PLMN_ID,
1574 &mm_data->reg.acting_hplmn);
1575 }
1576
1577 /*Inform ACI of the new AHPLMN value*/
1578 mm_mmgmm_ahplmn_ind(&mm_data->reg.acting_hplmn);
1579
1580 /* Delete any Equivalent PLMN list */
1581 reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE);
1582
1583
1584 /* If AHPLMN value read from SIM is same as the RPLMN then inform
1585 * RR about it. No need of registering again. Set the flag
1586 * to true so that hplmn will now be taken from this
1587 */
1588 if (reg_plmn_equal_rplmn(&mm_data->reg.acting_hplmn))
1589 {
1590 reg_stop_hplmn_tim ();
1591 }
1592 else
1593 {
1594 mm_data->plmn_scan_mm = TRUE;
1595 /* Start with AHPLMN registration */
1596 mm_func_mmgmm_net_req();
1597 }
1598 }
1599 else
1600 {
1601 T_plmn hplmn;
1602
1603 /*Inform ACI of the new AHPLMN value*/
1604 mm_mmgmm_ahplmn_ind(&mm_data->reg.acting_hplmn);
1605
1606 /* Since mm_data->reg.acting_hplmn.v_plmn is FALSE it will take HPLMN from IMSI */
1607 reg_extract_hplmn(&hplmn);
1608
1609 if (reg_plmn_equal_rplmn(&hplmn))
1610 {
1611 /* Do Nothing. MS is already registered to True-HPLMN */
1612 }
1613 else
1614 {
1615 /* If AHPLMN is FFFFFF OR we are on already on an AHPLMN MM should
1616 * immediately start a network search for HPLMN
1617 */
1618 if (mm_data->reg.acting_hplmn_invalid OR
1619 mm_data->reg.reg_plmn_equal_ahplmn)
1620 {
1621 mm_data->plmn_scan_mm = TRUE;
1622 mm_func_mmgmm_net_req();
1623 }
1624 else
1625 {
1626 /*Do Nothing. Since MS is registered to any other PLMN HPPLMN
1627 Timer will be running. Network scan will start after the
1628 Timer expires
1629 */
1630 }
1631 }/*reg_plmn_equal_rplmn*/
1632 }/*valid_acting_hplmn*/
1633 check_if_cingular_sim(); /*for cingular only 31179*/
1634 }/*end of mm_data->reg.upd_sim_act_hplmn*/
1635 }/*end of reg_read_next_sim_file*/
1636 }/*end of reg_sim_read_cnf*/
1637
1638
1639 #endif
1640