FreeCalypso > hg > fc-magnetite
comparison src/aci2/aci/cmh_mmf.c @ 3:93999a60b835
src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 26 Sep 2016 00:29:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:c41a534f33c6 | 3:93999a60b835 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : GSM-PS (6147) | |
4 | Modul : CMH_MMF | |
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 module defines the functions used by the command | |
18 | handler for mobility management. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef CMH_MMF_C | |
23 #define CMH_MMF_C | |
24 #endif | |
25 | |
26 #include "aci_all.h" | |
27 | |
28 /*==== INCLUDES ===================================================*/ | |
29 #include "aci_cmh.h" | |
30 #include "ati_cmd.h" | |
31 #include "aci_cmd.h" | |
32 #include "aci_mem.h" | |
33 #include "pcm.h" | |
34 | |
35 #ifdef FAX_AND_DATA | |
36 #include "aci_fd.h" | |
37 #endif /* of #ifdef FAX_AND_DATA */ | |
38 | |
39 #include "aci.h" | |
40 #include "psa.h" | |
41 #include "psa_cc.h" | |
42 #include "psa_mm.h" | |
43 #include "psa_sim.h" | |
44 #include "psa_sat.h" | |
45 #include "psa_util.h" | |
46 #include "cmh.h" | |
47 | |
48 #ifdef DTI | |
49 #include "dti.h" /* functionality of the dti library */ | |
50 #include "dti_conn_mng.h" | |
51 /* #include "dti_cntrl_mng.h" */ | |
52 #endif | |
53 | |
54 | |
55 #ifdef GPRS | |
56 #include "gaci.h" | |
57 #include "gaci_cmh.h" | |
58 #include "psa_gmm.h" | |
59 #include "cmh_gmm.h" | |
60 #endif /* GPRS */ | |
61 | |
62 #include "cmh_mm.h" | |
63 #include "cmh_sim.h" | |
64 | |
65 | |
66 #ifndef _SIMULATION_ | |
67 #include "ffs/ffs.h" | |
68 #include "ffs_coat.h" | |
69 #endif /* !_SIMULATION_ */ | |
70 | |
71 #ifdef FF_CPHS | |
72 #include "cphs.h" | |
73 #endif /* FF_CPHS */ | |
74 | |
75 /*==== CONSTANTS ==================================================*/ | |
76 /* Countries, for which the ECC should be ignored, i.e. done as normal call */ | |
77 /* contains MCC and ECC, last element should be always NULL*/ | |
78 GLOBAL const T_ECCIgnoreRec ECCIgnoreTable[] = | |
79 { | |
80 { 0x260, ALL_MNC, "999" }, /* Poland */ | |
81 { 0x454, 0x04F, "112" }, /* "HK ORANGE" */ | |
82 { 0x454, 0x10F, "112" }, /* "HK New World" */ | |
83 { -1, -1, NULL } /* End mark */ | |
84 }; | |
85 | |
86 #define ONS_EXT_DCS 0x80 | |
87 | |
88 /*==== TYPES ======================================================*/ | |
89 | |
90 /*==== EXPORT =====================================================*/ | |
91 | |
92 /*==== VARIABLES ==================================================*/ | |
93 LOCAL T_OPER_ENTRY ONSDesc; | |
94 GLOBAL T_ONS_READ_STATE ONSReadStatus = ONS_READ_NOT_DONE; | |
95 | |
96 /* This is required because FFS is not available in the Simulation Mode */ | |
97 #ifdef _SIMULATION_ | |
98 T_FFSPLMNIMSI RAMPlmnIMSI = {0}; | |
99 #endif | |
100 | |
101 #if defined GPRS AND defined (DTI) | |
102 EXTERN T_GMM_SHRD_PRM gmmShrdPrm; | |
103 #endif | |
104 /*==== FUNCTIONS ==================================================*/ | |
105 | |
106 /* | |
107 +-------------------------------------------------------------------+ | |
108 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
109 | ROUTINE : cmhMM_wild_compare | | |
110 +-------------------------------------------------------------------+ | |
111 | |
112 PURPOSE : | |
113 | |
114 */ | |
115 | |
116 LOCAL BOOL cmhMM_wild_compare( int sim, int bcch ) | |
117 { | |
118 if ((bcch & 0x00F) != (sim & 0x00F) AND (sim & 0x00F) != 0x00D) | |
119 return FALSE; | |
120 if ((bcch & 0x0F0) != (sim & 0x0F0) AND (sim & 0x0F0) != 0x0D0) | |
121 return FALSE; | |
122 if ((bcch & 0xF00) != (sim & 0xF00) AND (sim & 0xF00) != 0xD00) | |
123 return FALSE; | |
124 | |
125 return TRUE; | |
126 } | |
127 | |
128 | |
129 /* | |
130 +-------------------------------------------------------------------+ | |
131 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
132 | ROUTINE : cmhSIM_plmn_equal_sim_wc| | |
133 +-------------------------------------------------------------------+ | |
134 | |
135 PURPOSE : | |
136 | |
137 */ | |
138 | |
139 LOCAL BOOL cmhSIM_plmn_equal_sim_wc (int bcch_mcc, int bcch_mnc, | |
140 int sim_mcc, int sim_mnc) | |
141 { | |
142 /*TRACE_FUNCTION ("cmhSIM_plmn_equal_sim()");*/ | |
143 | |
144 /* Check MCC */ | |
145 if (!cmhMM_wild_compare(sim_mcc, bcch_mcc)) | |
146 return FALSE; | |
147 | |
148 /* Check first 2 MNC digits */ | |
149 if (!cmhMM_wild_compare(sim_mnc & 0xff0, bcch_mnc & 0xff0)) | |
150 return FALSE; | |
151 | |
152 /* Check for full match */ | |
153 if (cmhMM_wild_compare(sim_mnc & 0xf, bcch_mnc & 0xf)) | |
154 return TRUE; | |
155 | |
156 /* The 3rd digit of the MNC differs */ | |
157 if ((bcch_mcc >= 0x310) AND (bcch_mcc <= 0x316)) | |
158 { | |
159 /* | |
160 * The MCC is in the range 310..316, this means North America. | |
161 * The zero suffix rule applies. | |
162 */ | |
163 return ((((sim_mnc & 0xf) EQ 0xf) AND ((bcch_mnc & 0xf) EQ 0x0)) OR | |
164 (((sim_mnc & 0xf) EQ 0x0) AND ((bcch_mnc & 0xf) EQ 0xf))); | |
165 } | |
166 return ((bcch_mnc & 0xf) EQ 0xf); | |
167 } | |
168 | |
169 | |
170 /* | |
171 +-------------------------------------------------------------------+ | |
172 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
173 | ROUTINE : cmhMM_FindPLMN | | |
174 +-------------------------------------------------------------------+ | |
175 | |
176 PURPOSE : scan the list of operators to find the PLMN | |
177 representation. | |
178 | |
179 NOTE: This function looks as if it could be simplified and | |
180 shortened. However, it is expected that it works. | |
181 | |
182 */ | |
183 | |
184 GLOBAL BOOL cmhMM_FindPLMN( T_OPER_ENTRY * plmnDesc, | |
185 SHORT mcc, SHORT mnc, U16 lac, BOOL nw_search ) | |
186 { | |
187 int i; /* holds list idx */ | |
188 EF_PLMN plmn; /* holds PLMN identifier */ | |
189 SHORT sim_mcc; /* Integer representation MCC */ | |
190 SHORT sim_mnc; /* Integer representation MNC */ | |
191 USHORT maxRec; /* holds maximum records */ | |
192 USHORT recNr; /* holds record number */ | |
193 UBYTE retVal; /* holds return value */ | |
194 UBYTE ver; /* holds version */ | |
195 | |
196 /* | |
197 *------------------------------------------------------------------- | |
198 * search list of PNN records if SIM is EONS enabled | |
199 *------------------------------------------------------------------- | |
200 */ | |
201 | |
202 TRACE_FUNCTION ("cmhMM_FindPLMN()"); | |
203 TRACE_EVENT_P3 ("mcc: %x, mnc %x, lac: %x", mcc, mnc, lac); | |
204 | |
205 /* Initial conditions for Data Coding Scheme and PLMN name source */ | |
206 memset (plmnDesc, 0, sizeof (T_OPER_ENTRY)); | |
207 /* plmnDesc.dcs = 0; */ | |
208 plmnDesc->pnn = FALSE; | |
209 | |
210 if(psaSIM_ChkSIMSrvSup(SRV_PNN)) | |
211 { | |
212 if (!nw_search) /* this is not for network search list */ | |
213 { | |
214 if(psaSIM_ChkSIMSrvSup(SRV_OPL) || cmhSIM_plmn_is_hplmn (mcc, mnc)) | |
215 { | |
216 if (mmShrdPrm.PNNLst.plmn.v_plmn EQ VLD_PLMN) | |
217 { | |
218 plmnDesc->mcc = mcc; | |
219 plmnDesc->mnc = mnc; | |
220 plmnDesc->pnn = TRUE; | |
221 plmnDesc->long_len = mmShrdPrm.PNNLst.long_len; | |
222 plmnDesc->long_ext_dcs = mmShrdPrm.PNNLst.long_ext_dcs; | |
223 plmnDesc->shrt_len = mmShrdPrm.PNNLst.shrt_len; | |
224 plmnDesc->shrt_ext_dcs = mmShrdPrm.PNNLst.shrt_ext_dcs; | |
225 | |
226 if(mmShrdPrm.PNNLst.long_len) | |
227 { | |
228 memcpy (plmnDesc->longName, | |
229 mmShrdPrm.PNNLst.long_name, | |
230 MINIMUM(mmShrdPrm.PNNLst.long_len, MAX_LONG_OPER_LEN - 1)); | |
231 } | |
232 | |
233 if(mmShrdPrm.PNNLst.shrt_len > 0) | |
234 { | |
235 memcpy (plmnDesc->shrtName, | |
236 mmShrdPrm.PNNLst.shrt_name, | |
237 MINIMUM(mmShrdPrm.PNNLst.shrt_len, MAX_SHRT_OPER_LEN - 1)); | |
238 } | |
239 return TRUE; | |
240 } | |
241 else | |
242 { | |
243 U16 current_lac = lac; | |
244 if (current_lac EQ NOT_PRESENT_16BIT) | |
245 current_lac = mmShrdPrm.lac; | |
246 | |
247 for (i=0; i<simShrdPrm.opl_list.num_rcd; i++) | |
248 { | |
249 int pnn_rec_number = simShrdPrm.opl_list.opl_rcd[i].pnn_rec_num; | |
250 SHORT sim_mcc, sim_mnc; | |
251 | |
252 cmhSIM_getMncMccFrmPLMNsel (simShrdPrm.opl_list.opl_rcd[i].plmn, | |
253 &sim_mcc, &sim_mnc); | |
254 | |
255 if (pnn_rec_number EQ 0xFF) | |
256 continue; /* empty record, continue with next one */ | |
257 | |
258 if(cmhSIM_plmn_equal_sim_wc( mcc, mnc, sim_mcc, sim_mnc) AND | |
259 ( (simShrdPrm.opl_list.opl_rcd[i].lac1 EQ 0x0000 AND | |
260 simShrdPrm.opl_list.opl_rcd[i].lac2 EQ 0xFFFE) | |
261 OR | |
262 (simShrdPrm.opl_list.opl_rcd[i].lac1 <= current_lac AND | |
263 simShrdPrm.opl_list.opl_rcd[i].lac2 >= current_lac) ) ) | |
264 { | |
265 if (pnn_rec_number EQ 0) | |
266 break; /* 31.102: 4.2.59 EFOPL (Operator PLMN List): | |
267 A value of '00' indicates that the name is to be taken from other sources, see TS 22.101 [24] */ | |
268 | |
269 pnn_rec_number--; /* adjust to zero based array */ | |
270 | |
271 if (simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].v_plmn) | |
272 { | |
273 plmnDesc->mcc = mcc; | |
274 plmnDesc->mnc = mnc; | |
275 plmnDesc->pnn = TRUE; | |
276 plmnDesc->long_len = | |
277 MINIMUM (simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].long_len, MAX_LONG_OPER_LEN - 1); | |
278 memcpy (plmnDesc->longName, | |
279 simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].long_name, | |
280 plmnDesc->long_len); | |
281 plmnDesc->long_ext_dcs = simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].long_ext_dcs; | |
282 plmnDesc->shrt_len = | |
283 MINIMUM (simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].shrt_len, MAX_SHRT_OPER_LEN - 1); | |
284 memcpy (plmnDesc->shrtName, | |
285 simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].shrt_name, | |
286 plmnDesc->shrt_len); | |
287 plmnDesc->shrt_ext_dcs = simShrdPrm.pnn_list.pnn_rcd[pnn_rec_number].shrt_ext_dcs; | |
288 return TRUE; | |
289 } | |
290 } | |
291 } | |
292 } | |
293 } | |
294 } | |
295 | |
296 else /* the procedure is used for building the PLMN selection list */ | |
297 { | |
298 T_pnn_name *current; /* points to PNN element currently compared */ | |
299 current = (T_pnn_name *)mmShrdPrm.PNNLst.next; | |
300 while (current != NULL) | |
301 { | |
302 SHORT sim_mcc, sim_mnc; | |
303 cmhMM_CnvrtPLMN2INT (current->plmn.mcc, current->plmn.mnc, | |
304 &sim_mcc, &sim_mnc); | |
305 if (cmhSIM_plmn_equal_sim (mcc, mnc, sim_mcc, sim_mnc) AND | |
306 (current->lac EQ lac)) | |
307 { | |
308 if(current->plmn.v_plmn EQ VLD_PLMN) | |
309 { | |
310 plmnDesc->mcc = mcc; | |
311 plmnDesc->mnc = mnc; | |
312 plmnDesc->pnn = TRUE; | |
313 plmnDesc->long_len = | |
314 MINIMUM (current->long_len, MAX_LONG_OPER_LEN - 1); | |
315 plmnDesc->long_ext_dcs = current->long_ext_dcs; | |
316 plmnDesc->shrt_len = | |
317 MINIMUM (current->shrt_len, MAX_SHRT_OPER_LEN - 1); | |
318 plmnDesc->shrt_ext_dcs = current->shrt_ext_dcs; | |
319 if (current->long_len) | |
320 { | |
321 memcpy (plmnDesc->longName, | |
322 current->long_name, | |
323 plmnDesc->long_len); | |
324 } | |
325 | |
326 if (current->shrt_len) | |
327 { | |
328 memcpy (plmnDesc->shrtName, | |
329 current->shrt_name, | |
330 plmnDesc->shrt_len); | |
331 } | |
332 return TRUE; | |
333 } | |
334 } | |
335 else | |
336 current = (T_pnn_name *)current->next; | |
337 } | |
338 } | |
339 } | |
340 | |
341 if((ONSReadStatus EQ ONS_READ_OVER) AND cmhSIM_plmn_is_hplmn (mcc, mnc)) | |
342 { | |
343 | |
344 *plmnDesc = ONSDesc; /* Struct assignment */ | |
345 | |
346 plmnDesc->mcc = mcc; | |
347 plmnDesc->mnc = mnc; | |
348 return TRUE; | |
349 } | |
350 | |
351 /* | |
352 *------------------------------------------------------------------- | |
353 * search list of operators ( PCM table ) | |
354 *------------------------------------------------------------------- | |
355 */ | |
356 recNr = 1; | |
357 | |
358 do | |
359 { | |
360 retVal= pcm_ReadRecord( (UBYTE *) EF_PLMN_ID, recNr, SIZE_EF_PLMN, | |
361 (UBYTE *)&plmn, &ver, &maxRec ); | |
362 | |
363 if( retVal EQ PCM_INVALID_SIZE OR retVal EQ PCM_INVALID_RECORD ) | |
364 break; | |
365 | |
366 sim_mcc = (plmn.mcc[0] << 8) + plmn.mcc[1]; | |
367 sim_mnc = (plmn.mnc[0] << 8) + plmn.mnc[1]; | |
368 | |
369 if (cmhSIM_plmn_equal_sim (mcc, mnc, sim_mcc, sim_mnc)) | |
370 { | |
371 cmhMM_CnvrtTrmPCMOpNam( plmnDesc, &plmn ); | |
372 | |
373 plmnDesc->mcc = sim_mcc; | |
374 plmnDesc->mnc = sim_mnc; | |
375 return TRUE; | |
376 } | |
377 | |
378 recNr++; | |
379 } | |
380 while( recNr <= maxRec ); | |
381 | |
382 /* | |
383 *------------------------------------------------------------------- | |
384 * search list of operators ( fixed table ) | |
385 *------------------------------------------------------------------- | |
386 */ | |
387 for( i = 0; | |
388 operListFixed[i].mcc NEQ -1 AND operListFixed[i].mnc NEQ -1; | |
389 i++ ) | |
390 { | |
391 sim_mcc = operListFixed[i].mcc; | |
392 sim_mnc = operListFixed[i].mnc; | |
393 | |
394 if (cmhSIM_plmn_equal_sim (mcc, mnc, sim_mcc, sim_mnc)) | |
395 { | |
396 strncpy (plmnDesc->longName, | |
397 operListFixed[i].longName, | |
398 MAX_LONG_OPER_LEN - 1); | |
399 strncpy (plmnDesc->shrtName, | |
400 operListFixed[i].shrtName, | |
401 MAX_SHRT_OPER_LEN - 1); | |
402 plmnDesc->mcc = operListFixed[i].mcc; | |
403 plmnDesc->mnc = operListFixed[i].mnc; | |
404 return TRUE; | |
405 } | |
406 } | |
407 | |
408 /* | |
409 *------------------------------------------------------------------- | |
410 * only mnc and mcc description available | |
411 *------------------------------------------------------------------- | |
412 */ | |
413 plmnDesc->mcc = mcc; | |
414 plmnDesc->mnc = mnc; | |
415 /* | |
416 * The competitor has here a more sophisticated algorithm: | |
417 * If they know the country code, they don't display the | |
418 * MCC in numerical representation, but an abbreviation | |
419 * for the country. We are satisfied displaying the MCC | |
420 * and saving the ROM space for the country table. | |
421 */ | |
422 if ( ( mnc & 0xF) NEQ 0xf ) /* is 3rd digit mnc? */ | |
423 { | |
424 sprintf (plmnDesc->longName, "%03x %03x", mcc, mnc); | |
425 } | |
426 else | |
427 { /* only 2-digit-MNC */ | |
428 mnc = (mnc & 0x0FF0) >> 4; | |
429 sprintf (plmnDesc->longName, "%03x %02x", mcc, mnc); | |
430 } | |
431 strcpy (plmnDesc->shrtName, plmnDesc->longName); | |
432 | |
433 return TRUE; | |
434 } | |
435 | |
436 /* | |
437 +-------------------------------------------------------------------+ | |
438 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
439 | ROUTINE : cmhMM_isBandAllowed | | |
440 +-------------------------------------------------------------------+ | |
441 | |
442 PURPOSE : Check if band combination is part of bands allowed by manufacturer. | |
443 To be used by AT%BAND. | |
444 Per convention: if AllowedBands = 0, all bands are allowed. | |
445 band 0 is never allowed (that is not a combination !!) | |
446 */ | |
447 | |
448 GLOBAL BOOL cmhMM_isBandAllowed( UBYTE band, UBYTE AllowedBands ) | |
449 { | |
450 if( AllowedBands EQ 0x00 ) | |
451 { | |
452 /* no manufacturer constraint */ | |
453 return(TRUE); | |
454 } | |
455 if( band EQ 0x00) | |
456 { | |
457 return(FALSE); | |
458 } | |
459 | |
460 if( (band & AllowedBands) EQ band ) | |
461 { | |
462 return( TRUE ); | |
463 } | |
464 else | |
465 return( FALSE ); | |
466 } | |
467 | |
468 /* | |
469 +---------------------------------------------------------------------+ | |
470 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
471 | ROUTINE : cmhMM_writeSetBand | | |
472 +---------------------------------------------------------------------+ | |
473 | |
474 PURPOSE : | |
475 | |
476 */ | |
477 #define SIZE_OF_RFCAP (16*sizeof(UBYTE)) | |
478 | |
479 GLOBAL BOOL cmhMM_writeSetBand( UBYTE setband ) | |
480 { | |
481 #ifndef _SIMULATION_ | |
482 T_FFS_RET ret_ffs; | |
483 UBYTE RFCap[SIZE_OF_RFCAP]; /* RFCap has 16 bytes */ | |
484 | |
485 ret_ffs = FFS_fread("/gsm/com/rfcap", | |
486 RFCap, | |
487 SIZE_OF_RFCAP); | |
488 if(ret_ffs < 1) /* error */ | |
489 { | |
490 TRACE_EVENT_P1("RFCap: cannot read FFS: error n: %d", ret_ffs); | |
491 return(FALSE); | |
492 } | |
493 | |
494 /* write user bands into FFS */ | |
495 RFCap[0] = setband; | |
496 | |
497 ret_ffs = FFS_fwrite("/gsm/com/rfcap", | |
498 RFCap, | |
499 SIZE_OF_RFCAP); | |
500 | |
501 if( ret_ffs NEQ EFFS_OK ) | |
502 { | |
503 TRACE_EVENT_P1("Cannot write value on RFCap, error n: %d", ret_ffs); | |
504 return(FALSE); | |
505 } | |
506 TRACE_EVENT("cmhMM_writeSetBand: data writing in FFS successful"); | |
507 #endif /* _SIMULATION_ */ | |
508 | |
509 return( TRUE ); | |
510 } | |
511 | |
512 /* | |
513 +---------------------------------------------------------------------+ | |
514 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
515 | ROUTINE : cmhMM_getBandSettings | | |
516 +---------------------------------------------------------------------+ | |
517 | |
518 PURPOSE : | |
519 */ | |
520 | |
521 GLOBAL void cmhMM_getBandSettings( UBYTE *SetBands, UBYTE *AllowedBands ) | |
522 { | |
523 UBYTE intern_set_bands = 0x00, /* initialized to NOT SET */ | |
524 intern_allowed_bands = 0x00; /* avoid several checks against NULL */ | |
525 #ifndef _SIMULATION_ | |
526 UBYTE RFCap[SIZE_OF_RFCAP]; /* RFCap has 16 bytes */ | |
527 T_FFS_RET ret_ffs; | |
528 | |
529 TRACE_FUNCTION("cmhMM_getBandSettings()"); | |
530 | |
531 ret_ffs = FFS_fread("/gsm/com/rfcap", | |
532 RFCap, | |
533 SIZE_OF_RFCAP); | |
534 if(ret_ffs < 1) /* error */ | |
535 { | |
536 TRACE_EVENT_P1("cmhMM_getBandSettings: RFCap: cannot read FFS: error n: %d", ret_ffs); | |
537 } | |
538 else | |
539 { | |
540 TRACE_EVENT("cmhMM_getBandSettings: data reading from FFS successful"); | |
541 intern_set_bands = RFCap[0]; | |
542 intern_allowed_bands = RFCap[1]; | |
543 } | |
544 #endif /* #ifndef _SIMULATION_ */ | |
545 | |
546 if( SetBands NEQ NULL ) | |
547 { | |
548 *SetBands = intern_set_bands; | |
549 TRACE_EVENT_P1("User defined Band bitfield: %d", *SetBands); | |
550 } | |
551 if( AllowedBands NEQ NULL ) | |
552 { | |
553 *AllowedBands = intern_allowed_bands; | |
554 TRACE_EVENT_P1("Manufacturer defined Band bitfield: %d", *AllowedBands); | |
555 } | |
556 } | |
557 | |
558 /* | |
559 +-------------------------------------------------------------------+ | |
560 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
561 | ROUTINE : cmhMM_FindNumeric | | |
562 +-------------------------------------------------------------------+ | |
563 | |
564 PURPOSE : Convert operator representation from string into numeric. | |
565 | |
566 NOTE: The cmhMM_FindNumeric() function is not part of the public | |
567 declared interface to ACI. | |
568 However some guys from the MFW team are using this function | |
569 in mfw_nma.c, declaring the function prototype in the | |
570 nfw_nma.c file locally. Be careful with changes. | |
571 | |
572 */ | |
573 | |
574 GLOBAL BOOL cmhMM_FindNumeric( T_OPER_ENTRY * plmnDesc, const CHAR *numStr ) | |
575 { | |
576 USHORT idx; | |
577 BOOL ready; | |
578 | |
579 TRACE_FUNCTION ("cmhMM_FindNumeric()"); | |
580 | |
581 plmnDesc->mcc = 0; | |
582 plmnDesc->mnc = 0; | |
583 ready = FALSE; | |
584 | |
585 /* | |
586 * Convert string representation into internal represention | |
587 */ | |
588 for (idx = 0; idx < SIZE_MCC + SIZE_MNC; idx++) | |
589 { | |
590 if (idx < SIZE_MCC) | |
591 { | |
592 /* | |
593 * Converting MCC | |
594 */ | |
595 if (!ready AND | |
596 numStr[idx] >= '0' AND numStr[idx] <= '9') | |
597 { | |
598 plmnDesc->mcc = (plmnDesc->mcc << 4) + numStr[idx] - '0'; | |
599 } | |
600 else | |
601 { | |
602 ready = TRUE; | |
603 } | |
604 } | |
605 else | |
606 { | |
607 /* | |
608 * Converting MNC | |
609 */ | |
610 if (!ready AND | |
611 numStr[idx] >= '0' AND numStr[idx] <= '9') | |
612 { | |
613 plmnDesc->mnc = (plmnDesc->mnc << 4) + numStr[idx] - '0'; | |
614 } | |
615 else | |
616 { | |
617 ready = TRUE; | |
618 if ((plmnDesc->mnc & 0x00F) NEQ 0xF) | |
619 plmnDesc->mnc = (plmnDesc->mnc << 4) + 0xF; | |
620 } | |
621 } | |
622 } | |
623 | |
624 /* | |
625 *------------------------------------------------------------------- | |
626 * search list of operators | |
627 *------------------------------------------------------------------- | |
628 */ | |
629 | |
630 (void)cmhMM_FindPLMN (plmnDesc, plmnDesc->mcc, plmnDesc->mnc, NOT_PRESENT_16BIT, FALSE); | |
631 | |
632 /* decode 7 Bit default GSM for MFW */ | |
633 if (plmnDesc->pnn) | |
634 { | |
635 char longName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
636 char shrtName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
637 | |
638 longName[0]=shrtName[0]='\0'; | |
639 | |
640 if (plmnDesc->long_len) | |
641 { | |
642 switch (plmnDesc->long_ext_dcs>>4 & 0x07) | |
643 { | |
644 case 0x00: | |
645 utl_cvtPnn7To8((UBYTE *)plmnDesc->longName, | |
646 (UBYTE) plmnDesc->long_len, | |
647 plmnDesc->long_ext_dcs, | |
648 (UBYTE *)longName); | |
649 break; | |
650 case 0x01: | |
651 TRACE_ERROR ("ERROR: Unhandled UCS2"); | |
652 break; | |
653 default: | |
654 TRACE_ERROR ("ERROR: Unknown DCS"); | |
655 break; | |
656 } | |
657 strncpy (plmnDesc->longName, longName, MAX_LONG_OPER_LEN - 1); | |
658 plmnDesc->longName[MAX_LONG_OPER_LEN - 1] = '\0'; | |
659 plmnDesc->long_len = strlen(longName); | |
660 } | |
661 if (plmnDesc->shrt_len) | |
662 { | |
663 switch (plmnDesc->shrt_ext_dcs>>4 & 0x07) | |
664 { | |
665 case 0x00: | |
666 utl_cvtPnn7To8((UBYTE *)plmnDesc->shrtName, | |
667 (UBYTE) plmnDesc->shrt_len, | |
668 plmnDesc->shrt_ext_dcs, | |
669 (UBYTE *)shrtName); | |
670 break; | |
671 case 0x01: | |
672 TRACE_ERROR ("ERROR: Unhandled UCS2"); | |
673 break; | |
674 default: | |
675 TRACE_ERROR ("ERROR: Unknown DCS"); | |
676 break; | |
677 } | |
678 strncpy (plmnDesc->shrtName, shrtName, MAX_SHRT_OPER_LEN - 1); | |
679 plmnDesc->shrtName[MAX_SHRT_OPER_LEN - 1] = '\0'; | |
680 plmnDesc->shrt_len = strlen(shrtName); | |
681 } | |
682 } | |
683 return TRUE; | |
684 } | |
685 | |
686 /* | |
687 +-------------------------------------------------------------------+ | |
688 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
689 | ROUTINE : cmhMM_FindName | | |
690 +-------------------------------------------------------------------+ | |
691 | |
692 PURPOSE : scan the list of operators to find the short or long name | |
693 representation. | |
694 | |
695 NOTE: The cmhMM_FindName() function is not part of the public | |
696 declared interface to ACI. | |
697 However some guys from the MFW team are using this function | |
698 in mfw_nma.c, declaring the function prototype in the | |
699 nfw_nma.c file locally. Be careful with changes. | |
700 | |
701 | |
702 */ | |
703 | |
704 GLOBAL BOOL cmhMM_FindName( T_OPER_ENTRY * plmnDesc, | |
705 const CHAR *string, T_ACI_CPOL_FRMT format ) | |
706 { | |
707 USHORT idx; /* holds list idx */ | |
708 EF_PLMN plmn; /* holds PLMN identifier */ | |
709 USHORT maxRec; /* holds maximum records */ | |
710 USHORT recNr; /* holds record number */ | |
711 UBYTE retVal; /* holds return value */ | |
712 UBYTE ver; /* holds version */ | |
713 char longName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
714 char shrtName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
715 | |
716 /* | |
717 *------------------------------------------------------------------- | |
718 * search list of PNN records if SIM is EONS enabled | |
719 *------------------------------------------------------------------- | |
720 */ | |
721 if(psaSIM_ChkSIMSrvSup(SRV_PNN) && psaSIM_ChkSIMSrvSup(SRV_OPL)) | |
722 { | |
723 T_pnn_name *current; /* points to PNN element currently compared */ | |
724 | |
725 current = (T_pnn_name *)mmShrdPrm.PNNLst.next; | |
726 while (current != NULL) | |
727 { | |
728 longName[0]=shrtName[0]='\0'; | |
729 | |
730 if (current->long_len) | |
731 { | |
732 switch (current->long_ext_dcs>>4 & 0x07) | |
733 { | |
734 case 0x00: | |
735 utl_cvtPnn7To8((UBYTE *)current->long_name, | |
736 current->long_len, | |
737 current->long_ext_dcs, | |
738 (UBYTE *)longName); | |
739 break; | |
740 case 0x01: | |
741 TRACE_ERROR ("ERROR: Unhandled UCS2"); | |
742 break; | |
743 default: | |
744 TRACE_ERROR ("ERROR: Unknown DSC"); | |
745 break; | |
746 } | |
747 } | |
748 | |
749 if (current->shrt_len) | |
750 { | |
751 switch (current->shrt_ext_dcs>>4 & 0x07) | |
752 { | |
753 case 0x00: | |
754 utl_cvtPnn7To8((UBYTE *)current->shrt_name, | |
755 current->shrt_len, | |
756 current->shrt_ext_dcs, | |
757 (UBYTE *)shrtName); | |
758 break; | |
759 case 0x01: | |
760 TRACE_ERROR ("ERROR: Unhandled UCS2"); | |
761 break; | |
762 default: | |
763 TRACE_ERROR ("ERROR: Unknown DSC"); | |
764 break; | |
765 } | |
766 } | |
767 | |
768 if((format EQ CPOL_FRMT_Long) && (strcmp (string, (char *)longName) EQ 0) || | |
769 (format EQ CPOL_FRMT_Short) && (strcmp (string,(char *)shrtName) EQ 0)) | |
770 { | |
771 plmnDesc->pnn = 1; | |
772 /* decode Name since MFW expects 8-Bit string */ | |
773 strncpy (plmnDesc->longName, longName, MAX_LONG_OPER_LEN - 1); | |
774 plmnDesc->longName[MAX_LONG_OPER_LEN - 1] = '\0'; | |
775 plmnDesc->long_len = strlen (plmnDesc->longName); | |
776 | |
777 strncpy (plmnDesc->shrtName, shrtName, MAX_SHRT_OPER_LEN - 1); | |
778 plmnDesc->shrtName[MAX_SHRT_OPER_LEN -1] = '\0'; | |
779 plmnDesc->shrt_len = strlen (plmnDesc->shrtName); | |
780 | |
781 cmhMM_CnvrtPLMN2INT( current->plmn.mcc, | |
782 current->plmn.mnc, | |
783 &plmnDesc->mcc, &plmnDesc->mnc ); | |
784 | |
785 if (current->plmn.v_plmn EQ VLD_PLMN) | |
786 { | |
787 return TRUE; | |
788 } | |
789 } | |
790 else | |
791 current = (T_pnn_name *)current->next; | |
792 } | |
793 } | |
794 | |
795 /* | |
796 *------------------------------------------------------------------- | |
797 * search list of operators ( PCM table ) | |
798 *------------------------------------------------------------------- | |
799 */ | |
800 recNr = 1; | |
801 | |
802 do | |
803 { | |
804 retVal= pcm_ReadRecord( (UBYTE *) EF_PLMN_ID, recNr, SIZE_EF_PLMN, | |
805 (UBYTE *)&plmn, &ver, &maxRec ); | |
806 | |
807 if( retVal EQ PCM_INVALID_SIZE OR retVal EQ PCM_INVALID_RECORD ) | |
808 break; | |
809 | |
810 cmhMM_CnvrtTrmPCMOpNam( plmnDesc, &plmn ); | |
811 | |
812 if ((format EQ CPOL_FRMT_Short AND | |
813 strcmp(plmnDesc->shrtName, string) EQ 0) OR | |
814 (format EQ CPOL_FRMT_Long AND | |
815 strcmp(plmnDesc->longName, string) EQ 0)) | |
816 { | |
817 plmnDesc->mcc = (plmn.mcc[0] << 8) + plmn.mcc[1]; | |
818 plmnDesc->mnc = (plmn.mnc[0] << 8) + plmn.mnc[1]; | |
819 return TRUE; | |
820 } | |
821 | |
822 recNr++; | |
823 } | |
824 while( recNr <= maxRec ); | |
825 | |
826 /* | |
827 *------------------------------------------------------------------- | |
828 * search list of operators ( fixed table ) | |
829 *------------------------------------------------------------------- | |
830 */ | |
831 for( idx = 0; operListFixed[idx].shrtName NEQ NULL; idx++ ) | |
832 { | |
833 if ((format EQ CPOL_FRMT_Short AND | |
834 strcmp((char*)operListFixed[idx].shrtName, string) EQ 0) OR | |
835 (format EQ CPOL_FRMT_Long AND | |
836 strcmp((char*)operListFixed[idx].longName, string) EQ 0)) | |
837 { | |
838 memset (plmnDesc, 0, sizeof (T_OPER_ENTRY)); | |
839 strncpy (plmnDesc->longName, | |
840 operListFixed[idx].longName, | |
841 MAX_LONG_OPER_LEN - 1); | |
842 strncpy (plmnDesc->shrtName, | |
843 operListFixed[idx].shrtName, | |
844 MAX_SHRT_OPER_LEN - 1); | |
845 plmnDesc->mcc = operListFixed[idx].mcc; | |
846 plmnDesc->mnc = operListFixed[idx].mnc; | |
847 return TRUE; | |
848 } | |
849 } | |
850 | |
851 return FALSE; | |
852 } | |
853 | |
854 /* | |
855 +-------------------------------------------------------------------+ | |
856 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
857 | ROUTINE : cmhMM_CnvrtPLMN2INT | | |
858 +-------------------------------------------------------------------+ | |
859 | |
860 PURPOSE : convert the BCD PLMN notation for mcc and mnc into | |
861 integer values. | |
862 */ | |
863 | |
864 GLOBAL void cmhMM_CnvrtPLMN2INT( const UBYTE * BCDmcc, const UBYTE * BCDmnc, | |
865 SHORT * mccBuf, SHORT * mncBuf ) | |
866 { | |
867 SHORT idx; | |
868 | |
869 /* | |
870 * Convert MCC | |
871 */ | |
872 *mccBuf = 0; | |
873 | |
874 for (idx = 0; idx < SIZE_MCC; idx++) | |
875 { | |
876 *mccBuf = (*mccBuf << 4) + BCDmcc[idx]; | |
877 } | |
878 | |
879 /* | |
880 * Convert MNC | |
881 */ | |
882 *mncBuf = 0; | |
883 | |
884 for (idx = 0; idx < SIZE_MNC; idx++) | |
885 { | |
886 *mncBuf = (*mncBuf << 4) + BCDmnc[idx]; | |
887 } | |
888 } | |
889 | |
890 /* | |
891 +-------------------------------------------------------------------+ | |
892 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
893 | ROUTINE : cmhMM_CnvrtINT2PLMN | | |
894 +-------------------------------------------------------------------+ | |
895 | |
896 PURPOSE : convert the integer PLMN notation for mcc and mnc into | |
897 BCD representation. | |
898 */ | |
899 | |
900 GLOBAL void cmhMM_CnvrtINT2PLMN( SHORT INTmcc, SHORT INTmnc, | |
901 UBYTE * mccBuf, UBYTE * mncBuf ) | |
902 { | |
903 SHORT idx; | |
904 SHORT shift; | |
905 | |
906 /* | |
907 * Convert MCC | |
908 */ | |
909 shift = 0; | |
910 | |
911 for (idx = SIZE_MCC - 1; idx >= 0; idx--) | |
912 { /*lint -e{702} */ | |
913 mccBuf[idx] = (INTmcc >> shift) & 0xf; | |
914 shift += 4; | |
915 } | |
916 | |
917 /* | |
918 * Convert MNC | |
919 */ | |
920 shift = 0; | |
921 | |
922 for (idx = SIZE_MNC - 1; idx >= 0; idx--) | |
923 { /*lint -e{702} */ | |
924 mncBuf[idx] = (INTmnc >> shift) & 0xf; | |
925 shift += 4; | |
926 } | |
927 } | |
928 | |
929 /* | |
930 +-------------------------------------------------------------------+ | |
931 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
932 | ROUTINE : cmhMM_GetNregCREGStat | | |
933 +-------------------------------------------------------------------+ | |
934 | |
935 PURPOSE : return CREG status for a not registered state. | |
936 */ | |
937 | |
938 GLOBAL T_ACI_CREG_STAT cmhMM_GetNregCREGStat( void ) | |
939 { | |
940 switch( mmShrdPrm.regMode ) | |
941 { | |
942 case( MODE_AUTO ): | |
943 | |
944 #if defined GPRS AND defined (DTI) | |
945 if ( cmhGMM_isClassCG() ) | |
946 return(CREG_STAT_NoSearch); | |
947 else | |
948 #endif | |
949 { | |
950 /* Depending on the deregistration cause proper CREG state has been sent to the user */ | |
951 switch(mmShrdPrm.deregCs) | |
952 { | |
953 case( NREG_LIMITED_SERVICE ): | |
954 return(CREG_STAT_Denied); | |
955 case( NREG_NO_SERVICE ): | |
956 return(CREG_STAT_NoSearch); | |
957 default: | |
958 return(CREG_STAT_Unknown); | |
959 } | |
960 } | |
961 case( MODE_MAN ): | |
962 return(CREG_STAT_NoSearch); | |
963 | |
964 default: | |
965 return(CREG_STAT_Unknown); | |
966 } | |
967 } | |
968 | |
969 /* | |
970 +-------------------------------------------------------------------+ | |
971 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
972 | ROUTINE : cmhMM_GetNregCMEStat | | |
973 +-------------------------------------------------------------------+ | |
974 | |
975 PURPOSE : return CME error status for a not registered state. | |
976 */ | |
977 | |
978 GLOBAL T_ACI_CME_ERR cmhMM_GetNregCMEStat( void ) | |
979 { | |
980 switch( mmShrdPrm.regStat ) | |
981 { | |
982 case( NO_VLD_RS ): | |
983 case( RS_NO_SRV ): | |
984 | |
985 return( CME_ERR_NoServ ); | |
986 | |
987 case( RS_LMTD_SRV ): | |
988 | |
989 return( CME_ERR_LimServ ); | |
990 | |
991 default: | |
992 | |
993 return( CME_ERR_Unknown ); | |
994 } | |
995 } | |
996 | |
997 /* | |
998 +-------------------------------------------------------------------+ | |
999 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
1000 | ROUTINE : cmhMM_GetOperLstLen | | |
1001 +-------------------------------------------------------------------+ | |
1002 | |
1003 PURPOSE : return CME error status for a not registered state. | |
1004 */ | |
1005 | |
1006 GLOBAL USHORT cmhMM_GetOperLstLen( void ) | |
1007 { | |
1008 return((sizeof(operListFixed)/sizeof(T_OPER_NTRY_FIXED))-1); | |
1009 } | |
1010 | |
1011 /* | |
1012 +-------------------------------------------------------------------+ | |
1013 | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | |
1014 | ROUTINE : cmhMM_CnvrtTrmPCMOpNam | | |
1015 +-------------------------------------------------------------------+ | |
1016 | |
1017 PURPOSE : Convert and terminate PCM long and short operator names. | |
1018 */ | |
1019 | |
1020 GLOBAL void cmhMM_CnvrtTrmPCMOpNam( T_OPER_ENTRY *plmnDesc, void *pPCMBuf ) | |
1021 { | |
1022 UBYTE len; | |
1023 EF_PLMN * pPlmn = (EF_PLMN *)pPCMBuf; | |
1024 | |
1025 /* convert and terminate long name */ | |
1026 for( len = 0; | |
1027 len < SIZE_EF_PLMN_LONG AND pPlmn->lngNam[len] NEQ 0xFF; | |
1028 len++ ) | |
1029 ; | |
1030 | |
1031 if (len > MAX_LONG_OPER_LEN - 1) | |
1032 len = MAX_LONG_OPER_LEN - 1; | |
1033 | |
1034 utl_cvtGsmIra( pPlmn->lngNam, len, | |
1035 (UBYTE *)plmnDesc->longName, len, | |
1036 CSCS_DIR_GsmToIra ); | |
1037 | |
1038 plmnDesc->longName[len] = '\0'; | |
1039 | |
1040 /* convert and terminate short name */ | |
1041 for( len = 0; | |
1042 len < SIZE_EF_PLMN_SHRT AND pPlmn->shrtNam[len] NEQ 0xFF; | |
1043 len++ ) | |
1044 ; | |
1045 | |
1046 if (len > MAX_SHRT_OPER_LEN - 1) | |
1047 len = MAX_SHRT_OPER_LEN - 1; | |
1048 | |
1049 utl_cvtGsmIra( pPlmn->shrtNam, len, | |
1050 (UBYTE *)plmnDesc->shrtName, len, | |
1051 CSCS_DIR_GsmToIra ); | |
1052 | |
1053 plmnDesc->shrtName[len] = '\0'; | |
1054 } | |
1055 | |
1056 /* | |
1057 +----------------------------------------------------------------------------+ | |
1058 | PROJECT : GSM-PS (6147) MODULE : CMH | | |
1059 | ROUTINE : cmhMM_Ntfy_NtwRegistrationStatus | | |
1060 +----------------------------------------------------------------------------+ | |
1061 | |
1062 PURPOSE : report function | |
1063 */ | |
1064 #ifdef FF_CPHS | |
1065 LOCAL BOOL has_roaming_state_changed(T_ACI_CREG_STAT creg) | |
1066 { | |
1067 static T_ACI_CREG_STAT last_creg_notified = CREG_STAT_NotPresent; | |
1068 UBYTE previous_creg; | |
1069 | |
1070 TRACE_EVENT_P2("has_roaming_state_changed() creg: %d, previous creg: %d", creg, last_creg_notified); | |
1071 previous_creg = last_creg_notified; | |
1072 | |
1073 /* update last_creg_notified */ | |
1074 last_creg_notified = creg; | |
1075 | |
1076 /* status has not changed at all */ | |
1077 if(creg EQ previous_creg) | |
1078 return(FALSE); | |
1079 | |
1080 /* Mobile is entering Roaming service: since creg is different from last_creg */ | |
1081 if(creg EQ CREG_STAT_Roam) | |
1082 return(TRUE); | |
1083 | |
1084 /* Mobile is not in Roaming service: Check whether this has already been told to the user */ | |
1085 if(previous_creg EQ CREG_STAT_Roam) | |
1086 return(TRUE); | |
1087 | |
1088 return(FALSE); | |
1089 } | |
1090 | |
1091 LOCAL void cmhMM_cphs_roaming(T_ACI_CREG_STAT creg) | |
1092 { | |
1093 if(has_roaming_state_changed(creg)) | |
1094 { | |
1095 /* Roaming state has changed */ | |
1096 if(creg EQ CREG_STAT_Roam) | |
1097 { | |
1098 cphs_roaming_ind(CPHS_ROAMING_ON); | |
1099 } | |
1100 else if(creg NEQ CREG_STAT_NotPresent) | |
1101 { | |
1102 cphs_roaming_ind(CPHS_ROAMING_OFF); | |
1103 } | |
1104 } | |
1105 } | |
1106 #endif /* FF_CPHS */ | |
1107 | |
1108 GLOBAL void cmhMM_Ntfy_NtwRegistrationStatus( T_ACI_CREG_STAT creg ) | |
1109 { | |
1110 SHORT src; | |
1111 T_ACI_P_CREG_GPRS_IND gprs_ind; | |
1112 | |
1113 TRACE_FUNCTION ("cmhMM_Ntfy_NtwRegistrationStatus()"); | |
1114 | |
1115 #ifdef FF_CPHS | |
1116 cmhMM_cphs_roaming(creg); | |
1117 #endif /* FF_CPHS */ | |
1118 | |
1119 #if defined (GPRS) AND defined (DTI) | |
1120 gprs_ind = gmmShrdPrm.gprs_indicator; | |
1121 #else | |
1122 gprs_ind = P_CREG_GPRS_Not_Supported; /* ACI-SPR-17218: use ACI type */ | |
1123 #endif | |
1124 | |
1125 /* notify GSM change in network status */ | |
1126 /* +CREG */ | |
1127 if( creg NEQ CREG_STAT_NotPresent ) | |
1128 { | |
1129 mmShrdPrm.creg_status = creg; | |
1130 | |
1131 for( src = 0; src < CMD_SRC_MAX; src++ ) | |
1132 { | |
1133 R_AT( RAT_CREG, src )( creg, mmShrdPrm.lac, mmShrdPrm.cid ); | |
1134 R_AT( RAT_P_CREG, src )( creg, mmShrdPrm.lac, mmShrdPrm.cid, gprs_ind ); | |
1135 } | |
1136 } | |
1137 } | |
1138 | |
1139 /* | |
1140 +-------------------------------------------------------------------------------------+ | |
1141 | PROJECT : GSM-PS MODULE : CMH | | |
1142 | ROUTINE : cmhMM_OpCheckName | | |
1143 +-------------------------------------------------------------------------------------+ | |
1144 | |
1145 PURPOSE : Function for EONS support. Checks if the operator name should be | |
1146 read from EF_PNN upon registration or location update. | |
1147 */ | |
1148 GLOBAL void cmhMM_OpCheckName() | |
1149 { | |
1150 SHORT mncCur, mccCur; /* holds converted mnc and mcc of current PLMN */ | |
1151 SHORT mncOpl, mccOpl; | |
1152 T_opl_field *ptrOpl; | |
1153 UBYTE i, pnn_rec_num=0; | |
1154 | |
1155 TRACE_FUNCTION ("cmhMM_OpCheckName()"); | |
1156 | |
1157 /* check if PNN is active and allocated on SIM */ | |
1158 if(psaSIM_ChkSIMSrvSup(SRV_PNN)) | |
1159 { | |
1160 /* check if OPL is active and allocated */ | |
1161 /* if OPL not activate the first record of PNN holds the operator name of the HPLMN */ | |
1162 if(!psaSIM_ChkSIMSrvSup(SRV_OPL)) | |
1163 { | |
1164 /* only read PNN if not already present */ | |
1165 if(mmShrdPrm.PNNLst.plmn.v_plmn != VLD_PLMN) | |
1166 { | |
1167 /* if HPLMN: this sequence is copied from cmhMM_Registered() */ | |
1168 cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc, | |
1169 mmShrdPrm.usedPLMN.mnc, | |
1170 &mccCur, &mncCur ); | |
1171 if( cmhSIM_plmn_is_hplmn (mccCur, mncCur)) | |
1172 { | |
1173 cmhMM_OpReadName(1); | |
1174 } | |
1175 } | |
1176 return; | |
1177 } | |
1178 /* check if the registered PLMN or LAC has changed since last registration */ | |
1179 | |
1180 if (memcmp (mmShrdPrm.usedPLMN.mcc, mmShrdPrm.PNNLst.plmn.mcc, SIZE_MCC) != 0 || | |
1181 memcmp (mmShrdPrm.usedPLMN.mnc, mmShrdPrm.PNNLst.plmn.mnc, SIZE_MNC) != 0 || | |
1182 mmShrdPrm.lac != mmShrdPrm.PNNLst.lac) | |
1183 { | |
1184 ptrOpl = cmhSIM_GetOPL(); | |
1185 if (ptrOpl->opl_status) | |
1186 { | |
1187 /* search the OPL list for the new PNN record number */ | |
1188 i = 0; | |
1189 pnn_rec_num = 0; /* if PNN record number in OPL is 0, no PNN name is available. */ | |
1190 while (i < ptrOpl->num_rcd) | |
1191 { | |
1192 cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc, | |
1193 mmShrdPrm.usedPLMN.mnc, | |
1194 &mccCur, &mncCur ); | |
1195 | |
1196 cmhSIM_getMncMccFrmPLMNsel (ptrOpl->opl_rcd[i].plmn, | |
1197 &mccOpl, &mncOpl); | |
1198 | |
1199 if(cmhSIM_plmn_equal_sim_wc (mccCur, mncCur, mccOpl, mncOpl) AND | |
1200 (ptrOpl->opl_rcd[i].lac1 <= mmShrdPrm.lac) AND | |
1201 (mmShrdPrm.lac <= ptrOpl->opl_rcd[i].lac2)) | |
1202 { | |
1203 pnn_rec_num = ptrOpl->opl_rcd[i].pnn_rec_num; | |
1204 break; | |
1205 } | |
1206 else | |
1207 i++; | |
1208 } | |
1209 if (pnn_rec_num != 0) | |
1210 { | |
1211 /* only read PNN if it is different from the last one saved */ | |
1212 if (mmShrdPrm.PNNLst.pnn_rec_num != pnn_rec_num) | |
1213 { | |
1214 cmhMM_OpReadName(pnn_rec_num); | |
1215 mmShrdPrm.PNNLst.plmn.v_plmn = INVLD_PLMN; | |
1216 } | |
1217 } | |
1218 } | |
1219 else | |
1220 TRACE_EVENT("OPL list unavailable");; /* no OPL list available */ | |
1221 } | |
1222 } | |
1223 | |
1224 /* if CPHS ONS file is not already read then read it */ | |
1225 if (!pnn_rec_num AND (ONSReadStatus EQ ONS_READ_NOT_DONE)) | |
1226 { | |
1227 #ifdef FF_CPHS | |
1228 cmhMM_ONSReadName(); | |
1229 #endif | |
1230 mmShrdPrm.PNNLst.plmn.v_plmn = INVLD_PLMN; | |
1231 } | |
1232 } | |
1233 /* | |
1234 +-------------------------------------------------------------------+ | |
1235 | PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | | |
1236 | STATE : code ROUTINE : cmhMM_OpReadName | | |
1237 +-------------------------------------------------------------------+ | |
1238 | |
1239 PURPOSE : Sends a SIM read request | |
1240 | |
1241 RESULT: has an error occured ? | |
1242 Returns: FALSE if primitive has been sent and TRUE if not | |
1243 */ | |
1244 GLOBAL BOOL cmhMM_OpReadName(UBYTE rcd) | |
1245 { | |
1246 TRACE_FUNCTION ("cmhMM_OpReadName()"); | |
1247 | |
1248 if (cmhSIM_ReadRecordEF (CMD_SRC_NONE, | |
1249 AT_CMD_NONE, | |
1250 SIM_PNN, | |
1251 rcd, | |
1252 NOT_PRESENT_8BIT, | |
1253 NULL, | |
1254 cmhMM_OpReadNameCb) EQ AT_FAIL) | |
1255 { | |
1256 TRACE_EVENT("FATAL ERROR"); | |
1257 return(TRUE); | |
1258 } | |
1259 return(FALSE); | |
1260 } | |
1261 | |
1262 /* | |
1263 +---------------------------------------------------------------------------------+ | |
1264 | PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | | |
1265 | STATE : code ROUTINE : cmhMM_OpReadNameCb | | |
1266 +---------------------------------------------------------------------------------+ | |
1267 | |
1268 PURPOSE : Call back for SIM retrieval of EF_PNN. | |
1269 */ | |
1270 GLOBAL void cmhMM_OpReadNameCb(SHORT table_id) | |
1271 { | |
1272 UBYTE *data; | |
1273 TRACE_FUNCTION ("cmhMM_OpReadNameCb()"); | |
1274 | |
1275 data = simShrdPrm.atb[table_id].exchData; | |
1276 | |
1277 /* Decode and copy PNN record data to PNN list*/ | |
1278 /*------------------------------------------*/ | |
1279 | |
1280 if (simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR) /* Process only if file is read */ | |
1281 { | |
1282 | |
1283 mmShrdPrm.PNNLst.plmn = mmShrdPrm.usedPLMN; | |
1284 mmShrdPrm.PNNLst.lac = mmShrdPrm.lac; | |
1285 mmShrdPrm.PNNLst.pnn_rec_num = simShrdPrm.atb[table_id].recNr; | |
1286 | |
1287 if (*data++ EQ PNN_LONG_NAME_IEI) | |
1288 { | |
1289 mmShrdPrm.PNNLst.long_len = (*data++)-1; /* substract dcs byte from lem */ | |
1290 mmShrdPrm.PNNLst.long_ext_dcs = *data++; | |
1291 memcpy (mmShrdPrm.PNNLst.long_name, | |
1292 data, | |
1293 MINIMUM(mmShrdPrm.PNNLst.long_len, sizeof(mmShrdPrm.PNNLst.long_name))); | |
1294 data += mmShrdPrm.PNNLst.long_len; | |
1295 | |
1296 /* PNN_SHORT_NAME_IEI is an optional field */ | |
1297 if (*data++ EQ PNN_SHORT_NAME_IEI) | |
1298 { | |
1299 mmShrdPrm.PNNLst.shrt_len = (*data++)-1; /* substract dcs byte from len */ | |
1300 mmShrdPrm.PNNLst.shrt_ext_dcs = *data++; | |
1301 memcpy (mmShrdPrm.PNNLst.shrt_name, | |
1302 data, | |
1303 MINIMUM(mmShrdPrm.PNNLst.shrt_len, sizeof(mmShrdPrm.PNNLst.shrt_name))); | |
1304 } | |
1305 else | |
1306 { | |
1307 mmShrdPrm.PNNLst.shrt_len = 0; | |
1308 } | |
1309 | |
1310 mmShrdPrm.PNNLst.next = NULL; | |
1311 } | |
1312 else /* PNN_LONG_NAME_IEI is a mandatory field in PNN, if not present, PNN is invalid */ | |
1313 { | |
1314 /* PNN record number 0 indicates no PNN name is available */ | |
1315 mmShrdPrm.PNNLst.pnn_rec_num = 0; | |
1316 } | |
1317 } | |
1318 cmhMM_Registered (); | |
1319 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
1320 } | |
1321 | |
1322 /* | |
1323 +---------------------------------------------------------------------------------------------+ | |
1324 | PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | | |
1325 | STATE : code ROUTINE : cmhMM_OpSetPNNLst | | |
1326 +---------------------------------------------------------------------------------------------+ | |
1327 | |
1328 PURPOSE : starts reading of EF_PNN from SIM and creates PNN list for manual PLMN selection. | |
1329 */ | |
1330 GLOBAL void cmhMM_OpSetPNNLst() | |
1331 { | |
1332 T_opl_field *ptrOpl; | |
1333 UBYTE i,j, pnn_rec_num; | |
1334 | |
1335 TRACE_FUNCTION ("cmhMM_OpSetPNNLst()"); | |
1336 | |
1337 ptrOpl = cmhSIM_GetOPL(); | |
1338 if (ptrOpl->opl_status) | |
1339 { | |
1340 mmShrdPrm.pnn_read_cnt = 0; | |
1341 /* search the OPL list for the PNN record number | |
1342 for every entry in the network search lists */ | |
1343 | |
1344 /* OPL list is searched for every entry in the network search lists */ | |
1345 for (j=0; j < MAX_PLMN_ID; j++) | |
1346 { | |
1347 /* check if entry in PLMNLst is valid */ | |
1348 if( mmShrdPrm.PLMNLst[j].v_plmn != INVLD_PLMN ) | |
1349 { | |
1350 pnn_rec_num = 0; /* if PNN record number in OPL is 0, no PNN name is available. */ | |
1351 i = 0; | |
1352 ptrOpl = cmhSIM_GetOPL(); | |
1353 while (i < ptrOpl->num_rcd) /* search OPL list for PLMN nr. j */ | |
1354 { | |
1355 SHORT bcch_mcc, bcch_mnc; | |
1356 SHORT sim_mcc, sim_mnc; | |
1357 | |
1358 cmhMM_CnvrtPLMN2INT (mmShrdPrm.PLMNLst[j].mcc, mmShrdPrm.PLMNLst[j].mnc, | |
1359 &bcch_mcc, &bcch_mnc); | |
1360 cmhSIM_getMncMccFrmPLMNsel (ptrOpl->opl_rcd[i].plmn, | |
1361 &sim_mcc, &sim_mnc); | |
1362 if (cmhSIM_plmn_equal_sim (bcch_mcc, bcch_mnc, sim_mcc, sim_mnc) AND | |
1363 ((ptrOpl->opl_rcd[i].lac1 EQ 0x0000 AND | |
1364 ptrOpl->opl_rcd[i].lac2 EQ 0xFFFE) OR | |
1365 (ptrOpl->opl_rcd[i].lac1 <= mmShrdPrm.LACLst[j] AND | |
1366 mmShrdPrm.LACLst[j] <= ptrOpl->opl_rcd[i].lac2))) | |
1367 { | |
1368 pnn_rec_num = ptrOpl->opl_rcd[i].pnn_rec_num; | |
1369 break; | |
1370 } | |
1371 else | |
1372 i++; | |
1373 } | |
1374 if (pnn_rec_num != 0) | |
1375 { | |
1376 if (cmhSIM_ReadRecordEF (CMD_SRC_NONE, | |
1377 AT_CMD_NONE, | |
1378 SIM_PNN, | |
1379 pnn_rec_num, /* the PNN rec. number is read */ | |
1380 NOT_PRESENT_8BIT, | |
1381 NULL, | |
1382 cmhMM_OpExtractNameCB) EQ AT_FAIL) | |
1383 { | |
1384 TRACE_EVENT("FATAL ERROR"); | |
1385 break; /* try to continue with the next one instead of return | |
1386 since otherwise AT+COPS=? will hang if cmhMM_NetworkLst() is not called! */ | |
1387 } | |
1388 /* in cmhMM_OpExtractNameCB the latest received PNN is placed right after the PNN-list head */ | |
1389 /* pnn_nr array is used for finding the associated plmn and lac in cmhMM_OpExtractNameCB. */ | |
1390 mmShrdPrm.pnn_nr[j] = pnn_rec_num; | |
1391 mmShrdPrm.pnn_read_cnt++; | |
1392 } | |
1393 else | |
1394 { | |
1395 /* name is to be taken from other sources, 3G TS 22.101 */ | |
1396 } | |
1397 } | |
1398 else | |
1399 { | |
1400 break; /* and Invalid PLMN indicates the end of the list. */ | |
1401 } | |
1402 } | |
1403 if (mmShrdPrm.pnn_read_cnt EQ 0) /* nothing processed? */ | |
1404 { | |
1405 if(( mmEntStat.curCmd EQ AT_CMD_COPS) OR ( mmEntStat.curCmd EQ AT_CMD_P_COPS) ) | |
1406 cmhMM_NetworkLst(); /* then print list anyway, otherwise AT+COPS=? will fail. */ | |
1407 } | |
1408 } | |
1409 else | |
1410 { | |
1411 if(( mmEntStat.curCmd EQ AT_CMD_COPS) OR ( mmEntStat.curCmd EQ AT_CMD_P_COPS) ) | |
1412 cmhMM_NetworkLst(); /* then print list anyway, otherwise AT+COPS=? will fail. */ | |
1413 } | |
1414 } | |
1415 | |
1416 /* | |
1417 +-------------------------------------------------------------------+ | |
1418 | PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | | |
1419 | STATE : code ROUTINE : cmhMM_OpExtractName | | |
1420 +-------------------------------------------------------------------+ | |
1421 | |
1422 PURPOSE : decodes EF_PNN record read from SIM. | |
1423 */ | |
1424 GLOBAL void cmhMM_OpExtractNameCB(SHORT table_id) | |
1425 { | |
1426 UBYTE *data; | |
1427 UBYTE i; | |
1428 T_pnn_name *newPNN; | |
1429 | |
1430 TRACE_FUNCTION ("cmhMM_OpExtractNameCB()"); | |
1431 | |
1432 data = simShrdPrm.atb[table_id].exchData; | |
1433 | |
1434 if (*data++ EQ PNN_LONG_NAME_IEI) | |
1435 { | |
1436 MALLOC(newPNN,sizeof(T_pnn_name)); | |
1437 newPNN->next = NULL; | |
1438 | |
1439 newPNN->pnn_rec_num = simShrdPrm.atb[table_id].recNr; | |
1440 | |
1441 /*find the associated PLMN and LAC for this PNN */ | |
1442 i = 0; | |
1443 while (i < MAX_PLMN_ID) | |
1444 { | |
1445 if (mmShrdPrm.pnn_nr[i] EQ newPNN->pnn_rec_num) | |
1446 { | |
1447 newPNN->plmn = mmShrdPrm.PLMNLst[i]; | |
1448 newPNN->lac = mmShrdPrm.LACLst[i]; | |
1449 break; | |
1450 } | |
1451 else | |
1452 i++; | |
1453 } | |
1454 | |
1455 newPNN->long_len = (*data++)-1; /* substract dcs byte */ | |
1456 newPNN->long_ext_dcs = *data++; | |
1457 memcpy (newPNN->long_name, | |
1458 data, | |
1459 MINIMUM(newPNN->long_len, sizeof(newPNN->long_name))); | |
1460 data += newPNN->long_len; | |
1461 | |
1462 /*----- IEI PNN short name ------*/ | |
1463 if (*data++ EQ PNN_SHORT_NAME_IEI) | |
1464 { | |
1465 newPNN->shrt_len = (*data++)-1; /* substract dcs byte */ | |
1466 newPNN->shrt_ext_dcs = *data++; | |
1467 memcpy (newPNN->shrt_name, | |
1468 data, | |
1469 MINIMUM(newPNN->shrt_len,sizeof(newPNN->shrt_name))); | |
1470 } | |
1471 else | |
1472 { | |
1473 newPNN->shrt_len = 0; | |
1474 } | |
1475 | |
1476 /* insert new element right after the static stored PNN name. */ | |
1477 newPNN->next = mmShrdPrm.PNNLst.next; | |
1478 mmShrdPrm.PNNLst.next = newPNN; | |
1479 } | |
1480 | |
1481 mmShrdPrm.pnn_read_cnt--; /* reading of PNN records completed, network list is prepared */ | |
1482 if (mmShrdPrm.pnn_read_cnt EQ 0) | |
1483 cmhMM_NetworkLst (); | |
1484 | |
1485 /* Deallocation of elements in linked list PNN */ | |
1486 // As you see, you see nothing. | |
1487 // ============================ | |
1488 | |
1489 // Immediate deallocation is not possible as someone could have | |
1490 // the idea to do a AT+COPS=? and immediately thereafter a | |
1491 // AT+COPS=1,0,"T-Mobile D" or AT+COPS=1,1,"TMO D" | |
1492 // A workaround could be to free everything not present in the actual | |
1493 // network list. Until now only a theoretical problem. For further study. | |
1494 | |
1495 // There is a second problem that this MM EONS extension list is not | |
1496 // affected by SAT changes of the respective files. Until now also | |
1497 // only theoretical and for further study. | |
1498 | |
1499 // And there is a third problem. This is, there exist 2 solutions | |
1500 // in the PS for EONS, the first one sitting in SIM related ACI around | |
1501 // the T_pnn data structure and the second one sitting in MM related ACI | |
1502 // around the T_pnn_name data structure. Two solutions for the same | |
1503 // problem. | |
1504 | |
1505 // => We should consider in the future to remove the implementation around | |
1506 // T_pnn_name and to enhance the T_pnn in SIM to end up in only one | |
1507 // implementation. This would improve the PS and save ROM. | |
1508 // Maybe the increasement of PNN_MAX_RECORDS to MAX_PLMN_ID + 1 or | |
1509 // something somewhat bigger will already do, otherwise an | |
1510 // intelligent entry replacement (aging) algorithm has to be introduced. | |
1511 // For further study. | |
1512 | |
1513 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
1514 | |
1515 } | |
1516 | |
1517 /* | |
1518 +-------------------------------------------------------------------------------------+ | |
1519 | PROJECT : GSM-PS MODULE : CMH | | |
1520 | ROUTINE : cmhMM_OpUpdateName | | |
1521 +-------------------------------------------------------------------------------------+ | |
1522 | |
1523 PURPOSE : Function for EONS support. Updates the operator name by reading EF_PNN. | |
1524 RETURNS: false if PS busy with reading files (primitive has been sent) | |
1525 TRUE if PS can go on with the updating | |
1526 */ | |
1527 GLOBAL BOOL cmhMM_OpUpdateName() | |
1528 { | |
1529 SHORT mncCur, mccCur; /* holds converted mnc and mcc of current PLMN */ | |
1530 T_opl_field *ptrOpl; | |
1531 UBYTE i, pnn_rec_num; | |
1532 | |
1533 TRACE_FUNCTION ("cmhMM_OpUpdateName()"); | |
1534 | |
1535 /* check if OPL is active and allocated */ | |
1536 /* if OPL not activate the first record of PNN holds the operator name of the HPLMN */ | |
1537 if(!psaSIM_ChkSIMSrvSup(SRV_OPL)) | |
1538 { | |
1539 cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc, | |
1540 mmShrdPrm.usedPLMN.mnc, | |
1541 &mccCur, &mncCur ); | |
1542 if( cmhSIM_plmn_is_hplmn (mccCur, mncCur)) | |
1543 { | |
1544 return(cmhMM_OpReadName(1)); | |
1545 } | |
1546 return(TRUE); /* no primitive has been sent to SIM */ | |
1547 } | |
1548 else /* OPL is active and allocated */ | |
1549 { | |
1550 ptrOpl = cmhSIM_GetOPL(); | |
1551 if (ptrOpl->opl_status) | |
1552 { | |
1553 /* search the OPL list for the new PNN record number */ | |
1554 i = 0; | |
1555 pnn_rec_num = 0; /* if PNN record number in OPL is 0, no PNN name is available. */ | |
1556 while (i < ptrOpl->num_rcd) | |
1557 { | |
1558 SHORT bcch_mcc, bcch_mnc; | |
1559 SHORT sim_mcc, sim_mnc; | |
1560 | |
1561 cmhMM_CnvrtPLMN2INT (mmShrdPrm.usedPLMN.mcc, mmShrdPrm.usedPLMN.mnc, | |
1562 &bcch_mcc, &bcch_mnc); | |
1563 cmhSIM_getMncMccFrmPLMNsel (ptrOpl->opl_rcd[i].plmn, | |
1564 &sim_mcc, &sim_mnc); | |
1565 if (cmhSIM_plmn_equal_sim (bcch_mcc, bcch_mnc, sim_mcc, sim_mnc) AND | |
1566 (ptrOpl->opl_rcd[i].lac1 <= mmShrdPrm.lac) AND | |
1567 (mmShrdPrm.lac <= ptrOpl->opl_rcd[i].lac2)) | |
1568 { | |
1569 pnn_rec_num = ptrOpl->opl_rcd[i].pnn_rec_num; | |
1570 break; | |
1571 } | |
1572 else | |
1573 i++; | |
1574 } | |
1575 if (pnn_rec_num != 0) | |
1576 { | |
1577 return(cmhMM_OpReadName(pnn_rec_num)); | |
1578 } | |
1579 } | |
1580 else | |
1581 TRACE_EVENT("OPL list unavailable");; /* no OPL list available */ | |
1582 } | |
1583 return(TRUE); /* no primitive has been sent to SIM */ | |
1584 } | |
1585 | |
1586 /* | |
1587 +-------------------------------------------------------------------------------------+ | |
1588 | PROJECT : GSM-PS MODULE : CMH | | |
1589 | ROUTINE : cmhMM_GetCmerSettings | | |
1590 +-------------------------------------------------------------------------------------+ | |
1591 */ | |
1592 GLOBAL void cmhMM_GetCmerSettings(T_ACI_CMD_SRC srcId, T_ACI_MM_CMER_VAL_TYPE *sCmerSettings) | |
1593 { | |
1594 sCmerSettings->sCmerModeParam = cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCMERSettings.sCmerModeParam; | |
1595 sCmerSettings->sCmerIndParam = cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCMERSettings.sCmerIndParam; | |
1596 sCmerSettings->sCmerBfrParam = cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCMERSettings.sCmerBfrParam; | |
1597 } | |
1598 | |
1599 /* | |
1600 +--------------------------------------------------------------------+ | |
1601 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
1602 | STATE : code ROUTINE : cmhMM_ChkIgnoreECC | | |
1603 +--------------------------------------------------------------------+ | |
1604 | |
1605 PURPOSE : This function is used to check if ECC should be set | |
1606 as a normal call. (Issue 17570) | |
1607 RETURN: TRUE - if further ECC checking should be ignored and call must be placed as normal | |
1608 FALSE - if ECC checking should be continued | |
1609 */ | |
1610 | |
1611 GLOBAL BOOL cmhMM_ChkIgnoreECC(CHAR *dialStr) | |
1612 { | |
1613 int i=0; | |
1614 SHORT mnc, mcc; | |
1615 | |
1616 /* remove any CLIR suppression/invocation prior checking for ECC */ | |
1617 if (!strncmp( dialStr, "*31#", 4) OR | |
1618 !strncmp( dialStr, "#31#", 4) ) | |
1619 { | |
1620 dialStr+=4; /* skip CLIR supression/invocation digits */ | |
1621 if ( *dialStr EQ '\0' ) | |
1622 { | |
1623 return( FALSE ); /* end already reached? */ | |
1624 } | |
1625 } | |
1626 | |
1627 if(mmShrdPrm.usedPLMN.v_plmn EQ VLD_PLMN) | |
1628 { | |
1629 cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc, mmShrdPrm.usedPLMN.mnc, &mcc, &mnc ); | |
1630 | |
1631 while (ECCIgnoreTable[i].mcc NEQ -1 AND ECCIgnoreTable[i].mnc NEQ -1 ) | |
1632 { | |
1633 if ( ECCIgnoreTable[i].mcc EQ mcc AND | |
1634 (ECCIgnoreTable[i].mnc EQ mnc OR ECCIgnoreTable[i].mnc EQ ALL_MNC) ) | |
1635 { | |
1636 if(!strcmp(ECCIgnoreTable[i].ecc, dialStr)) | |
1637 { | |
1638 TRACE_EVENT("cmhCC_ChkIgnoreECC(): no ECC but normal call detected"); | |
1639 return (TRUE); | |
1640 } | |
1641 } | |
1642 i++; | |
1643 } | |
1644 } | |
1645 return (FALSE); | |
1646 } | |
1647 | |
1648 | |
1649 /* | |
1650 +--------------------------------------------------------------------+ | |
1651 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
1652 | STATE : code ROUTINE : cmhMM_OperatorSelect | | |
1653 +--------------------------------------------------------------------+ | |
1654 | |
1655 PURPOSE : | |
1656 | |
1657 This function encapsulates the common CMH functionality of | |
1658 sAT_PlusCOPS(), sAT_PercentCOPS(), and sAT_PercentNRG(). | |
1659 | |
1660 The body of this function is based on the former sAT_PercentNRG(). | |
1661 | |
1662 */ | |
1663 | |
1664 GLOBAL T_ACI_RETURN cmhMM_OperatorSelect(T_ACI_CMD_SRC srcId, | |
1665 T_ACI_NRG_RGMD regMode, | |
1666 T_ACI_NRG_SVMD srvMode, | |
1667 T_ACI_NRG_FRMT oprFrmt, | |
1668 CHAR *opr) | |
1669 { | |
1670 T_MM_CMD_PRM * pMMCmdPrm; /* points to MM command parameters */ | |
1671 T_SIM_SET_PRM * pSIMSetPrm; /* points to SIM parameter set */ | |
1672 T_OPER_ENTRY plmnDesc; /* points to PLMN description */ | |
1673 T_ACI_RETURN retVal=AT_FAIL; /* holds return value */ | |
1674 BOOL found; /* result of cmhMM_FindXXX() */ | |
1675 UBYTE rm; /* holds converted registration mode */ | |
1676 | |
1677 TRACE_FUNCTION ("cmhMM_OperatorSelect()"); | |
1678 | |
1679 /* | |
1680 *------------------------------------------------------------------- | |
1681 * check command source | |
1682 *------------------------------------------------------------------- | |
1683 */ | |
1684 if(!cmh_IsVldCmdSrc (srcId)) | |
1685 { | |
1686 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
1687 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
1688 return( AT_FAIL ); | |
1689 } | |
1690 | |
1691 pMMCmdPrm = &cmhPrm[srcId].mmCmdPrm; | |
1692 pSIMSetPrm = &simShrdPrm.setPrm[srcId]; | |
1693 mmShrdPrm.regModeBeforeAbort = mmShrdPrm.regMode; | |
1694 | |
1695 /* | |
1696 *------------------------------------------------------------------- | |
1697 * process the regMode parameter | |
1698 *------------------------------------------------------------------- | |
1699 */ | |
1700 | |
1701 switch( regMode ) | |
1702 { | |
1703 case( NRG_RGMD_Auto ): rm = MODE_AUTO; break; | |
1704 case( NRG_RGMD_Manual ): | |
1705 case( NRG_RGMD_Both ): rm = MODE_MAN; | |
1706 if(!cmhSIM_isplmnmodebit_set()) | |
1707 { | |
1708 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
1709 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); | |
1710 return( AT_FAIL ); | |
1711 } | |
1712 break; | |
1713 case( NRG_RGMD_Dereg ): rm = MODE_AUTO; break; | |
1714 | |
1715 default: | |
1716 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
1717 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
1718 return( AT_FAIL ); | |
1719 } | |
1720 | |
1721 | |
1722 /* | |
1723 *------------------------------------------------------------------- | |
1724 * process the srvMode parameter | |
1725 *------------------------------------------------------------------- | |
1726 */ | |
1727 | |
1728 switch( srvMode ) | |
1729 { | |
1730 /* | |
1731 *--------------------------------------------------------------- | |
1732 * setting of registration mode only. This is only used by %NRG. It is obsolete and | |
1733 * should be removed at some point in the future. | |
1734 *--------------------------------------------------------------- | |
1735 */ | |
1736 case( NRG_SVMD_SetRegModeOnly ): | |
1737 | |
1738 /* | |
1739 * Unset the Current Command to match exactly what sAT_PercentNRG() | |
1740 * used to do. | |
1741 */ | |
1742 mmEntStat.curCmd = AT_CMD_NONE; | |
1743 mmShrdPrm.regMode = rm; | |
1744 mmShrdPrm.regModeAutoBack = FALSE; | |
1745 | |
1746 /* | |
1747 * Documentation (8415.052.00.002) says: | |
1748 * | |
1749 * "<srvMode>=3 can be used to change the behaviour of registration | |
1750 * in case of a loss of coverage. If connection to the operator is | |
1751 * lost and <regMode> was set to manual, ME tries to register the previous | |
1752 * operator automatically.". This is not exactly what is done here. | |
1753 * What is done is that the registration mode is set to automatic in MM. | |
1754 * The main difference is that for phase 2+ the HPLMN search period | |
1755 * will be evaluated by RR and the HPLMN may be reselected after 30 minutes, | |
1756 * even without any loss of coverage. | |
1757 */ | |
1758 | |
1759 | |
1760 #ifdef GPRS | |
1761 if( psaG_MM_CMD_SET_REGMD ( rm ) < 0 ) /* restore former registration mode*/ | |
1762 #else | |
1763 if( psaMM_SetRegMode ( rm ) < 0 ) /* set registration mode */ | |
1764 #endif | |
1765 { | |
1766 TRACE_EVENT( "FATAL RETURN psaMM_SetRegMode in %%NRG" ); | |
1767 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
1768 retVal = AT_FAIL; | |
1769 } | |
1770 else | |
1771 retVal = AT_CMPL; | |
1772 break; | |
1773 | |
1774 /* | |
1775 *--------------------------------------------------------------- | |
1776 * registration to full service | |
1777 *--------------------------------------------------------------- | |
1778 */ | |
1779 case( NRG_SVMD_Full ): | |
1780 | |
1781 /* For the %NRG case, only if SIM data is available we can start a registration attempt | |
1782 * But the COPS commands dont require that. | |
1783 */ | |
1784 | |
1785 if(( simShrdPrm.SIMStat EQ SS_OK AND | |
1786 simShrdPrm.PINStat EQ PS_RDY ) | |
1787 OR (mmEntStat.curCmd NEQ AT_CMD_NRG)) | |
1788 { | |
1789 switch( regMode ) | |
1790 { | |
1791 case( NRG_RGMD_Auto ): /* automatic registration */ | |
1792 | |
1793 mmShrdPrm.regModeAutoBack = FALSE; | |
1794 mmShrdPrm.regMode = MODE_AUTO; | |
1795 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
1796 | |
1797 #ifdef GPRS | |
1798 /* Taken from the former sAT_PlusCOPS() | |
1799 * COPS will be request an only GSM registration. | |
1800 * If the ME is an only GPRS mobile, then it is impossible to request only GSM. | |
1801 * This patch will be eliminate an error in this situation. | |
1802 * | |
1803 * brz, 02.07.01 | |
1804 */ | |
1805 if ( cmhGMM_class_eq_CG() EQ TRUE ) | |
1806 { | |
1807 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
1808 return AT_CMPL; | |
1809 } | |
1810 #endif | |
1811 | |
1812 | |
1813 #ifdef GPRS | |
1814 if( psaG_MM_CMD_REG ( ) < 0 ) /* register to network */ | |
1815 #else | |
1816 if( psaMM_Registrate () < 0 ) /* register to network */ | |
1817 #endif | |
1818 { | |
1819 TRACE_EVENT( "FATAL RETURN psaMM_Registrate in cmhMM_OperatorSelect()" ); | |
1820 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
1821 retVal = AT_FAIL; | |
1822 break; | |
1823 } | |
1824 | |
1825 cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Search); | |
1826 | |
1827 retVal = AT_EXCT; | |
1828 break; | |
1829 | |
1830 case( NRG_RGMD_Manual ): /* manual registration */ | |
1831 case( NRG_RGMD_Both ): /* manual followed by automatic reg. */ | |
1832 | |
1833 mmShrdPrm.regModeAutoBack = (regMode EQ NRG_RGMD_Both); | |
1834 | |
1835 /* | |
1836 * The following code is for %COPS=1 and %NRG=1. | |
1837 * It will get the IMSI and last registered PLMN from FFS. | |
1838 * If the IMSI has changed or no information is available in FFS, | |
1839 * it will tell MM to register to the operator stored in EF(LOCI). | |
1840 * If the IMSI hasn't changed, it will manually register to the Operator stored in FFS. | |
1841 * | |
1842 */ | |
1843 if( !opr OR !*opr) | |
1844 { | |
1845 UBYTE mcc[SIZE_MCC]; | |
1846 UBYTE mnc[SIZE_MNC]; | |
1847 UBYTE IMSI[MAX_IMSI-1]; | |
1848 char tempIMSI[MAX_IMSI] = {'\0'}; | |
1849 BOOL readFromLOCI =FALSE; | |
1850 | |
1851 | |
1852 mmShrdPrm.slctPLMN.v_plmn = VLD_PLMN; | |
1853 | |
1854 /* Get the IMSI and last registered PLMN from FFS. | |
1855 * Compare the IMSI stored in FFS to the current one. If the same, copy MCC and MNC | |
1856 * to pMMSetPrm -> slctPLMN. This will select this network manually. | |
1857 */ | |
1858 | |
1859 if (cmhMM_OperatorReadFromFFS(mcc,mnc,IMSI)) | |
1860 { | |
1861 TRACE_EVENT("Operator and IMSI succesfully read from FFS!"); | |
1862 if (!memcmp(IMSI,simShrdPrm.imsi.field,MAX_IMSI-1)) | |
1863 { | |
1864 memcpy(mmShrdPrm.slctPLMN.mcc, mcc,SIZE_MCC); | |
1865 memcpy(mmShrdPrm.slctPLMN.mnc, mnc,SIZE_MNC); | |
1866 } | |
1867 else | |
1868 { | |
1869 readFromLOCI = TRUE; | |
1870 } | |
1871 } | |
1872 else | |
1873 readFromLOCI = TRUE; | |
1874 /* If the SIM has changed or FFS cannot be read, read EF(LOCI) from the SIM. | |
1875 /* This wil now lead to a PLMN_RES with MNC,MCC=0xFFF: */ | |
1876 if (readFromLOCI) | |
1877 { | |
1878 psaSIM_cnvrtIMSI2ASCII(tempIMSI); | |
1879 psaSIM_decodeIMSI(IMSI,simShrdPrm.imsi.c_field,tempIMSI); | |
1880 | |
1881 cmhMM_CnvrtINT2PLMN( 0xFFF, | |
1882 0xFFF, | |
1883 mmShrdPrm.slctPLMN.mcc, | |
1884 mmShrdPrm.slctPLMN.mnc ); | |
1885 } | |
1886 } | |
1887 else | |
1888 { | |
1889 switch( oprFrmt ) | |
1890 { | |
1891 case( NRG_FRMT_Long ): | |
1892 found = cmhMM_FindName (&plmnDesc, opr, COPS_FRMT_Long); | |
1893 break; | |
1894 | |
1895 case( NRG_FRMT_Short ): | |
1896 found = cmhMM_FindName (&plmnDesc, opr, COPS_FRMT_Short); | |
1897 break; | |
1898 | |
1899 case( NRG_FRMT_Numeric ): | |
1900 found = cmhMM_FindNumeric(&plmnDesc, opr); | |
1901 break; | |
1902 | |
1903 default: | |
1904 found = FALSE; | |
1905 break; | |
1906 } | |
1907 | |
1908 if (!found) | |
1909 { | |
1910 mmEntStat.curCmd = AT_CMD_NONE; /* Unset the Current Command */ | |
1911 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
1912 return( AT_FAIL ); | |
1913 } | |
1914 | |
1915 mmShrdPrm.slctPLMN.v_plmn = VLD_PLMN; | |
1916 cmhMM_CnvrtINT2PLMN( plmnDesc.mcc, /*lint -e644 plmnDesc may not have been initialized*/ | |
1917 plmnDesc.mnc, | |
1918 mmShrdPrm.slctPLMN.mcc, | |
1919 mmShrdPrm.slctPLMN.mnc ); | |
1920 } | |
1921 mmShrdPrm.regMode = MODE_MAN; | |
1922 | |
1923 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
1924 | |
1925 #ifdef GPRS | |
1926 if( psaG_MM_CMD_NET_SEL ( ) < 0 ) /* register to network */ | |
1927 #else | |
1928 if( psaMM_NetSel () < 0 ) /* register to network */ | |
1929 #endif | |
1930 { | |
1931 TRACE_EVENT( "FATAL RETURN psaMM_NetSel in %%NRG" ); | |
1932 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
1933 retVal = AT_FAIL; | |
1934 break; | |
1935 } | |
1936 | |
1937 cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Search); | |
1938 | |
1939 retVal = AT_EXCT; | |
1940 break; | |
1941 } | |
1942 } | |
1943 /* | |
1944 * No SIM data is available, activate SIM | |
1945 * The following block of code was only available in the former sAT_PercentNRG() | |
1946 * Therefore, it will only be executed by the %NRG command. | |
1947 */ | |
1948 else | |
1949 { | |
1950 /* check SIM entity status */ | |
1951 if( simEntStat.curCmd NEQ AT_CMD_NONE ) | |
1952 | |
1953 return( AT_BUSY ); | |
1954 | |
1955 /* prepare PLMN desc for later use */ | |
1956 if( regMode EQ NRG_RGMD_Manual ) | |
1957 { | |
1958 if( ! opr ) | |
1959 { | |
1960 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
1961 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
1962 return( AT_FAIL ); | |
1963 } | |
1964 | |
1965 switch( oprFrmt ) | |
1966 { | |
1967 case( NRG_FRMT_Long ): | |
1968 found = cmhMM_FindName (&plmnDesc, opr, COPS_FRMT_Long); | |
1969 break; | |
1970 | |
1971 case( NRG_FRMT_Short ): | |
1972 found = cmhMM_FindName (&plmnDesc, opr, COPS_FRMT_Short); | |
1973 break; | |
1974 | |
1975 case( NRG_FRMT_Numeric): | |
1976 found = cmhMM_FindNumeric (&plmnDesc, opr); | |
1977 break; | |
1978 | |
1979 default: | |
1980 found = FALSE; | |
1981 break; | |
1982 } | |
1983 | |
1984 if (!found) | |
1985 { | |
1986 mmEntStat.curCmd = AT_CMD_NONE; /* Unset the Current Command */ | |
1987 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
1988 return( AT_FAIL ); | |
1989 } | |
1990 | |
1991 mmShrdPrm.slctPLMN.v_plmn = VLD_PLMN; | |
1992 cmhMM_CnvrtINT2PLMN( plmnDesc.mcc, | |
1993 plmnDesc.mnc, | |
1994 mmShrdPrm.slctPLMN.mcc, | |
1995 mmShrdPrm.slctPLMN.mnc ); | |
1996 } | |
1997 | |
1998 pSIMSetPrm -> actProc = SIM_INITIALISATION; | |
1999 | |
2000 simEntStat.curCmd = AT_CMD_NRG; | |
2001 simEntStat.entOwn = simShrdPrm.owner = srcId; | |
2002 | |
2003 if( psaSIM_ActivateSIM() < 0 ) /* activate SIM card */ | |
2004 { | |
2005 TRACE_EVENT( "FATAL RETURN psaSIM in %%NRG" ); | |
2006 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
2007 retVal = AT_FAIL; | |
2008 break; | |
2009 } | |
2010 | |
2011 retVal = AT_EXCT; | |
2012 } | |
2013 break; | |
2014 | |
2015 /* | |
2016 *--------------------------------------------------------------- | |
2017 * registration to limited service. | |
2018 * The COPS commands will use this for deregistration | |
2019 *--------------------------------------------------------------- | |
2020 */ | |
2021 | |
2022 case( NRG_SVMD_Limited ): | |
2023 | |
2024 mmShrdPrm.regModeAutoBack = FALSE; | |
2025 | |
2026 switch( mmShrdPrm.regStat ) | |
2027 { | |
2028 case( RS_LMTD_SRV ): | |
2029 | |
2030 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
2031 retVal = AT_CMPL; | |
2032 break; | |
2033 | |
2034 case( RS_NO_SRV ): | |
2035 case( NO_VLD_RS ): | |
2036 /* | |
2037 * if SIM data is available, do not destory it in ACI. | |
2038 * It may be needed later | |
2039 */ | |
2040 if(( simShrdPrm.SIMStat EQ SS_OK AND | |
2041 simShrdPrm.PINStat EQ PS_RDY ) OR (mmEntStat.curCmd NEQ AT_CMD_NRG)) | |
2042 { | |
2043 | |
2044 /* flag a pending request. It only applies to the %NRG case */ | |
2045 if (mmEntStat.curCmd EQ AT_CMD_NRG) | |
2046 regReqPnd = TRUE; | |
2047 | |
2048 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
2049 | |
2050 #ifdef GPRS | |
2051 mmShrdPrm.nrgCs = GMMREG_DT_COMB; | |
2052 if( psaG_MM_CMD_DEREG ( mmShrdPrm.nrgCs ) < 0 ) /* deregister from network */ | |
2053 #else | |
2054 mmShrdPrm.nrgCs = CS_SIM_REM; | |
2055 if( psaMM_DeRegistrate () < 0 ) /* deregister from network */ | |
2056 #endif /* GPRS */ | |
2057 { | |
2058 TRACE_EVENT( "FATAL RETURN psaMM_DeRegistrate in %%NRG" ); | |
2059 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
2060 retVal = AT_FAIL; | |
2061 } | |
2062 else | |
2063 { | |
2064 /* Next line commented out HM 28.08.00 */ | |
2065 /* simShrdPrm.SIMStat = NO_VLD_SS; */ /* no SIM data available */ | |
2066 retVal = AT_EXCT; | |
2067 } | |
2068 } | |
2069 /* | |
2070 * No SIM data is available, try a registration to limited service. | |
2071 * The following block of code was only available in the former sAT_PercentNRG() | |
2072 * Therefore, it will only be executed by the %NRG command. | |
2073 */ | |
2074 else | |
2075 { | |
2076 mmShrdPrm.regMode = MODE_AUTO; | |
2077 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
2078 #ifdef GPRS | |
2079 if( psaG_MM_CMD_REG ( ) < 0 ) /* register to network */ | |
2080 #else | |
2081 if( psaMM_Registrate () < 0 ) /* register to network */ | |
2082 #endif | |
2083 { | |
2084 TRACE_EVENT( "FATAL RETURN psaMM_Registrate in %%NRG" ); | |
2085 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
2086 retVal = AT_FAIL; | |
2087 } | |
2088 else | |
2089 { | |
2090 retVal = AT_EXCT; | |
2091 } | |
2092 } | |
2093 break; | |
2094 | |
2095 case( RS_FULL_SRV ): | |
2096 | |
2097 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
2098 | |
2099 #ifdef GPRS | |
2100 mmShrdPrm.nrgCs = GMMREG_DT_COMB; | |
2101 if( psaG_MM_CMD_DEREG ( mmShrdPrm.nrgCs ) < 0 ) /* deregister from network */ | |
2102 #else | |
2103 mmShrdPrm.nrgCs = CS_SIM_REM; | |
2104 if( psaMM_DeRegistrate () < 0 ) /* deregister from network */ | |
2105 #endif | |
2106 { | |
2107 TRACE_EVENT( "FATAL RETURN psaMM_Deregistrate in %%NRG" ); | |
2108 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
2109 retVal = AT_FAIL; | |
2110 break; | |
2111 } | |
2112 | |
2113 /* Next line commented out HM 28.08.00 */ | |
2114 /* simShrdPrm.SIMStat = NO_VLD_SS; */ /* no SIM data available */ | |
2115 retVal = AT_EXCT; | |
2116 break; | |
2117 } | |
2118 break; | |
2119 | |
2120 /* | |
2121 *--------------------------------------------------------------- | |
2122 * registration to no service. Only used by %NRG | |
2123 *--------------------------------------------------------------- | |
2124 */ | |
2125 | |
2126 case( NRG_SVMD_NoSrv ): | |
2127 | |
2128 mmShrdPrm.regModeAutoBack = FALSE; | |
2129 | |
2130 mmEntStat.entOwn = mmShrdPrm.owner = srcId; | |
2131 | |
2132 #ifdef GPRS | |
2133 mmShrdPrm.nrgCs = GMMREG_DT_COMB; | |
2134 if( psaG_MM_CMD_DEREG ( mmShrdPrm.nrgCs ) < 0 ) /* deregister from network */ | |
2135 #else | |
2136 mmShrdPrm.nrgCs = CS_POW_OFF; | |
2137 if( psaMM_DeRegistrate () < 0 ) /* deregister from network */ | |
2138 #endif | |
2139 { | |
2140 TRACE_EVENT( "FATAL RETURN psaMM_Deregistrate in %%NRG" ); | |
2141 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); | |
2142 retVal = AT_FAIL; | |
2143 break; | |
2144 } | |
2145 | |
2146 retVal = AT_EXCT; | |
2147 break; | |
2148 | |
2149 default: | |
2150 mmEntStat.curCmd = AT_CMD_NONE; /*Unset the Current Command */ | |
2151 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); | |
2152 return( AT_FAIL ); | |
2153 } | |
2154 | |
2155 /* | |
2156 *------------------------------------------------------------------- | |
2157 * update NRG parameters | |
2158 *------------------------------------------------------------------- | |
2159 */ | |
2160 if (mmEntStat.curCmd EQ AT_CMD_NRG) | |
2161 { | |
2162 pMMCmdPrm -> NRGsrvMode = srvMode; | |
2163 pMMCmdPrm -> NRGregMode = regMode; | |
2164 pMMCmdPrm -> NRGoprFrmt = oprFrmt; | |
2165 } | |
2166 | |
2167 /* | |
2168 *------------------------------------------------------------------- | |
2169 * log command execution | |
2170 *------------------------------------------------------------------- | |
2171 */ | |
2172 #if defined SMI OR defined MFW OR defined FF_MMI_RIV | |
2173 { | |
2174 T_ACI_CLOG cmdLog; /* holds logging info */ | |
2175 | |
2176 cmdLog.atCmd = mmEntStat.curCmd; | |
2177 cmdLog.cmdType = CLOG_TYPE_Set; | |
2178 cmdLog.retCode = retVal; | |
2179 cmdLog.cId = ACI_NumParmNotPresent; | |
2180 cmdLog.sId = ACI_NumParmNotPresent; | |
2181 | |
2182 if (mmEntStat.curCmd EQ AT_CMD_NRG) | |
2183 { | |
2184 cmdLog.cmdPrm.sNRG.srcId = srcId; | |
2185 cmdLog.cmdPrm.sNRG.regMode = regMode; | |
2186 cmdLog.cmdPrm.sNRG.srvMode = srvMode; | |
2187 cmdLog.cmdPrm.sNRG.oprFrmt = oprFrmt; | |
2188 cmdLog.cmdPrm.sNRG.opr = opr; | |
2189 } | |
2190 else /*+COPS and %COPS. At the moment, the same message sent by both */ | |
2191 { | |
2192 cmdLog.cmdPrm.sCOPS.srcId = srcId; | |
2193 cmdLog.cmdPrm.sCOPS.mode = mmShrdPrm.COPSmode; | |
2194 cmdLog.cmdPrm.sCOPS.format = pMMCmdPrm -> COPSfrmt; | |
2195 cmdLog.cmdPrm.sCOPS.oper = opr; | |
2196 } | |
2197 | |
2198 rAT_PercentCLOG( &cmdLog ); | |
2199 } | |
2200 #endif | |
2201 | |
2202 return( retVal ); | |
2203 | |
2204 | |
2205 } | |
2206 | |
2207 /* | |
2208 +--------------------------------------------------------------------+ | |
2209 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2210 | STATE : code ROUTINE : cmhMM_OperatorQuery | | |
2211 +--------------------------------------------------------------------+ | |
2212 | |
2213 PURPOSE : | |
2214 | |
2215 This function encapsulates the common CMH functionality of | |
2216 qAT_PlusCOPS(), qAT_PercentCOPS(), and qAT_PercentNRG(). It basically gets the | |
2217 Network Operator name based on the format parameter. | |
2218 | |
2219 */ | |
2220 | |
2221 | |
2222 GLOBAL void cmhMM_OperatorQuery( T_ACI_CMD_SRC srcId, | |
2223 T_ACI_COPS_FRMT format, | |
2224 CHAR *oper) | |
2225 { | |
2226 SHORT mcc, mnc; /* holds coverted values for mcc and mnc */ | |
2227 T_OPER_ENTRY plmnDesc; /* entry of operator list */ | |
2228 BOOL found; | |
2229 | |
2230 TRACE_FUNCTION ("cmhMM_OperatorQuery()"); | |
2231 | |
2232 if( mmShrdPrm.regStat EQ RS_FULL_SRV AND | |
2233 mmShrdPrm.usedPLMN.v_plmn EQ VLD_PLMN) | |
2234 { | |
2235 cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc, mmShrdPrm.usedPLMN.mnc, | |
2236 &mcc, &mnc ); | |
2237 | |
2238 found = cmhMM_FindPLMN (&plmnDesc, mcc, mnc, mmShrdPrm.lac, FALSE); | |
2239 | |
2240 if (!found) | |
2241 { | |
2242 TRACE_EVENT("!cmhMM_FindPLMN()"); | |
2243 if( format EQ COPS_FRMT_Numeric ) | |
2244 { | |
2245 if ((mnc & 0x00F) EQ 0xF) | |
2246 /*lint -e{702} */ | |
2247 sprintf (oper, "%03X%02X", mcc, mnc >> 4); | |
2248 else | |
2249 sprintf (oper, "%03X%03X", mcc, mnc); | |
2250 } | |
2251 } | |
2252 else | |
2253 { | |
2254 char longName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
2255 char shrtName[(MAX_ALPHA_OPER_LEN*8+6)/7]; | |
2256 | |
2257 longName[0] = shrtName[0] = '\0'; | |
2258 | |
2259 switch( format ) | |
2260 { | |
2261 case( COPS_FRMT_Long ): | |
2262 TRACE_EVENT("COPS_FRMT_Long"); | |
2263 | |
2264 if (plmnDesc.pnn) | |
2265 { | |
2266 if (plmnDesc.long_len) | |
2267 { | |
2268 switch (plmnDesc.long_ext_dcs>>4 & 0x07) | |
2269 { | |
2270 case 0x00: | |
2271 utl_cvtPnn7To8((UBYTE *)plmnDesc.longName, | |
2272 plmnDesc.long_len, | |
2273 plmnDesc.long_ext_dcs, | |
2274 (UBYTE *)longName); | |
2275 break; | |
2276 case 0x01: | |
2277 TRACE_ERROR ("ERROR: Unhandled UCS2 DCS"); | |
2278 break; | |
2279 default: | |
2280 TRACE_ERROR ("ERROR: Unknown DCS"); | |
2281 break; | |
2282 } | |
2283 } | |
2284 strncpy( oper, longName, MAX_ALPHA_OPER_LEN-1 ); | |
2285 } | |
2286 else | |
2287 { | |
2288 strncpy( oper, plmnDesc.longName, MAX_ALPHA_OPER_LEN-1 ); | |
2289 } | |
2290 oper[MAX_ALPHA_OPER_LEN-1] = '\0'; | |
2291 break; | |
2292 | |
2293 case( COPS_FRMT_Short ): | |
2294 if (plmnDesc.pnn) | |
2295 { | |
2296 if (plmnDesc.shrt_len) | |
2297 { | |
2298 switch (plmnDesc.shrt_ext_dcs>>4 & 0x07) | |
2299 { | |
2300 case 0x00: | |
2301 utl_cvtPnn7To8((UBYTE *)plmnDesc.shrtName, | |
2302 plmnDesc.shrt_len, | |
2303 plmnDesc.shrt_ext_dcs, | |
2304 (UBYTE *)shrtName); | |
2305 break; | |
2306 case 0x01: | |
2307 TRACE_ERROR ("ERROR: Unhandled UCS2"); | |
2308 break; | |
2309 default: | |
2310 TRACE_ERROR ("ERROR: Unknown DCS"); | |
2311 break; | |
2312 } | |
2313 } | |
2314 strncpy( oper, shrtName, MAX_ALPHA_OPER_LEN-1 ); | |
2315 } | |
2316 else | |
2317 { | |
2318 strncpy( oper, plmnDesc.shrtName, MAX_ALPHA_OPER_LEN-1 ); | |
2319 } | |
2320 oper[MAX_ALPHA_OPER_LEN-1] = '\0'; | |
2321 break; | |
2322 | |
2323 case( COPS_FRMT_Numeric ): | |
2324 if ((mnc & 0x00F) EQ 0xF) | |
2325 /*lint -e{702} */ | |
2326 sprintf (oper, "%03X%02X", mcc, mnc >> 4); | |
2327 else | |
2328 sprintf (oper, "%03X%03X", mcc, mnc); | |
2329 break; | |
2330 } | |
2331 } | |
2332 } | |
2333 } | |
2334 | |
2335 | |
2336 /* | |
2337 +--------------------------------------------------------------------+ | |
2338 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2339 | STATE : code ROUTINE : cmhMM_OperatorStoreInFFS | | |
2340 +--------------------------------------------------------------------+ | |
2341 | |
2342 PURPOSE : | |
2343 | |
2344 This function stores the Operator given by MCC and MNC, and the IMSI number in the FFS file | |
2345 given by MM_FFS_OPER_FILE. If the directory in which the file is stored does not exist, it will create it. | |
2346 | |
2347 | |
2348 */ | |
2349 | |
2350 | |
2351 | |
2352 GLOBAL BOOL cmhMM_OperatorStoreInFFS(UBYTE* mcc, UBYTE* mnc, UBYTE* IMSI) | |
2353 { | |
2354 | |
2355 #ifndef _SIMULATION_ | |
2356 T_FFS_RET result; | |
2357 #endif | |
2358 T_FFSPLMNIMSI currentPlmnIMSI; | |
2359 | |
2360 TRACE_FUNCTION("cmhMM_OperatorStoreInFFS"); | |
2361 | |
2362 | |
2363 memcpy( currentPlmnIMSI.IMSI, IMSI, MAX_IMSI-1); | |
2364 memcpy(currentPlmnIMSI.mcc,mcc,SIZE_MCC); | |
2365 memcpy(currentPlmnIMSI.mnc,mnc,SIZE_MNC); | |
2366 | |
2367 #ifndef _SIMULATION_ | |
2368 | |
2369 switch(FFS_mkdir(MM_FFS_OPER_DIR)) | |
2370 {/* Check / Create ffs directory */ | |
2371 case EFFS_OK: | |
2372 TRACE_EVENT("cmhMM_OperatorStoreInFFS: Dir Created "); | |
2373 break; | |
2374 case EFFS_EXISTS: | |
2375 TRACE_EVENT("cmhMM_OperatorStoreInFFS:Dir Exists "); | |
2376 break; | |
2377 default: | |
2378 TRACE_EVENT("cmhMM_OperatorStoreInFFS:Dir Not Created"); | |
2379 return ( FALSE ); | |
2380 } | |
2381 | |
2382 result = FFS_fwrite(MM_FFS_OPER_FILE, ¤tPlmnIMSI, sizeof(T_FFSPLMNIMSI)); | |
2383 TRACE_EVENT_P1("cmhMM_OperatorStoreInFFS:FFS dir ok,FFS_fwrite res %x", result); | |
2384 | |
2385 if (result < EFFS_OK) | |
2386 return FALSE; | |
2387 | |
2388 #else /*Simulation is defined*/ | |
2389 | |
2390 memcpy(&RAMPlmnIMSI,¤tPlmnIMSI,sizeof(T_FFSPLMNIMSI)); | |
2391 | |
2392 #endif | |
2393 | |
2394 return TRUE; | |
2395 | |
2396 } | |
2397 | |
2398 /* | |
2399 +--------------------------------------------------------------------+ | |
2400 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2401 | STATE : code ROUTINE : cmhMM_OperatorReadFromFFS | | |
2402 +--------------------------------------------------------------------+ | |
2403 | |
2404 PURPOSE : | |
2405 | |
2406 This function reads the Operator given by MCC and MNC, and the IMSI number from the FFS file | |
2407 given by MM_FFS_OPER_FILE. | |
2408 | |
2409 | |
2410 */ | |
2411 | |
2412 | |
2413 GLOBAL BOOL cmhMM_OperatorReadFromFFS(UBYTE* mcc, UBYTE* mnc, UBYTE* IMSI) | |
2414 { | |
2415 #ifndef _SIMULATION_ | |
2416 T_FFS_RET result; | |
2417 #endif | |
2418 | |
2419 T_FFSPLMNIMSI currentPlmnIMSI; | |
2420 | |
2421 TRACE_FUNCTION("cmhMM_OperatorReadFromFFS()"); | |
2422 | |
2423 #ifndef _SIMULATION_ | |
2424 | |
2425 result = FFS_fread(MM_FFS_OPER_FILE, ¤tPlmnIMSI, sizeof(T_FFSPLMNIMSI)); | |
2426 | |
2427 TRACE_EVENT_P1("FFS result = %d",result); | |
2428 | |
2429 if (result < EFFS_OK) | |
2430 return FALSE; | |
2431 | |
2432 #else | |
2433 | |
2434 memcpy(¤tPlmnIMSI,&RAMPlmnIMSI,sizeof(T_FFSPLMNIMSI)); | |
2435 | |
2436 | |
2437 #endif | |
2438 | |
2439 memcpy( IMSI,currentPlmnIMSI.IMSI, MAX_IMSI-1); | |
2440 memcpy(mcc,currentPlmnIMSI.mcc,SIZE_MCC); | |
2441 memcpy(mnc,currentPlmnIMSI.mnc,SIZE_MNC); | |
2442 | |
2443 | |
2444 | |
2445 return TRUE; | |
2446 | |
2447 | |
2448 | |
2449 } | |
2450 | |
2451 /* | |
2452 +--------------------------------------------------------------------+ | |
2453 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2454 | STATE : code ROUTINE : cmhMM_GetActingHPLMN | | |
2455 +--------------------------------------------------------------------+ | |
2456 | |
2457 PURPOSE : fills the Acting HPLMN if present. | |
2458 */ | |
2459 GLOBAL BOOL cmhMM_GetActingHPLMN(SHORT * mccBuf, SHORT * mncBuf) | |
2460 { | |
2461 TRACE_FUNCTION("cmhMM_GetActingHPLMN"); | |
2462 if(mmShrdPrm.ActingHPLMN.v_plmn EQ VLD_PLMN) | |
2463 { | |
2464 cmhMM_CnvrtPLMN2INT( mmShrdPrm.ActingHPLMN.mcc, mmShrdPrm.ActingHPLMN.mnc, mccBuf, mncBuf ); | |
2465 TRACE_EVENT("Acting HPLMN Present"); | |
2466 return(TRUE); | |
2467 } | |
2468 TRACE_EVENT("Acting HPLMN not Present"); | |
2469 return (FALSE); | |
2470 } | |
2471 | |
2472 /* | |
2473 +-------------------------------------------------------------------+ | |
2474 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2475 | STATE : code ROUTINE : cmhMM_ONSReadName | | |
2476 +-------------------------------------------------------------------+ | |
2477 | |
2478 PURPOSE : Sends a SIM read request | |
2479 | |
2480 RESULT: has an error occured ? | |
2481 Returns: FALSE if primitive has been sent and TRUE if not | |
2482 */ | |
2483 GLOBAL BOOL cmhMM_ONSReadName() | |
2484 { | |
2485 TRACE_FUNCTION ("cmhMM_ONSReadName()"); | |
2486 | |
2487 if (cmhSIM_ReadTranspEF (CMD_SRC_NONE, | |
2488 AT_CMD_NONE, | |
2489 SIM_CPHS_ONSTR, | |
2490 0, | |
2491 NOT_PRESENT_8BIT, | |
2492 NULL, | |
2493 cmhMM_ONSReadNameCb) EQ AT_FAIL) | |
2494 { | |
2495 TRACE_EVENT("FATAL ERROR"); | |
2496 return(TRUE); | |
2497 } | |
2498 ONSReadStatus = ONS_READING; | |
2499 return(FALSE); | |
2500 } | |
2501 | |
2502 /* | |
2503 +-------------------------------------------------------------------+ | |
2504 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2505 | STATE : code ROUTINE : cmhMM_ONSReadNameCb | | |
2506 +-------------------------------------------------------------------+ | |
2507 | |
2508 PURPOSE : Call back for SIM retrieval of EF_ONS. | |
2509 */ | |
2510 | |
2511 GLOBAL void cmhMM_ONSReadNameCb(SHORT table_id) | |
2512 { | |
2513 int i =0; | |
2514 | |
2515 TRACE_FUNCTION ("cmhMM_ONSReadNameCb()"); | |
2516 | |
2517 if(!(simShrdPrm.atb[table_id].exchData NEQ NULL AND | |
2518 simShrdPrm.atb[table_id].exchData[0] NEQ 0xFF AND | |
2519 simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)) | |
2520 { | |
2521 ONSReadStatus = ONS_READ_FAIL; | |
2522 } | |
2523 else | |
2524 { | |
2525 ONSReadStatus = ONS_READ_OVER; | |
2526 memset (&ONSDesc, 0, sizeof (T_OPER_ENTRY)); | |
2527 ONSDesc.long_len = 0; | |
2528 while (simShrdPrm.atb[table_id].exchData[i] NEQ 0xFF AND | |
2529 ONSDesc.long_len < MAX_LONG_OPER_LEN - 1) | |
2530 { | |
2531 ONSDesc.long_len++; | |
2532 i++; | |
2533 } | |
2534 if (ONSDesc.long_len <= MAX_SHRT_OPER_LEN - 1) | |
2535 { | |
2536 ONSDesc.shrt_len = ONSDesc.long_len; | |
2537 } | |
2538 else | |
2539 { | |
2540 ONSDesc.shrt_len = MAX_SHRT_OPER_LEN - 1; | |
2541 } | |
2542 | |
2543 /* Issue OMAPS00058768 : EFons may have fewer bytes than MAX_LONG_OPER_LEN and if all of them are used bytes then | |
2544 we will not come across 0xFF (unused bytes), which causes ONSDesc.long_len = MAX_LONG_OPER_LEN - 1. | |
2545 So this leads to the function memcpy() to copy garbage characters in front of operator name. | |
2546 */ | |
2547 ONSDesc.long_len = MINIMUM(simShrdPrm.atb[table_id].dataLen, ONSDesc.long_len); | |
2548 ONSDesc.shrt_len = MINIMUM(simShrdPrm.atb[table_id].dataLen, ONSDesc.shrt_len); | |
2549 | |
2550 memcpy (ONSDesc.longName, simShrdPrm.atb[table_id].exchData, ONSDesc.long_len); | |
2551 memcpy (ONSDesc.shrtName, simShrdPrm.atb[table_id].exchData, ONSDesc.shrt_len); | |
2552 | |
2553 ONSDesc.long_ext_dcs = ONS_EXT_DCS; | |
2554 ONSDesc.shrt_ext_dcs = ONS_EXT_DCS; | |
2555 | |
2556 /* Issue OMAPS00058768 : For file update of ONS we no need to call cmhMM_Registered() */ | |
2557 #ifdef SIM_TOOLKIT | |
2558 if (simShrdPrm.fuRef < 0) | |
2559 #endif | |
2560 { | |
2561 cmhMM_Registered (); | |
2562 } | |
2563 #ifdef SIM_TOOLKIT | |
2564 if (simShrdPrm.fuRef >= 0) | |
2565 { | |
2566 psaSAT_FUConfirm (simShrdPrm.fuRef, | |
2567 (USHORT)((simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)? | |
2568 SIM_FU_SUCCESS: SIM_FU_ERROR)); | |
2569 } | |
2570 #endif | |
2571 } | |
2572 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
2573 } | |
2574 | |
2575 /* | |
2576 +-------------------------------------------------------------- + | |
2577 | PROJECT : GSM-PS (6147) MODULE : CMH_MMF | | |
2578 | STATE : code ROUTINE : cmhMM_Reset_ONSDesc | | |
2579 +---------------------------------------------------------------+ | |
2580 | |
2581 PURPOSE :Issue OMAPS00058768: Reset ONSDesc. | |
2582 */ | |
2583 | |
2584 GLOBAL void cmhMM_Reset_ONSDesc() | |
2585 { | |
2586 memset(&ONSDesc,0x00,sizeof(ONSDesc)); | |
2587 ONSReadStatus = ONS_READ_NOT_DONE; | |
2588 } | |
2589 /*==== EOF ========================================================*/ |