comparison gsm-fw/g23m-aci/aci/cmh_mmf.c @ 775:eedbf248bac0

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