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