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