FreeCalypso > hg > freecalypso-citrine
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 |