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, &currentPlmnIMSI, 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,&currentPlmnIMSI,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, &currentPlmnIMSI, 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(&currentPlmnIMSI,&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 ========================================================*/