comparison g23m-aci/aci/phb.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : MMI-Framework (8417)
4 | Modul : PHB
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This modul contains the functions to establish the phone books.
18 +-----------------------------------------------------------------------------
19 */
20
21 #include "config.h"
22 #include "fixedconf.h"
23 #include "condat-features.h"
24 #include "aci_conf.h"
25
26 #ifndef TI_PS_FFS_PHB
27
28 #include "aci_all.h"
29
30 #include "aci_cmh.h"
31 #include "ati_cmd.h"
32 #include "aci_cmd.h"
33 #include "aci.h"
34 #include "p_sim.h"
35 #include "pcm.h"
36 #include "gdi.h"
37
38 #include "phb.h"
39 #include "psa.h"
40 #include "psa_sim.h"
41 #include "psa_cc.h"
42 #ifdef SIM_TOOLKIT
43 #include "psa_sat.h"
44 #endif
45
46 #ifdef FAX_AND_DATA
47 #include "aci_fd.h"
48 #endif /* of #ifdef FAX_AND_DATA */
49
50 #include "cmh.h"
51 #include "cmh_phb.h"
52
53 #include "dti_conn_mng.h"
54
55
56 #include "cmh_sim.h"
57 #include "psa_mm.h"
58 #include "psa_ss.h"
59
60 #ifndef _SIMULATION_
61 #include "../../services/ffs/ffs.h"
62 #endif
63 /********* current define *******************************************/
64 static T_PHB_EXT_CMP_FCT ext_compare_fct = NULL; /* external compare function */
65 static T_PHB_CTB phb_ctb[MAX_PHONEBOOK];
66 static T_PHB_AFB_ELEMENT phb_element[MAX_AFB_RECORDS];
67 static T_PHB_RDM_ELEMENT phb_l_element[MAX_RDM_RECORDS];
68 static UBYTE adn_bitmap[MAX_ADN_BITMAP];
69 static UBYTE fdn_bitmap[MAX_FDN_BITMAP];
70 static UBYTE bdn_bitmap[MAX_BDN_BITMAP];
71 static UBYTE sdn_bitmap[MAX_SDN_BITMAP];
72 static UBYTE ecc_bitmap[MAX_ECC_BITMAP];
73 static UBYTE upn_bitmap[MAX_UPN_BITMAP];
74 #ifdef PHONEBOOK_EXTENSION
75 static T_PHB_EXT_RECORDS phb_ext_records[MAX_PHB_EXT];
76 static UBYTE ext1_bitmap[MAX_EXT1_BITMAP];
77 static UBYTE ext2_bitmap[MAX_EXT2_BITMAP];
78 static UBYTE ext3_bitmap[MAX_EXT3_BITMAP];
79 static UBYTE ext4_bitmap[MAX_EXT4_BITMAP];
80 #endif
81 static UBYTE sim_service_table[MAX_SRV_TBL]; /* SIM service table */
82 static UBYTE data [256];
83
84 static SHORT ext_index;
85 static UBYTE max_ext_chain_reads=0;
86 static UBYTE phb_stat;
87 static UBYTE fdn_mode;
88 static T_ACI_CLASS fdn_classtype;
89 static T_ACI_CLASS fdn_input_classtype;
90 static UBYTE read_flag = 0;
91 static SHORT db_index = UNUSED_INDEX; /* memory index for delete whole phonebook */
92 static BOOL sstUpdateId = FALSE; /* SIM service table update indication (SAT) */
93
94 static UBYTE max_sim_LDN_records = 0; /* to ensure that every physical record is written */
95
96 static int cmpString (UBYTE *s1, UBYTE *s2, UBYTE len);
97 static int pb_cmp_phb_entry ( UBYTE *pb_tag, UBYTE pb_len,
98 T_ACI_PB_TEXT *search_tag );
99 static int pb_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag);
100 static void pb_cvt_alpha_for_cmp ( UBYTE *src,
101 UBYTE *dst,
102 UBYTE len );
103 static BOOL imsiFlag;
104
105 static BOOL pause_pb_reading_while_EXT_reading = FALSE; /* pauses the loop while reading EXT-Records */
106 static SHORT paused_table_id = 0; /* the paused record */
107 EXTERN T_PCEER causeMod;
108 EXTERN SHORT causeCeer;
109
110 #ifdef SIM_TOOLKIT
111 BOOL pb_update (int ref, T_SIM_FILE_UPDATE_IND *fu);
112 BOOL pb_update_ecc_fu (int ref, T_SIM_FILE_UPDATE_IND *fu);
113 #endif
114 void pb_copy_ecc_entry (UBYTE *ecc, UBYTE num);
115 void pb_read_sim_ecc ( void );
116 void pb_read_eeprom_ecc (void);
117 T_PHB_RETURN pb_read_eeprom_req(void);
118 BOOL pb_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length);
119 void pb_read_sim_dat_cb(SHORT table_id);
120 void pb_read_sim_req(void);
121 void pb_sat_update_reset (USHORT data_id);
122 void pb_init_afb(void);
123 void pb_init_ctb (T_PHB_TYPE book);
124 void pb_init_element (UBYTE book);
125 void pb_init_l_element (UBYTE book); /*CQ16301: Added support for LND Refresh*/
126
127 BOOL pb_init_sync_sim(UBYTE type);
128 BOOL pb_prepare_sync_sim(UBYTE type, UBYTE rcd_num);
129 BOOL pb_sync_sim(UBYTE type, UBYTE rcd_num);
130 void pb_sync_sim_cb(SHORT table_id);
131 void pb_finish_sync_sim(void);
132
133 void copy_phb_element ( T_PHB_RECORD *entry, T_PHB_AFB_ELEMENT phb_element );
134 void copy_phb_l_element ( T_PHB_RECORD *entry, T_PHB_RDM_ELEMENT phb_l_element );
135
136
137 LOCAL USHORT pb_get_ext_file_id (UBYTE pb_type);
138 LOCAL void pb_prepare_ext_data(UBYTE *number, UBYTE no_len,
139 UBYTE *subaddr, UBYTE sub_len,
140 USHORT file_id);
141 LOCAL void pb_free_used_record(UBYTE type, SHORT index, UBYTE rec_num);
142 /*
143 +--------------------------------------------------------------------+
144 | PROJECT: MMI-Framework (8417) MODULE: PHB |
145 | STATE : code ROUTINE: pb_sat_update_reset |
146 +--------------------------------------------------------------------+
147
148 PURPOSE : Initialisation of phonebook field for SAT REFRESH
149 */
150
151 void pb_sat_update_reset (USHORT data_id)
152 {
153 TRACE_FUNCTION("pb_sat_update_reset()");
154
155 #ifdef SIM_TOOLKIT
156 switch (data_id)
157 {
158 /* ACI-ENH-17240: Subissue of CQ 16303, ADN and FDN are updated
159 if one of them has changed */
160 case SIM_ADN:
161 /*
162 * pb_init_element (ADN);
163 * pb_init_ctb (ADN);
164 * phb_ctb[ADN].rcd_bitmap = adn_bitmap;
165 * memset(phb_ctb[ADN].rcd_bitmap, 0, MAX_ADN_BITMAP);
166 * break;
167 */
168 case SIM_FDN:
169 /*
170 * pb_init_element (FDN);
171 * pb_init_ctb (FDN);
172 * phb_ctb[FDN].rcd_bitmap = fdn_bitmap;
173 * memset(phb_ctb[FDN].rcd_bitmap, 0, MAX_FDN_BITMAP);
174 */
175 pb_init_afb();
176 break;
177
178 case SIM_BDN:
179 pb_init_element (BDN);
180 pb_init_ctb (BDN);
181 phb_ctb[BDN].rcd_bitmap = bdn_bitmap;
182 memset(phb_ctb[BDN].rcd_bitmap, 0, MAX_BDN_BITMAP);
183 break;
184
185 case SIM_SDN:
186 pb_init_element (SDN);
187 pb_init_ctb (SDN);
188 phb_ctb[SDN].rcd_bitmap = sdn_bitmap;
189 memset(phb_ctb[SDN].rcd_bitmap, 0, MAX_SDN_BITMAP);
190 break;
191
192 case SIM_MSISDN:
193 pb_init_element (UPN);
194 pb_init_ctb (UPN);
195 phb_ctb[UPN].rcd_bitmap = upn_bitmap;
196 memset(phb_ctb[UPN].rcd_bitmap, 0, MAX_UPN_BITMAP);
197 break;
198
199 /* CQ16301: Added support for LND refresh triggered by SAT */
200 case SIM_LND:
201 pb_init_l_element (LDN);
202 pb_init_ctb (LDN);
203 break;
204
205 default:
206 break;
207 }
208 #endif
209 }
210
211 /*
212 +--------------------------------------------------------------------+
213 | PROJECT: MMI-Framework (8417) MODULE: PHB |
214 | STATE : code ROUTINE: pb_init_ctb |
215 +--------------------------------------------------------------------+
216
217 PURPOSE : Initialisation of the phonebook control block,
218 but not for bitmap field
219 */
220
221 void pb_init_ctb (T_PHB_TYPE book)
222 {
223 TRACE_FUNCTION("pb_init_ctb()");
224
225 phb_ctb[book].mem = NO_PHB_ENTRY;
226 phb_ctb[book].alpha_len = 0;
227 phb_ctb[book].max_rcd = 0;
228 phb_ctb[book].used_rcd = 0;
229 phb_ctb[book].first_rcd = UNUSED_INDEX;
230 phb_ctb[book].first_trcd = UNUSED_INDEX;
231 phb_ctb[book].first_nrcd = UNUSED_INDEX;
232 phb_ctb[book].first_mtrcd = UNUSED_INDEX;
233 phb_ctb[book].first_mnrcd = UNUSED_INDEX;
234 }
235
236 /*
237 +--------------------------------------------------------------------+
238 | PROJECT: MMI-Framework (8417) MODULE: PHB |
239 | STATE : code ROUTINE: pb_init_element |
240 +--------------------------------------------------------------------+
241
242 PURPOSE : Initialisation of the saved phonebook element
243 */
244
245 void pb_init_element (UBYTE book)
246 {
247 SHORT index;
248
249 TRACE_FUNCTION("pb_init_element()");
250
251 index = phb_ctb[book].first_rcd;
252 while (index NEQ UNUSED_INDEX)
253 {
254 phb_element[index].free = PHB_ELEMENT_FREE;
255 index = phb_element[index].next_rcd;
256 }
257 }
258
259 /*
260 +--------------------------------------------------------------------+
261 | PROJECT: MMI-Framework (8417) MODULE: PHB |
262 | STATE : code ROUTINE: pb_init_l_element |
263 +--------------------------------------------------------------------+
264
265 PURPOSE : Initialisation of the saved phonebook element (ME)
266 */
267
268 void pb_init_l_element (UBYTE book)
269 {
270 SHORT index;
271
272 TRACE_FUNCTION("pb_init_l_element()");
273
274 index = phb_ctb[book].first_rcd;
275 while (index NEQ UNUSED_INDEX)
276 {
277 phb_l_element[index].free = PHB_ELEMENT_FREE;
278 index = phb_element[index].next_rcd;
279 }
280 }
281
282 /*
283 +--------------------------------------------------------------------+
284 | PROJECT: MMI-Framework (8417) MODULE: PHB |
285 | STATE : code ROUTINE: phb_Init |
286 +--------------------------------------------------------------------+
287
288 PURPOSE : Power-on initialisation of the phonebook module
289 */
290
291 void phb_Init (void)
292 {
293 fdn_mode = NO_OPERATION;
294 /* set fdn_classtype to default value */
295 fdn_classtype = CLASS_VceDatFaxSms;
296 fdn_input_classtype = fdn_classtype;
297 #ifdef SIM_TOOLKIT
298 simShrdPrm.fuRef=-1;
299 if (!psaSAT_FURegister (pb_update))
300 {
301 TRACE_EVENT ("FAILED to register the handler pb_update() for FU");
302 }
303 if (!psaSAT_FURegister (pb_update_ecc_fu))
304 {
305 TRACE_EVENT ("FAILED to register the handler pb_update_ecc_fu() for FU");
306 }
307
308 #endif
309 }
310
311 /*
312 +--------------------------------------------------------------------+
313 | PROJECT: MMI-Framework (8417) MODULE: PHB |
314 | STATE : code ROUTINE: pb_init |
315 +--------------------------------------------------------------------+
316
317 PURPOSE :
318 */
319
320 void pb_init (void)
321 {
322 TRACE_FUNCTION ("pb_init()");
323
324 if (fdn_mode EQ NO_OPERATION)
325 {
326 {
327 T_PHB_TYPE i;
328
329 /* Initiate the bitmap in control block */
330 for (i=0; i<MAX_PHONEBOOK; i++)
331 {
332 pb_init_ctb(i);
333
334 switch(i)
335 {
336 case ECC:
337 phb_ctb[i].rcd_bitmap = ecc_bitmap;
338 memset(phb_ctb[i].rcd_bitmap, 0, MAX_ECC_BITMAP);
339 break;
340 case ADN:
341 phb_ctb[i].rcd_bitmap = adn_bitmap;
342 memset(phb_ctb[i].rcd_bitmap, 0, MAX_ADN_BITMAP);
343 break;
344 case FDN:
345 phb_ctb[i].rcd_bitmap = fdn_bitmap;
346 memset(phb_ctb[i].rcd_bitmap, 0, MAX_FDN_BITMAP);
347 break;
348 case BDN:
349 phb_ctb[i].rcd_bitmap = bdn_bitmap;
350 memset(phb_ctb[i].rcd_bitmap, 0, MAX_BDN_BITMAP);
351 break;
352 case SDN:
353 phb_ctb[i].rcd_bitmap = sdn_bitmap;
354 memset(phb_ctb[i].rcd_bitmap, 0, MAX_SDN_BITMAP);
355 break;
356 case UPN:
357 phb_ctb[i].rcd_bitmap = upn_bitmap;
358 memset(phb_ctb[i].rcd_bitmap, 0, MAX_UPN_BITMAP);
359 break;
360 }
361 }
362 }
363 #ifdef PHONEBOOK_EXTENSION
364 {
365 T_PHB_EXT_TYPE i;
366 /* Initiate the bitmap for the phonebook extention records */
367 for (i = 0; i < MAX_PHB_EXT; i++)
368 {
369 phb_ext_records[i].mem = NO_PHB_ENTRY;
370 phb_ext_records[i].max_rcd = 0;
371 switch (i)
372 {
373 case EXT1:
374 phb_ext_records[i].rcd_bitmap = ext1_bitmap;
375 memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT1_BITMAP); /* ADN; LDN */
376 break;
377
378 case EXT2:
379 phb_ext_records[i].rcd_bitmap = ext2_bitmap;
380 memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT2_BITMAP); /* FDN */
381 break;
382 case EXT3:
383 phb_ext_records[i].rcd_bitmap = ext3_bitmap;
384 memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT3_BITMAP); /* SDN */
385 break;
386 case EXT4:
387 phb_ext_records[i].rcd_bitmap = ext4_bitmap;
388 memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT4_BITMAP); /* BDN */
389 break;
390 }
391 }
392 }
393 #endif
394 {
395 int i;
396 /* Initiate the free element */
397 for (i=0; i<MAX_AFB_RECORDS; i++)
398 phb_element[i].free = PHB_ELEMENT_FREE;
399 for (i=0; i<MAX_RDM_RECORDS; i++)
400 phb_l_element[i].free = PHB_ELEMENT_FREE;
401 }
402
403 phb_stat = PHB_UNKNOWN;
404 cmhPHB_StatIndication ( PHB_UNKNOWN, CME_ERR_NotPresent, TRUE );
405 }
406 }
407
408
409 /*
410 +--------------------------------------------------------------------+
411 | PROJECT: MMI-Framework (8417) MODULE: PHB |
412 | STATE : code ROUTINE: pb_init_afb |
413 +--------------------------------------------------------------------+
414
415
416 PURPOSE :
417
418 */
419
420 void pb_init_afb(void)
421 {
422 T_PHB_TYPE i;
423 SHORT index;
424 SHORT cur_index;
425
426 TRACE_FUNCTION ("pb_init_afb()");
427
428 /* Initiate the bitmap in control block */
429 for (i=0; i<MAX_PHONEBOOK; i++)
430 {
431 switch (i)
432 {
433 case ADN:
434 case FDN:
435 index = phb_ctb[i].first_rcd;
436 while (index != UNUSED_INDEX)
437 {
438 cur_index = index;
439 index = phb_element[cur_index].next_rcd;
440 phb_element[cur_index].free = PHB_ELEMENT_FREE;
441 phb_element[cur_index].prev_rcd = UNUSED_INDEX;
442 phb_element[cur_index].next_rcd = UNUSED_INDEX;
443 }
444 pb_init_ctb(i);
445 switch(i)
446 {
447 case ADN:
448 phb_ctb[i].rcd_bitmap = adn_bitmap;
449 memset(phb_ctb[i].rcd_bitmap, 0, MAX_ADN_BITMAP);
450 break;
451 case FDN:
452 phb_ctb[i].rcd_bitmap = fdn_bitmap;
453 memset(phb_ctb[i].rcd_bitmap, 0, MAX_FDN_BITMAP);
454 break;
455 }
456 break;
457 case ADN_FDN:
458 pb_init_ctb(i);
459 break;
460 default:
461 break;
462 }
463 }
464 }
465
466 /*
467 +--------------------------------------------------------------------+
468 | PROJECT: MMI-Framework (8417) MODULE: PHB |
469 | STATE : code ROUTINE: pb_reset |
470 +--------------------------------------------------------------------+
471
472 PURPOSE : Invalidate phonebook buffered in RAM
473
474 */
475
476 void pb_reset (void)
477 {
478 TRACE_FUNCTION("pb_reset()");
479
480 pb_write_eeprom();
481
482 fdn_mode = NO_OPERATION; /* some more stuff may be needed */
483 /* set fdn_classtype to default value */
484 fdn_classtype = CLASS_VceDatFaxSms;
485 fdn_input_classtype = fdn_classtype;
486 cmhPHB_StatIndication ( PHB_UNKNOWN, CME_ERR_NotPresent, TRUE );
487 }
488
489 /*
490 +--------------------------------------------------------------------+
491 | PROJECT: MMI-Framework (8417) MODULE: PHB |
492 | STATE : code ROUTINE: pb_create_memory |
493 +--------------------------------------------------------------------+
494
495
496 PURPOSE : Find the next free entry
497
498 */
499
500 T_PHB_RETURN pb_create_memory(SHORT *index)
501 {
502 int i;
503
504 /* TRACE_FUNCTION("pb_create_memory()"); */
505
506 for (i=0; i<MAX_AFB_RECORDS; i++)
507 {
508 if (phb_element[i].free EQ PHB_ELEMENT_FREE)
509 {
510 memset ((char *)&phb_element[i].entry, 0xff, sizeof (T_AFB_RECORD));
511 phb_element[i].free = PHB_ELEMENT_USED;
512 *index = i;
513 return PHB_OK;
514 }
515 }
516
517 return PHB_FULL;
518 }
519
520
521 /*
522 +--------------------------------------------------------------------+
523 | PROJECT: MMI-Framework (8417) MODULE: PHB |
524 | STATE : code ROUTINE: pb_create_l_memory |
525 +--------------------------------------------------------------------+
526
527
528 PURPOSE : Find the next free entry
529
530 */
531
532 T_PHB_RETURN pb_create_l_memory(SHORT *index)
533 {
534 SHORT i;
535
536 /* TRACE_FUNCTION("pb_create_l_memory()"); */
537
538 for (i=0; i<MAX_RDM_RECORDS; i++)
539 {
540 if (phb_l_element[i].free EQ PHB_ELEMENT_FREE)
541 {
542 memset ((char *)&phb_l_element[i].entry, 0xff, sizeof (T_RDM_RECORD));
543 phb_l_element[i].free = PHB_ELEMENT_USED;
544 *index = i;
545 return PHB_OK;
546 }
547 }
548
549 return PHB_FULL;
550 }
551
552
553 /*
554 +--------------------------------------------------------------------+
555 | PROJECT: MMI-Framework (8417) MODULE: PHB |
556 | STATE : code ROUTINE: pb_read_ecc |
557 +--------------------------------------------------------------------+
558
559
560 PURPOSE : Build emergency call phonebook.
561
562 */
563 T_PHB_RETURN pb_read_ecc (USHORT error, UBYTE ecc_len, UBYTE *sim_ecc)
564 {
565 UBYTE *data_ptr;
566 int i;
567
568 TRACE_FUNCTION ("pb_read_ecc()");
569
570 if (fdn_mode != NO_OPERATION)
571 return PHB_OK;
572
573 /* If SIM card is not active, the emergency call numbers are read from EEPROM */
574 if ( ( error EQ SIM_CAUSE_OTHER_ERROR )
575 OR ( error EQ SIM_CAUSE_CARD_REMOVED)
576 OR ( error >= SIM_CAUSE_PARAM_WRONG AND error <= SIM_CAUSE_DRV_TEMPFAIL) )
577 {
578 pb_read_eeprom_ecc();
579 }
580
581 /* SIM card is active, the emergency call numbers are read from SIM card */
582 else
583 {
584 /* if SIM ECC data is not empty, copy SIM ECC data to phonebook */
585 if ( strcmp((CHAR*)sim_ecc,"") )
586 {
587 phb_ctb[ECC].mem = SIM_MEMORY;
588 data_ptr = sim_ecc;
589 phb_ctb[ECC].max_rcd = (SHORT)((ecc_len/3) > MAX_ECC_RCD)? MAX_ECC_RCD: ecc_len/3;
590
591 phb_ctb[ECC].type = ECC;
592 phb_ctb[ECC].first_trcd = UNUSED_INDEX;
593
594 /* Read emergency call number */
595 for (i=0; i<MAX_ECC_RCD; i++)
596 {
597 pb_copy_ecc_entry (data_ptr, (UBYTE)i);
598 data_ptr += 3;
599 }
600 }
601 }
602
603 return PHB_OK;
604 }
605
606
607 /*
608 +----------------------------------------------------------------------+
609 | PROJECT: MMI-Framework (8417) MODULE: PHB |
610 | STATE : code ROUTINE: pb_read_sim |
611 +----------------------------------------------------------------------+
612
613
614 PURPOSE : SIM card informs the numbers of phonebook record.
615
616 */
617
618 BOOL pb_read_sim(USHORT data_id, UBYTE rcd_num, UBYTE len)
619 {
620 SHORT table_id;
621
622 TRACE_FUNCTION ("pb_read_sim()");
623
624 table_id = psaSIM_atbNewEntry();
625
626 if(table_id NEQ NO_ENTRY)
627 {
628 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
629 simShrdPrm.atb[table_id].accType = ACT_RD_REC;
630 simShrdPrm.atb[table_id].v_path_info = FALSE;
631 simShrdPrm.atb[table_id].reqDataFld = data_id;
632 simShrdPrm.atb[table_id].recNr = rcd_num;
633 if (rcd_num EQ 1)
634 simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT;
635 else
636 simShrdPrm.atb[table_id].dataLen = len;
637 simShrdPrm.atb[table_id].exchData = data;
638 simShrdPrm.atb[table_id].rplyCB = pb_read_cb;
639
640 simShrdPrm.aId = table_id;
641
642 if (pause_pb_reading_while_EXT_reading EQ TRUE) /* Read request must be paused while EXT is read */
643 {
644 paused_table_id = simShrdPrm.aId; /* save the aId for later SIM Access */
645 }
646 else
647 {
648 if(psaSIM_AccessSIMData() < 0)
649 {
650 TRACE_EVENT("FATAL ERROR");
651 return FALSE;
652 }
653 }
654 }
655 else
656 return FALSE;
657
658 return TRUE;
659 }
660
661
662
663 /*
664 +----------------------------------------------------------------------+
665 | PROJECT: MMI-Framework (8417) MODULE: PHB |
666 | STATE : code ROUTINE: pb_read_sim_ext |
667 +----------------------------------------------------------------------+
668
669
670 PURPOSE : SIM card informs the numbers of phonebook record.
671
672 */
673
674 #ifdef PHONEBOOK_EXTENSION
675 void pb_read_sim_ext(USHORT data_id, UBYTE rcd_num)
676 {
677 SHORT table_id;
678
679 TRACE_FUNCTION ("pb_read_sim_ext()");
680
681 table_id = psaSIM_atbNewEntry();
682
683 if(table_id NEQ NO_ENTRY)
684 {
685 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
686 simShrdPrm.atb[table_id].accType = ACT_RD_REC;
687 simShrdPrm.atb[table_id].v_path_info = FALSE;
688 simShrdPrm.atb[table_id].reqDataFld = data_id;
689 simShrdPrm.atb[table_id].recNr = rcd_num;
690 simShrdPrm.atb[table_id].dataLen = 13;
691 simShrdPrm.atb[table_id].exchData = data;
692 simShrdPrm.atb[table_id].rplyCB = pb_read_ext_cb;
693
694 simShrdPrm.aId = table_id;
695
696 pause_pb_reading_while_EXT_reading = TRUE; /* Suspend further ADN reading while EXT is read */
697
698 if(psaSIM_AccessSIMData() < 0)
699 {
700 TRACE_EVENT("pb_read_sim_ext (): FATAL ERROR");
701 }
702 }
703 }
704 #endif
705
706
707
708 /*
709 +----------------------------------------------------------------------+
710 | PROJECT: MMI-Framework (8417) MODULE: PHB |
711 | STATE : code ROUTINE: pb_init_sync_sim |
712 +----------------------------------------------------------------------+
713
714
715 PURPOSE : Sync the local LDN entries to SIM
716 */
717
718
719 BOOL pb_init_sync_sim(UBYTE type)
720 {
721 TRACE_FUNCTION ("pb_init_sync_sim()");
722
723 switch (type)
724 {
725 case LDN:
726 break;
727 default: /* Only supported for LDN */
728 return FALSE;
729 }
730
731 if (phb_ctb[type].service EQ ALLOCATED_AND_ACTIVATED
732 AND phb_ctb[type].mem != NO_PHB_ENTRY)
733 {
734 if (max_sim_LDN_records) /* start with oldest record */
735 return (pb_prepare_sync_sim(type, max_sim_LDN_records));
736 }
737 return FALSE;
738 }
739
740
741 /*
742 +----------------------------------------------------------------------+
743 | PROJECT: MMI-Framework (8417) MODULE: PHB |
744 | STATE : code ROUTINE: pb_prepare_sync_sim |
745 +----------------------------------------------------------------------+
746
747
748 PURPOSE : Sync the local LDN entries to SIM
749 */
750
751 BOOL pb_prepare_sync_sim(UBYTE type, UBYTE rcd_num)
752 {
753 T_PHB_RECORD entry;
754 T_PHB_RETURN sim_result;
755 UBYTE tag_len;
756
757 TRACE_FUNCTION ("pb_prepare_sync_sim()");
758
759 switch (type)
760 {
761 case LDN:
762 break;
763 default:
764 return FALSE;
765 }
766
767 memset(data, 0xFF, sizeof(data));
768
769 if (pb_read_phys_record( type, rcd_num, &entry) NEQ PHB_OK)
770 {
771 sim_result = pb_sync_sim(type, rcd_num); /* Write an empty record */
772 }
773 else
774 {
775 tag_len = MINIMUM ( phb_ctb[type].alpha_len, entry.tag_len );
776 memcpy(data, entry.tag, tag_len);
777 data[phb_ctb[type].alpha_len] = entry.len+1;
778 /*#if PHONEBOOK_EXTENSION*/
779 #if 0
780 if (entry.number[10] NEQ 0xFF)
781 {
782 data[phb_ctb[type].alpha_len] = 11; /* max. length */
783 }
784 else
785 {
786 data[phb_ctb[type].alpha_len] = entry.len+1;
787 }
788 #else
789 data[phb_ctb[type].alpha_len] = entry.len+1;
790 #endif
791 data[phb_ctb[type].alpha_len+1] = entry.ton_npi;
792 memcpy((char *)&data[phb_ctb[type].alpha_len+2],
793 (char *)entry.number, 10);
794 data[phb_ctb[type].alpha_len+12] = entry.cc_id;
795
796 /*#ifdef PHONEBOOK_EXTENSION*/
797 #if 0
798 if (entry->number[10] NEQ 0xFF)
799 {
800 file_id = pb_get_ext_file_id (type);
801 if (old_ext_rcd_num NEQ 0xFF)
802 {
803 /* use the old extention record */
804 phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num;
805 }
806 else
807 {
808 phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (type);
809 }
810 data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num;
811 }
812 /* only number extention or subaddress could be store */
813 else if (entry->subaddr[0] NEQ 0xFF)
814 {
815 file_id = pb_get_ext_file_id (type);
816 if (old_ext_rcd_num NEQ 0xFF)
817 {
818 /* use the old extention record */
819 phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num;
820 }
821 else
822 {
823 phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (0xFF);
824 }
825 data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num;
826 }
827 #endif
828 sim_result = pb_sync_sim(type, rcd_num); /* Record is always 1 for cyclic files */
829
830 /*#ifdef PHONEBOOK_EXTENSION*/
831 #if 0
832 if (sim_result NEQ PHB_FAIL)
833 {
834 if (phb_element[new_index].entry.ext_rcd_num NEQ 0xFF)
835 {
836 pb_prepare_ext_data (phb_element[new_index].entry.number,
837 phb_element[new_index].entry.len,
838 phb_element[new_index].entry.subaddr,
839 10,
840 file_id);
841 sim_result = pb_write_sim_ext(file_id, phb_element[new_index].entry.ext_rcd_num);
842 }
843 else if (old_ext_rcd_num NEQ 0xFF)
844 {
845 /* delete the old extention record */
846 pb_rem_ext_record_flag (type, old_ext_rcd_num);
847 pb_prepare_ext_data (NULL, 0, NULL, 0, file_id);
848 sim_result = pb_write_sim_ext(SIM_EXT1, old_ext_rcd_num);
849 }
850 }
851 #endif /* PHONEBOOK_EXTENSION */
852 }
853 if (sim_result NEQ PHB_FAIL)
854 return (TRUE);
855 return TRUE;
856 }
857
858
859 /*
860 +----------------------------------------------------------------------+
861 | PROJECT: MMI-Framework (8417) MODULE: PHB |
862 | STATE : code ROUTINE: pb_sync_sim |
863 +----------------------------------------------------------------------+
864
865
866 PURPOSE : Sync the local LDN entries to SIM
867 */
868
869 BOOL pb_sync_sim (UBYTE type, UBYTE rcd_num)
870 {
871 SHORT table_id;
872 USHORT data_id;
873
874 TRACE_FUNCTION ("pb_sync_sim()");
875
876 switch (type)
877 {
878 case LDN:
879 data_id = SIM_LND;
880 break;
881 default:
882 return FALSE;
883 }
884
885 table_id = psaSIM_atbNewEntry();
886 if (table_id EQ NO_ENTRY)
887 {
888 TRACE_ERROR ("pb_sync_sim(): no more table entries");
889 return (FALSE);
890 }
891
892 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
893 simShrdPrm.atb[table_id].accType = ACT_WR_REC;
894 simShrdPrm.atb[table_id].v_path_info = FALSE;
895 simShrdPrm.atb[table_id].reqDataFld = data_id;
896 simShrdPrm.atb[table_id].recNr = rcd_num;
897 simShrdPrm.atb[table_id].dataLen = phb_ctb[type].alpha_len + 14;
898 simShrdPrm.atb[table_id].exchData = data;
899 simShrdPrm.atb[table_id].rplyCB = pb_sync_sim_cb;
900
901 simShrdPrm.aId = table_id;
902
903
904 if(psaSIM_AccessSIMData() < 0)
905 {
906 return (FALSE);
907 }
908
909 phb_stat = PHB_BUSY;
910 cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, TRUE );
911
912 /* return (PHB_EXCT);*/
913 return (TRUE);
914 }
915
916
917
918
919 /*
920 +------------------------------------------------------------------+
921 | PROJECT : MMI-Framework (8417) MODULE : PHB |
922 | STATE : code ROUTINE : pb_sync_sim_cb |
923 +------------------------------------------------------------------+
924
925
926 PURPOSE : Call back for sync phonebook in SIM card.
927
928 */
929
930 void pb_sync_sim_cb(SHORT table_id)
931 {
932 UBYTE type;
933 USHORT type_id;
934 UBYTE rcd_num;
935
936 TRACE_FUNCTION("pb_sync_sim_cb()");
937
938 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
939
940 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
941 {
942 TRACE_ERROR("pb_sync_sim_cb(): error for writing");
943 /* return; */ /* dont stop writing here if one record fails since must reach?
944 pb_finish_sync_sim to deactivate the sim */
945 }
946
947 /* Inform the data of record */
948 switch (simShrdPrm.atb[table_id].reqDataFld)
949 {
950 case SIM_LND: /* Up to now only LDN supported */
951 type = LDN;
952 type_id = SIM_LND;
953 break;
954 default:
955 TRACE_FUNCTION("pb_sync_sim_cb() invalid callback");
956 return;
957 }
958
959 rcd_num = simShrdPrm.atb[table_id].recNr;
960 if (--rcd_num)
961 {
962 pb_prepare_sync_sim(type, rcd_num); /* sync next record */
963 return;
964 }
965 else /* Last record copied to SIM */
966 {
967 pb_finish_sync_sim();
968 }
969 return;
970 }
971
972
973
974 /*
975 +---------------------------------------------------------------------+
976 | PROJECT : MMI-Framework (8417) MODULE : PHB |
977 | STATE : code ROUTINE : pb_finish_sync_sim |
978 +---------------------------------------------------------------------+
979
980
981 PURPOSE : Call back for sync phonebook in SIM card.
982
983 */
984
985 void pb_finish_sync_sim()
986 {
987 phb_stat = PHB_READY;
988
989 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE );
990
991 pb_reset();
992 pb_init();
993
994 simShrdPrm.synCs = SYNC_DEACTIVATE; /* This was moved from pb_sync_sim_ldn */
995 psaSIM_SyncSIM();
996
997 return;
998 }
999
1000
1001
1002
1003
1004 /*
1005 +-------------------------------------------------------------------+
1006 | PROJECT : MMI-Framework (8417) MODULE : PHB |
1007 | STATE : code ROUTINE : pb_copy_sim_entry|
1008 +-------------------------------------------------------------------+
1009
1010
1011 PURPOSE : SIM card informs the numbers of phonebook record.
1012
1013 */
1014
1015 void pb_copy_sim_entry(SHORT cur_index)
1016 {
1017 UBYTE *ptr;
1018 UBYTE max_tag_len;
1019 #ifdef PHONEBOOK_EXTENSION
1020 USHORT file_id;
1021 #endif
1022
1023 TRACE_FUNCTION ("pb_copy_sim_entry()");
1024
1025 ptr = data;
1026 max_tag_len = MINIMUM (phb_ctb[phb_element[cur_index].type].alpha_len,
1027 PHB_MAX_TAG_LEN);
1028 phb_element[cur_index].entry.tag_len = (UBYTE)pb_get_entry_len(ptr, max_tag_len);
1029 memset(phb_element[cur_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
1030 memcpy ( (char*)phb_element[cur_index].entry.tag,
1031 (char*)ptr,
1032 phb_element[cur_index].entry.tag_len );
1033
1034 ptr += phb_ctb[phb_element[cur_index].type].alpha_len;
1035 phb_element[cur_index].entry.len = *(ptr++) - 1;
1036 phb_element[cur_index].entry.ton_npi = *ptr++;
1037
1038 /*
1039 * This error handling is done to avoid the accidental incorrect
1040 * record length stored in the test SIMs
1041 */
1042 if (phb_element[cur_index].entry.len > PHB_PACKED_NUM_LEN)
1043 {
1044 phb_element[cur_index].entry.len = PHB_PACKED_NUM_LEN;
1045 }
1046
1047 memset(phb_element[cur_index].entry.number, 0xFF, PHB_PACKED_NUM_LEN);
1048 memcpy( (char*)phb_element[cur_index].entry.number, (char*)ptr, phb_element[cur_index].entry.len );
1049 ptr += 10;
1050 phb_element[cur_index].entry.cc_id = *ptr++;
1051
1052 #ifdef PHONEBOOK_EXTENSION
1053 if (*ptr != 0xFF) /* check for extention records */
1054 {
1055 file_id = pb_get_ext_file_id(phb_element[cur_index].type);
1056 if (file_id != 0xFFFF)
1057 {
1058 phb_element[cur_index].entry.ext_rcd_num = (UBYTE)*ptr;
1059 ext_index = cur_index;
1060 max_ext_chain_reads=5; /* Limit the number of additional EXT reads per ADN record to avoid a possible endless loop */
1061 pb_read_sim_ext(file_id, phb_element[cur_index].entry.ext_rcd_num);
1062 }
1063 }
1064 else
1065 {
1066 phb_element[cur_index].entry.ext_rcd_num = 0xFF;
1067 }
1068 #endif
1069 }
1070
1071
1072 /*
1073 +-------------------------------------------------------------------+
1074 | PROJECT : MMI-Framework (8417) MODULE : PHB |
1075 | STATE : code ROUTINE : pb_copy_sim_entry|
1076 +-------------------------------------------------------------------+
1077
1078
1079 PURPOSE : SIM card informs the numbers of phonebook record.
1080
1081 */
1082
1083 void pb_copy_sim_ldn_entry(SHORT cur_index)
1084 {
1085 UBYTE *ptr;
1086 UBYTE max_tag_len;
1087 #ifdef PHONEBOOK_EXTENSION
1088 /* USHORT file_id;*/
1089 #endif
1090
1091 TRACE_FUNCTION ("pb_copy_sim_ldn_entry()");
1092
1093 ptr = data;
1094 max_tag_len = MINIMUM (phb_ctb[phb_l_element[cur_index].type].alpha_len,
1095 PHB_MAX_TAG_LEN);
1096 phb_l_element[cur_index].entry.tag_len = (UBYTE)pb_get_entry_len(ptr, max_tag_len);
1097 memset(phb_l_element[cur_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
1098 memcpy ( (char*)phb_l_element[cur_index].entry.tag,
1099 (char*)ptr,
1100 phb_l_element[cur_index].entry.tag_len );
1101
1102 ptr += phb_ctb[phb_l_element[cur_index].type].alpha_len;
1103 phb_l_element[cur_index].entry.len = *(ptr++) - 1;
1104 phb_l_element[cur_index].entry.ton_npi = *ptr++;
1105 memset(phb_l_element[cur_index].entry.number, 0xFF, PHB_PACKED_NUM_LEN);
1106 memcpy( (char*)phb_l_element[cur_index].entry.number, (char*)ptr, 10 );
1107 ptr += 10;
1108 phb_l_element[cur_index].entry.cc_id = *ptr++;
1109
1110 phb_l_element[cur_index].entry.year = 0xff; /* This is not on SIM */
1111 phb_l_element[cur_index].entry.month = 0xff;
1112 phb_l_element[cur_index].entry.day = 0xff;
1113 phb_l_element[cur_index].entry.hour = 0xff;
1114 phb_l_element[cur_index].entry.minute = 0xff;
1115 phb_l_element[cur_index].entry.second = 0xff;
1116
1117 /*#ifdef PHONEBOOK_EXTENSION */
1118 #if 0
1119 if (*ptr != 0xFF) /* check for extention records */
1120 {
1121 file_id = pb_get_ext_file_id(phb_l_element[cur_index].type);
1122 if (file_id != 0xFFFF)
1123 {
1124 phb_l_element[cur_index].entry.ext_rcd_num = (UBYTE)*ptr;
1125 ext_index = cur_index;
1126 pb_read_sim_ext(file_id, phb_l_element[cur_index].entry.ext_rcd_num);
1127 }
1128 }
1129 else
1130 {
1131 phb_l_element[cur_index].entry.ext_rcd_num = 0xFF;
1132 }
1133 #endif
1134 }
1135
1136
1137 /*
1138 +---------------------------------------------------------------------+
1139 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1140 | STATE : code ROUTINE: pb_read_sim_record |
1141 +---------------------------------------------------------------------+
1142
1143
1144 PURPOSE : Build emergency call phonebook.
1145
1146 */
1147
1148 T_PHB_RETURN pb_read_sim_record(UBYTE type, USHORT type_id, UBYTE rcd_num)
1149 {
1150 SHORT index;
1151 UBYTE n,m;
1152
1153 /* TRACE_FUNCTION ("pb_read_sim_record()");*/
1154
1155 if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd)
1156 {
1157 TRACE_FUNCTION("Used rcd full!");
1158 return PHB_FULL;
1159 }
1160
1161 if (type NEQ LDN)
1162 {
1163 /* search a free element in phonebook element table */
1164 if (pb_create_memory(&index) NEQ PHB_OK)
1165 {
1166 TRACE_FUNCTION("Memory full");
1167 pb_read_eeprom_req();
1168 return PHB_FULL;
1169 }
1170
1171 phb_ctb[type].used_rcd++;
1172 n = (UBYTE)(rcd_num-1)/8;
1173 m = (rcd_num-1)%8;
1174 phb_ctb[type].rcd_bitmap[n] |= 0x01 << m;
1175 phb_element[index].type = type;
1176 phb_element[index].entry.index = rcd_num;
1177
1178 pb_copy_sim_entry(index);
1179
1180 pb_record_sort(index);
1181 pb_alpha_sort(index);
1182 pb_num_sort(index);
1183
1184 if ((type EQ ADN) OR (type EQ FDN))
1185 {
1186 pb_malpha_sort(index);
1187 pb_mnum_sort(index);
1188 }
1189 }
1190 else /* special handling for LDN entries from SIM */
1191 {
1192 if (pb_create_l_memory(&index) NEQ PHB_OK)
1193 {
1194 TRACE_FUNCTION("Memory full");
1195 pb_read_eeprom_req();
1196 return PHB_OK;
1197 }
1198 phb_ctb[type].used_rcd++;
1199 phb_l_element[index].type = type;
1200 phb_l_element[index].entry.index = rcd_num;
1201
1202 pb_copy_sim_ldn_entry(index);
1203
1204 pb_l_record_sort(index);
1205 /* pb_l_alpha_sort(index);*//* not possible with RDM Structure */
1206 /* pb_l_num_sort(index);*/
1207 }
1208
1209 return PHB_OK;
1210 }
1211
1212
1213 /*
1214 +---------------------------------------------------------------------+
1215 | PROJECT: MODULE: PHB |
1216 | STATE : code ROUTINE: pb_get_ext_file_id |
1217 +---------------------------------------------------------------------+
1218
1219
1220 PURPOSE : Find and gives the extention SIM file ID for the
1221 phonebook entry.
1222
1223 */
1224 #ifdef PHONEBOOK_EXTENSION
1225 LOCAL USHORT pb_get_ext_file_id (UBYTE pb_type)
1226 {
1227 switch (pb_type)
1228 {
1229 case 0xFF:
1230 case ADN:
1231 case LDN:
1232 //TISH, EXT1 is also used to save UPN extension number. See 11.11 10.5.10
1233 case UPN:
1234 return (SIM_EXT1);
1235
1236 case FDN:
1237 return (SIM_EXT2);
1238
1239 case SDN:
1240 return (SIM_EXT3);
1241
1242 case BDN:
1243 return (SIM_EXT4);
1244
1245 default:
1246 TRACE_ERROR ("pb_get_free_ext_record(): invalid type");
1247 return (0xFFFF);
1248 }
1249 }
1250
1251
1252 /*
1253 +-----------------------------------------------------------------------+
1254 | PROJECT: MODULE: PHB |
1255 | STATE : code ROUTINE: pb_rem_ext_record_flag |
1256 +-----------------------------------------------------------------------+
1257
1258
1259 PURPOSE : Removes the flag for the extention record.
1260
1261 */
1262
1263 LOCAL void pb_rem_ext_record_flag (UBYTE pb_type, UBYTE rcd_num)
1264 {
1265 UBYTE *rcd_bitmap;
1266 UBYTE pos, bit, len;
1267
1268 switch (pb_type)
1269 {
1270 case 0xFF:
1271 case ADN:
1272 //TISH, EXT1 is also used to save UPN extension number. See 11.11 10.5.10
1273 case UPN:
1274 rcd_bitmap = phb_ext_records[EXT1].rcd_bitmap;
1275 len = MAX_EXT1_BITMAP;
1276 break;
1277
1278 case FDN:
1279 rcd_bitmap = phb_ext_records[EXT2].rcd_bitmap;
1280 len = MAX_EXT2_BITMAP;
1281 break;
1282
1283 case SDN:
1284 rcd_bitmap = phb_ext_records[EXT3].rcd_bitmap;
1285 len = MAX_EXT3_BITMAP;
1286 break;
1287 case BDN:
1288 rcd_bitmap = phb_ext_records[EXT4].rcd_bitmap;
1289 len = MAX_EXT4_BITMAP;
1290 break;
1291 default:
1292 TRACE_ERROR ("pb_rem_free_ext_record(): invalid type");
1293 return;
1294 }
1295
1296 pos = (UBYTE)(rcd_num - 1) / 8;
1297 bit = (rcd_num - 1) % 8;
1298
1299 rcd_bitmap[pos] &= (UBYTE)(~(1u << bit));
1300
1301 }
1302
1303 //TISH set extension rcd_bitmap flag
1304 LOCAL void pb_set_ext_record_flag (UBYTE pb_type, UBYTE rcd_num)
1305 {
1306 UBYTE *rcd_bitmap;
1307 UBYTE pos, bit, len;
1308
1309 switch (pb_type)
1310 {
1311 case 0xFF:
1312 case ADN:
1313 case UPN:
1314 rcd_bitmap = phb_ext_records[EXT1].rcd_bitmap;
1315 len = MAX_EXT1_BITMAP;
1316 break;
1317
1318 case FDN:
1319 rcd_bitmap = phb_ext_records[EXT2].rcd_bitmap;
1320 len = MAX_EXT2_BITMAP;
1321 break;
1322
1323 case BDN:
1324 case SDN:
1325 default:
1326 TRACE_ERROR ("pb_rem_free_ext_record(): invalid type");
1327 return;
1328 }
1329
1330 pos = (UBYTE)(rcd_num - 1) / 8;
1331 bit = (rcd_num - 1) % 8;
1332
1333 rcd_bitmap[pos] |= (UBYTE)((1u << bit));
1334
1335 }
1336 /*
1337 +-------------------------------------------------------------------------+
1338 | PROJECT: MODULE: PHB |
1339 | STATE : code ROUTINE: pb_rem_ext_record_number |
1340 +-------------------------------------------------------------------------+
1341
1342
1343 PURPOSE : Gives the extention record number for the phonebook entry.
1344
1345 */
1346
1347 LOCAL UBYTE pb_get_ext_record_number (UBYTE pb_type)
1348 {
1349 UBYTE *rcd_bitmap;
1350 UBYTE len, pos, bit, rcd_num, max_rcd;
1351
1352 switch (pb_type)
1353 {
1354 case 0xFF:
1355 case ADN:
1356 //TISH, EXT1 is also used to save UPN extension number. See 11.11 10.5.10
1357 case UPN:
1358 rcd_bitmap = phb_ext_records[EXT1].rcd_bitmap;
1359 len = MAX_EXT1_BITMAP;
1360 max_rcd = phb_ext_records[EXT1].max_rcd;
1361 break;
1362
1363 case FDN:
1364 rcd_bitmap = phb_ext_records[EXT2].rcd_bitmap;
1365 len = MAX_EXT2_BITMAP;
1366 max_rcd = phb_ext_records[EXT2].max_rcd;
1367 break;
1368
1369 case SDN:
1370 rcd_bitmap = phb_ext_records[EXT3].rcd_bitmap;
1371 len = MAX_EXT3_BITMAP;
1372 max_rcd = phb_ext_records[EXT3].max_rcd;
1373 break;
1374
1375 case BDN:
1376 rcd_bitmap = phb_ext_records[EXT4].rcd_bitmap;
1377 len = MAX_EXT4_BITMAP;
1378 max_rcd = phb_ext_records[EXT4].max_rcd;
1379 break;
1380
1381 default:
1382 TRACE_ERROR ("pb_get_free_ext_number(): invalid type");
1383 return (0xFF);
1384 }
1385
1386 for (pos = 0; pos < len; pos++)
1387 {
1388 if ((UBYTE)~(rcd_bitmap[pos]))
1389 {
1390 int flag;
1391 for(bit=0;bit<8;bit++)
1392 {
1393 flag = rcd_bitmap[pos] & (0x01 << bit);
1394 rcd_num = (pos * 8) + bit + 1;
1395 if(flag)continue;
1396
1397 /* Check for maximum extension records supported */
1398 if (rcd_num > max_rcd )
1399 {
1400 return (0xFF);
1401 }
1402
1403 return (rcd_num);
1404 }
1405 }
1406 }
1407 TRACE_ERROR ("pb_get_free_ext_record(): no more extention records free");
1408
1409 return (0xFF);
1410 }
1411
1412
1413 /*
1414 +-----------------------------------------------------------------------+
1415 | PROJECT: MODULE: PHB |
1416 | STATE : code ROUTINE: pb_read_ext_records |
1417 +-----------------------------------------------------------------------+
1418
1419
1420 PURPOSE : Store the extention record flag and read the next record.
1421
1422 */
1423
1424 LOCAL void pb_read_ext_records (T_PHB_EXT_TYPE type,
1425 USHORT sim_id,
1426 SHORT table_id)
1427 {
1428 UBYTE rcd_num;
1429 // UBYTE n, m;
1430
1431 rcd_num = simShrdPrm.atb[table_id].recNr;
1432
1433 if (rcd_num EQ 1)
1434 {
1435 phb_ext_records[type].max_rcd = simShrdPrm.atb[table_id].recMax;
1436 }
1437
1438 /* If this record is not empty EQ> set used flag */
1439 //TISH: the ext record flag will be set at pb_read_ext_cb.
1440 /*
1441 if (data[0] NEQ 0xFF)
1442 {
1443 n = (UBYTE)(rcd_num - 1) / 8;
1444 m = (rcd_num - 1) % 8;
1445 phb_ext_records[type].rcd_bitmap[n] |= (0x01 << m);
1446 }
1447 */
1448 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
1449
1450 if (rcd_num < phb_ext_records[type].max_rcd)
1451 {
1452 pb_read_sim(sim_id, ++rcd_num, simShrdPrm.atb[table_id].dataLen);
1453 }
1454 else
1455 {
1456 pb_read_sim_req();
1457 }
1458 }
1459
1460 /*
1461 +-----------------------------------------------------------------------+
1462 | PROJECT: MODULE: PHB |
1463 | STATE : code ROUTINE: pb_get_ext_type |
1464 +-----------------------------------------------------------------------+
1465
1466
1467 PURPOSE : gives the extention type for the
1468 phonebook entry.
1469
1470 */
1471 LOCAL UBYTE pb_get_ext_type(UBYTE type)
1472 {
1473 switch (type)
1474 {
1475 case 0xFF:
1476 case ADN:
1477 case LDN:
1478 return ((UBYTE)EXT1);
1479
1480 case FDN:
1481 return ((UBYTE)EXT2);
1482
1483 case SDN:
1484 return ((UBYTE)EXT3);
1485
1486 case BDN:
1487 return ((UBYTE)EXT4);
1488 default:
1489 TRACE_ERROR ("pb_get_free_ext_record(): invalid type");
1490 return (0xFF);
1491 }
1492 }
1493
1494 /*
1495 +-----------------------------------------------------------------------+
1496 | PROJECT: MODULE: PHB |
1497 | STATE : code ROUTINE: pb_read_ext_records |
1498 +-----------------------------------------------------------------------+
1499
1500
1501 PURPOSE : Gives the value of maximum extension records and used extension records
1502
1503 */
1504 LOCAL void pb_read_ext_status(UBYTE ext_type, SHORT * max_ext, SHORT * used_ext)
1505 {
1506 UBYTE rec_num;
1507 UBYTE *rcd_bitmap;
1508 UBYTE bit, pos;
1509
1510 TRACE_FUNCTION ("pb_read_ext_status()");
1511
1512 *max_ext = phb_ext_records[ext_type].max_rcd;
1513 rcd_bitmap = phb_ext_records[ext_type].rcd_bitmap;
1514
1515 for(rec_num=1; rec_num<= *max_ext; rec_num++)
1516 {
1517 /* if bit is set to 1 then it is used record else if bit is set to 0 then it is free record */
1518 pos = (UBYTE)(rec_num-1)/8;
1519 bit = (rec_num - 1) % 8;
1520 if(rcd_bitmap[pos] & (0x01 << bit))
1521 *used_ext +=1;
1522 }
1523
1524 }
1525
1526
1527 #endif
1528
1529 /*
1530 +---------------------------------------------------------------------+
1531 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1532 | STATE : code ROUTINE: pb_read_cb |
1533 +---------------------------------------------------------------------+
1534
1535
1536 PURPOSE : read sim callback function
1537
1538 */
1539 void pb_read_cb(SHORT table_id)
1540 {
1541 UBYTE type = NOT_PRESENT_8BIT;
1542 USHORT type_id;
1543 UBYTE rcd_num; /* record number */
1544
1545 TRACE_FUNCTION ("pb_read_cb()");
1546
1547 /* Inform the data of record */
1548 switch (simShrdPrm.atb[table_id].reqDataFld)
1549 {
1550 #ifdef PHONEBOOK_EXTENSION
1551 case SIM_EXT1:
1552 pb_read_ext_records (EXT1, SIM_EXT1, table_id);
1553 return;
1554
1555 case SIM_EXT2:
1556 pb_read_ext_records (EXT2, SIM_EXT2, table_id);
1557 return;
1558
1559 case SIM_EXT3:
1560 pb_read_ext_records (EXT3, SIM_EXT3, table_id);
1561 return;
1562
1563 case SIM_EXT4:
1564 pb_read_ext_records (EXT4, SIM_EXT4, table_id);
1565 return;
1566
1567 #endif
1568 case SIM_ADN:
1569 type = ADN;
1570 type_id = SIM_ADN;
1571 break;
1572
1573 case SIM_FDN:
1574 type = FDN;
1575 type_id = SIM_FDN;
1576 break;
1577
1578 case SIM_LND: /* Support for SIM_LDN */
1579 type = LDN; /* Caution: different identifiers LDN and LND */
1580 type_id = SIM_LND;
1581 break;
1582
1583 case SIM_SDN:
1584 type = SDN;
1585 type_id = SIM_SDN;
1586 break;
1587
1588 case SIM_BDN:
1589 type = BDN;
1590 type_id = SIM_BDN;
1591 break;
1592
1593 case SIM_MSISDN:
1594 type = UPN;
1595 type_id = SIM_MSISDN;
1596 break;
1597
1598 default:
1599 TRACE_ERROR ("Invalid reqDataFld!");
1600 return;
1601
1602 }
1603 TRACE_EVENT_P1("Callback of SIM reading Phonebook: %d", type);
1604
1605 rcd_num = simShrdPrm.atb[table_id].recNr;
1606
1607
1608 if (rcd_num EQ 1)
1609 {
1610 if (type EQ LDN)
1611 {
1612 /* remember physical count for writing of correct number of LND on CFUN=0 */
1613 max_sim_LDN_records = simShrdPrm.atb[table_id].recMax;
1614 }
1615 phb_ctb[type].alpha_len = simShrdPrm.atb[table_id].dataLen - 14;
1616 phb_ctb[type].max_rcd = simShrdPrm.atb[table_id].recMax;
1617 }
1618
1619 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
1620
1621 /*
1622 * workaround for invalid phonebook entries (the entire entry is filled with 0x00)
1623 * this entries have been received which a very slow SIM
1624 * check if the Length of BCD number/SSC contents is 0x00 then discard
1625 */
1626
1627 /* If this record is not empty, this record is written in phonebook. */
1628 if((phb_ctb[type].max_rcd NEQ 0)
1629 AND ((*data NEQ 0xff) OR (*(data + phb_ctb[type].alpha_len + 2) NEQ 0xff))
1630 AND (*(data + phb_ctb[type].alpha_len) NEQ 0x00))
1631 {
1632 if (pb_read_sim_record(type, type_id, rcd_num) EQ PHB_FULL)
1633 {
1634 #ifdef SIM_TOOLKIT
1635 if (simShrdPrm.fuRef >= 0)
1636 {
1637 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCC_ADD);
1638 }
1639 #endif
1640 phb_stat = PHB_READY;
1641 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE );
1642 return;
1643 }
1644 }
1645
1646 if (rcd_num < phb_ctb[type].max_rcd)
1647 {
1648 if(simShrdPrm.atb[table_id].reqDataFld != type_id) //TISH: if last field id is not current field id
1649 pb_read_sim(type_id, ++rcd_num, NOT_PRESENT_8BIT);
1650 else
1651 pb_read_sim(type_id, ++rcd_num, simShrdPrm.atb[table_id].dataLen);
1652 }
1653 else
1654 pb_read_sim_req();
1655 }
1656
1657
1658
1659
1660 /*
1661 +---------------------------------------------------------------------+
1662 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1663 | STATE : code ROUTINE: pb_nibblecopy |
1664 +---------------------------------------------------------------------+
1665
1666
1667 PURPOSE : appends a packed BCD number to an existing entry.
1668 */
1669
1670 #ifdef PHONEBOOK_EXTENSION
1671 int pb_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count)
1672 {
1673
1674 int i;
1675 int nibble;
1676
1677 int destnibble=destlen*2;
1678 if (destnibble)
1679 {
1680 if ((dest[destlen-1] & 0xF0) EQ 0xF0) /* check if there is space in last nibble */
1681 destnibble--;
1682 }
1683
1684 for ( i=0; i<count*2; i++ )
1685 {
1686 /* check if we access out of bounds */
1687 if (destnibble/2 >= PHB_PACKED_NUM_LEN)
1688 return PHB_PACKED_NUM_LEN;
1689
1690 /* get nibble */
1691 if (i%2 EQ 0)
1692 nibble = src[i/2] & 0x0F;
1693 else
1694 nibble = (src[i/2] & 0xF0) >> 4;
1695
1696 if (nibble EQ 0xF) /* end of number detected */
1697 break;
1698
1699 /* put nibble */
1700 if (destnibble%2 EQ 0)
1701 {
1702 dest[destnibble/2] &= 0xF0;
1703 dest[destnibble/2] |= nibble;
1704 }
1705 else
1706 {
1707 dest[destnibble/2] &= 0x0F;
1708 dest[destnibble/2] |= nibble << 4;
1709 }
1710
1711 destnibble++;
1712 }
1713 return destnibble/2 + destnibble%2; /* round up */
1714 }
1715 #endif
1716
1717
1718 /*
1719 +---------------------------------------------------------------------+
1720 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1721 | STATE : code ROUTINE: pb_read_ext_cb |
1722 +---------------------------------------------------------------------+
1723
1724
1725 PURPOSE : read sim callback function
1726
1727 */
1728
1729 #ifdef PHONEBOOK_EXTENSION
1730 void pb_read_ext_cb(SHORT table_id)
1731 {
1732 USHORT type_id;
1733 /* UBYTE buf[11];*/
1734 UBYTE data_len;
1735 UBYTE data_type;
1736
1737 TRACE_FUNCTION ("pb_read_ext_cb()");
1738
1739 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
1740
1741 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
1742 {
1743 TRACE_EVENT_P1 ("SIM returned error 0x%04X", simShrdPrm.atb[table_id].errCode);
1744 }
1745 else
1746 {
1747 type_id = simShrdPrm.atb[table_id].reqDataFld;
1748
1749 /* If this extension record is not empty, it is written in phonebook. */
1750 data_type = data[0];
1751 data_len = data[1];
1752 //TISH set extension rcd_bitmap flag
1753 pb_set_ext_record_flag(phb_element[ext_index].type, simShrdPrm.atb[table_id].recNr);
1754
1755 switch (data_type)
1756 {
1757 case 1: /* Called Party Subaddress */
1758 {
1759 int sa_len = 0;
1760 while (sa_len<PHB_PACKED_NUM_LEN) /* get length of possible already stored subaddr if more than one EXT is used */
1761 {
1762 if (phb_element[ext_index].entry.subaddr[sa_len] EQ 0xFF)
1763 break;
1764 else if ((phb_element[ext_index].entry.subaddr[sa_len] & 0xF0) EQ 0xF0)
1765 {
1766 sa_len++;
1767 break;
1768 }
1769 else
1770 sa_len++;
1771 }
1772
1773 pb_nibblecopy (phb_element[ext_index].entry.subaddr,
1774 sa_len,
1775 data + 2,
1776 data_len);
1777 }
1778 break;
1779
1780 case 2: /* Additional data */
1781 phb_element[ext_index].entry.len =
1782 pb_nibblecopy (phb_element[ext_index].entry.number,
1783 phb_element[ext_index].entry.len,
1784 data + 2,
1785 data_len);
1786 break;
1787
1788 default: /* unknown type */
1789 break;
1790 }
1791
1792 if (data[12] != 0xFF) /* check if a further EXT entry exists */
1793 {
1794 if (max_ext_chain_reads) /* limit reached? */
1795 {
1796 max_ext_chain_reads--;
1797 pb_read_sim_ext(type_id, data[12]);
1798 return;
1799 }
1800 }
1801 }
1802
1803 /* Continue reading the last by EXT interrupted phonebook */
1804 pause_pb_reading_while_EXT_reading = FALSE;
1805
1806 if (paused_table_id)
1807 {
1808 simShrdPrm.aId = paused_table_id;
1809 paused_table_id = 0;
1810 if(psaSIM_AccessSIMData() < 0)
1811 {
1812 TRACE_EVENT("FATAL ERROR");
1813 return;
1814 }
1815 }
1816 }
1817 #endif
1818
1819 /*
1820 +--------------------------------------------------------------------+
1821 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1822 | STATE : code ROUTINE: pb_read_eeprom_req |
1823 +--------------------------------------------------------------------+
1824
1825
1826 PURPOSE : Request to build phonebook.
1827
1828 */
1829 T_PHB_RETURN pb_read_eeprom_req(void)
1830 {
1831 UBYTE version;
1832 UBYTE i, n, m;
1833 SHORT index;
1834 USHORT max_rcd;
1835 EF_UPN *efupn;
1836
1837 TRACE_FUNCTION ("pb_read_eeprom_req()");
1838
1839 phb_ctb[ADN_FDN].mem = SIM_MEMORY;
1840 phb_ctb[ADN_FDN].type = ADN_FDN;
1841 if (phb_ctb[ADN].alpha_len)
1842 phb_ctb[ADN_FDN].alpha_len = phb_ctb[ADN].alpha_len;
1843 else
1844 phb_ctb[ADN_FDN].alpha_len = phb_ctb[FDN].alpha_len;
1845
1846 phb_ctb[ADN_FDN].max_rcd = phb_ctb[ADN].max_rcd + phb_ctb[FDN].max_rcd;
1847 phb_ctb[ADN_FDN].used_rcd = phb_ctb[ADN].used_rcd + phb_ctb[FDN].used_rcd;
1848
1849 if (read_flag)
1850 {
1851 phb_stat = PHB_READY;
1852 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE );
1853 return PHB_OK;
1854 }
1855
1856 /* Read Last Dialing Numbers */
1857
1858 if (phb_ctb[LDN].mem EQ NO_PHB_ENTRY) /* No phonebook loaded from SIM? */
1859 {
1860 phb_ctb[LDN].mem = TE_MEMORY;
1861 phb_ctb[LDN].type = LDN;
1862 phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3;
1863 phb_ctb[LDN].used_rcd = 0;
1864 phb_ctb[LDN].first_rcd = UNUSED_INDEX;
1865 phb_ctb[LDN].first_trcd = UNUSED_INDEX;
1866 phb_ctb[LDN].first_nrcd = UNUSED_INDEX;
1867 phb_ctb[LDN].first_mtrcd = UNUSED_INDEX;
1868 phb_ctb[LDN].first_mnrcd = UNUSED_INDEX;
1869 }
1870 else
1871 {
1872 /* either: */
1873 /* phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3;*//* adjust in case SIM_max_record was smaller than PCM_max_rcd */
1874 /* or: */
1875 ; /* use max_rcd as read from SIM. */
1876
1877 }
1878 if (imsiFlag EQ FALSE ) /* SIM has changed? */
1879 {
1880 memset (data, 0xFF, SIZE_EF_LDN);
1881 i=0;
1882 while (i < NR_EF_LDN)
1883 {
1884 if (pcm_WriteRecord((UBYTE *)EF_LDN_ID, /* Wipe entire LDN-PCM */
1885 (USHORT)(i+1),
1886 SIZE_EF_LDN,
1887 data) NEQ DRV_OK)
1888 break;
1889 i++;
1890 }
1891 }
1892 else
1893 { /* Merge timestamp with existing SIM-entries */
1894 BOOL all_records_match = TRUE;
1895 SHORT records_from_sim = phb_ctb[LDN].used_rcd; /* =0 in case of no records from SIM read */
1896 EF_LDN *p = (EF_LDN *)data;
1897
1898 index = phb_ctb[LDN].first_rcd;
1899 for (i=0; i<(UBYTE)phb_ctb[LDN].max_rcd; i++)
1900 {
1901 if ((i+1) > NR_EF_LDN)
1902 break; /* end of phonebook */
1903 if (pcm_ReadRecord((UBYTE *)EF_LDN_ID,
1904 (USHORT)(i+1),
1905 SIZE_EF_LDN,
1906 (UBYTE *)&data[0],
1907 &version,
1908 &max_rcd) NEQ DRV_OK)
1909 break; /* read error */
1910 else
1911 {
1912 if (p->len NEQ 0 AND p->len NEQ 0xFF)
1913 {
1914 if ((i+1) <= records_from_sim)
1915 {
1916 if (index EQ UNUSED_INDEX)
1917 {
1918 all_records_match = FALSE;
1919 break;
1920 }
1921 if ( !memcmp((char *)phb_l_element[index].entry.number, (char *)&p->dldNum, 10)
1922 AND phb_l_element[index].entry.ton_npi EQ p->numTp
1923 AND phb_l_element[index].entry.len EQ p->len
1924 AND phb_l_element[index].entry.cc_id EQ p->ccp) /* Number matches? */
1925 {
1926 pb_copy_ldn_record(index, 0); /* then update the record with Timestamps and cc_id from PCM */
1927 }
1928 else
1929 {
1930 all_records_match = FALSE; /* one (or more) record failed */
1931 break; /* stop processing of further records */
1932 }
1933 index = phb_l_element[index].next_rcd;
1934 }
1935 else /* PCM has more entries than on SIM */
1936 {
1937 /* search a free element in phonebook element table */
1938 if (pb_create_l_memory(&index) NEQ PHB_OK)
1939 return PHB_FULL;
1940
1941 phb_ctb[LDN].used_rcd++;
1942 phb_l_element[index].type = LDN;
1943 phb_l_element[index].entry.index = i+1;
1944
1945 pb_copy_ldn_record((SHORT)index, 0);
1946 pb_l_record_sort(index);
1947 }
1948 }
1949 }
1950 }
1951 if (all_records_match NEQ TRUE) /* some elements did not match */
1952 {
1953 index = phb_ctb[LDN].first_rcd;
1954 for (i=0; i<phb_ctb[LDN].used_rcd; i++)
1955 {
1956 if (index EQ UNUSED_INDEX)
1957 {
1958 break;
1959 }
1960 phb_l_element[index].entry.year =
1961 phb_l_element[index].entry.month =
1962 phb_l_element[index].entry.day =
1963 phb_l_element[index].entry.hour =
1964 phb_l_element[index].entry.minute =
1965 phb_l_element[index].entry.second = 0xFF; /* remove previous merged data from PCM */
1966 index = phb_l_element[index].next_rcd;
1967 }
1968 }
1969 }
1970
1971
1972 /* Read Last received Numbers from EEPROM */
1973 phb_ctb[LRN].mem = TE_MEMORY;
1974 phb_ctb[LRN].type = LRN;
1975 phb_ctb[LRN].max_rcd = MAX_RDM_RECORDS/3;
1976 phb_ctb[LRN].used_rcd = 0;
1977 phb_ctb[LRN].first_rcd = UNUSED_INDEX;
1978 phb_ctb[LRN].first_trcd = UNUSED_INDEX;
1979 phb_ctb[LRN].first_nrcd = UNUSED_INDEX;
1980 phb_ctb[LRN].first_mtrcd = UNUSED_INDEX;
1981 phb_ctb[LRN].first_mnrcd = UNUSED_INDEX;
1982
1983 if (imsiFlag EQ FALSE )
1984 {
1985 memset (data, 0xFF, SIZE_EF_LRN);
1986 i=0;
1987 while (i < NR_EF_LRN)
1988 {
1989 if (pcm_WriteRecord((UBYTE *)EF_LRN_ID, /* Wipe entire LRN-PCM */
1990 (USHORT)(i+1),
1991 SIZE_EF_LRN,
1992 data) NEQ DRV_OK)
1993 break;
1994 i++;
1995 }
1996 }
1997 else
1998 {
1999 EF_LRN *p = (EF_LRN *)data;
2000 for (i=0; i<(UBYTE)phb_ctb[LRN].max_rcd; i++)
2001 {
2002 if ((i+1) > NR_EF_LRN)
2003 break;
2004 if (pcm_ReadRecord((UBYTE *)EF_LRN_ID,
2005 (USHORT)(i+1),
2006 SIZE_EF_LRN,
2007 (UBYTE *)&data[0],
2008 &version,
2009 &max_rcd) NEQ DRV_OK)
2010 break;
2011 else
2012 {
2013 if (p->len NEQ 0 AND p->len NEQ 0xFF)
2014 {
2015 /* search a free element in phonebook element table */
2016 if (pb_create_l_memory(&index) NEQ PHB_OK)
2017 return PHB_FULL;
2018
2019 phb_ctb[LRN].used_rcd++;
2020 phb_l_element[index].type = LRN;
2021 phb_l_element[index].entry.index = i+1;
2022
2023 pb_copy_lrn_record(index, 0);
2024 pb_l_record_sort(index);
2025 }
2026 }
2027 }
2028 }
2029
2030 /* Read Last missed Numbers from EEPROM */
2031 phb_ctb[LMN].mem = TE_MEMORY;
2032 phb_ctb[LMN].type = LMN;
2033 phb_ctb[LMN].max_rcd = MAX_RDM_RECORDS/3;
2034 phb_ctb[LMN].used_rcd = 0;
2035 phb_ctb[LMN].first_rcd = UNUSED_INDEX;
2036 phb_ctb[LMN].first_trcd = UNUSED_INDEX;
2037 phb_ctb[LMN].first_nrcd = UNUSED_INDEX;
2038 phb_ctb[LMN].first_mtrcd = UNUSED_INDEX;
2039 phb_ctb[LMN].first_mnrcd = UNUSED_INDEX;
2040
2041 if (imsiFlag EQ FALSE )
2042 {
2043 memset (data, 0xFF, SIZE_EF_LMN);
2044 i=0;
2045 while (i < NR_EF_LMN)
2046 {
2047 if (pcm_WriteRecord((UBYTE *)EF_LMN_ID, /* Wipe entire LMN-PCM */
2048 (USHORT)(i+1),
2049 SIZE_EF_LMN,
2050 data) NEQ DRV_OK)
2051 break;
2052 i++;
2053 }
2054 }
2055 else
2056 {
2057 EF_LMN *p = (EF_LMN *)data;
2058 for (i=0; i<(UBYTE)phb_ctb[LMN].max_rcd; i++)
2059 {
2060 if ((i+1) > NR_EF_LMN)
2061 break;
2062 if (pcm_ReadRecord((UBYTE *)EF_LMN_ID,
2063 (USHORT)(i+1),
2064 SIZE_EF_LMN,
2065 (UBYTE *)&data[0],
2066 &version,
2067 &max_rcd) NEQ DRV_OK)
2068 break;
2069 else
2070 {
2071 if (p->len NEQ 0 AND p->len NEQ 0xFF)
2072 {
2073 /* search a free element in phonebook element table */
2074 if (pb_create_l_memory(&index) NEQ PHB_OK)
2075 return PHB_FULL;
2076
2077 phb_ctb[LMN].used_rcd++;
2078 phb_l_element[index].type = LMN;
2079 phb_l_element[index].entry.index = i+1;
2080
2081 pb_copy_lmn_record(index, 0);
2082 pb_l_record_sort(index);
2083 }
2084 }
2085 }
2086 }
2087
2088 if (phb_ctb[UPN].mem EQ NO_PHB_ENTRY)
2089 {
2090 phb_ctb[UPN].mem = TE_MEMORY;
2091 phb_ctb[UPN].type = UPN;
2092 phb_ctb[UPN].max_rcd = NR_EF_UPN;
2093 phb_ctb[UPN].used_rcd = 0;
2094 phb_ctb[UPN].first_rcd = UNUSED_INDEX;
2095 phb_ctb[UPN].first_trcd = UNUSED_INDEX;
2096 phb_ctb[UPN].first_nrcd = UNUSED_INDEX;
2097 phb_ctb[UPN].first_mtrcd = UNUSED_INDEX;
2098 phb_ctb[UPN].first_mnrcd = UNUSED_INDEX;
2099
2100 for (i=0; i<NR_EF_UPN; i++)
2101 {
2102 if (pcm_ReadRecord((UBYTE *)EF_UPN_ID,
2103 (USHORT)(i+1),
2104 SIZE_EF_UPN,
2105 (UBYTE *)&data[0],
2106 &version,
2107 &max_rcd) NEQ DRV_OK)
2108 {
2109 phb_ctb[UPN].mem = NO_PHB_ENTRY;
2110 phb_ctb[UPN].max_rcd = 0;
2111 }
2112 else
2113 {
2114 efupn = (EF_UPN *)&data[0];
2115 if (efupn->usrNum[0] NEQ 0xff)
2116 {
2117 /* search a free element in phonebook element table */
2118 if (pb_create_memory(&index) NEQ PHB_OK)
2119 return PHB_FULL;
2120
2121 phb_ctb[UPN].used_rcd++;
2122 n = (UBYTE)i/8;
2123 m = i%8;
2124 phb_ctb[UPN].rcd_bitmap[n] |= 0x01 << m;
2125
2126 phb_element[index].type = UPN;
2127 phb_element[index].entry.index = i+1;
2128
2129 /* copy record */
2130 memset(phb_element[index].entry.tag, 0xFF, sizeof(phb_element[index].entry.tag));
2131 memset(phb_element[index].entry.number, 0xFF, sizeof(phb_element[index].entry.number));
2132 memcpy(phb_element[index].entry.tag,
2133 efupn->alphId,
2134 10*sizeof(UBYTE));
2135 phb_element[index].entry.tag_len = pb_get_entry_len(efupn->alphId, 10);
2136 phb_element[index].entry.len = efupn->len;
2137 phb_element[index].entry.ton_npi = efupn->numTp;
2138 memcpy(phb_element[index].entry.number,
2139 efupn->usrNum,
2140 10*sizeof(UBYTE));
2141 phb_element[index].entry.cc_id = efupn->ccp;
2142
2143 pb_record_sort(index);
2144 pb_alpha_sort(index);
2145 pb_num_sort(index);
2146 }
2147 }
2148 }
2149 }
2150 phb_stat = PHB_READY;
2151 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE );
2152 read_flag = 1;
2153 return PHB_OK;
2154 }
2155
2156
2157 /*
2158 +--------------------------------------------------------------------+
2159 | PROJECT: MMI-Framework (8417) MODULE: PHB |
2160 | STATE : code ROUTINE: pb_read_sim_req |
2161 +--------------------------------------------------------------------+
2162
2163
2164 PURPOSE : Request to build phonebook.
2165
2166 */
2167
2168 void pb_read_sim_req(void)
2169 {
2170 UBYTE serv_stat;
2171
2172 TRACE_FUNCTION("pb_read_sim_req()");
2173
2174 /* Read Fixed Dialing Numbers from SIM card */
2175 if ((serv_stat = pb_ssc(SRV_FDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2176 AND phb_ctb[FDN].mem EQ NO_PHB_ENTRY)
2177 {
2178 phb_ctb[FDN].mem = SIM_MEMORY;
2179 phb_ctb[FDN].type = FDN;
2180 phb_ctb[FDN].service = serv_stat;
2181 pb_read_sim(SIM_FDN, 1, NOT_PRESENT_8BIT);
2182 return;
2183 }
2184
2185 if (read_flag)
2186 {
2187 pb_read_eeprom_req();
2188 return;
2189 }
2190
2191 /* Read MSISDN from SIM card */
2192 if ((serv_stat = pb_ssc(SRV_MSISDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2193 AND phb_ctb[UPN].mem EQ NO_PHB_ENTRY)
2194 {
2195 phb_ctb[UPN].mem = SIM_MEMORY;
2196 phb_ctb[UPN].type = UPN;
2197 phb_ctb[UPN].service = serv_stat;
2198 pb_read_sim(SIM_MSISDN, 1, NOT_PRESENT_8BIT);
2199 return;
2200 }
2201
2202 /* Read Barred Dialing Numbers from SIM card */
2203 if ((serv_stat = pb_ssc(SRV_BDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2204 AND phb_ctb[BDN].mem EQ NO_PHB_ENTRY)
2205 {
2206 phb_ctb[BDN].mem = SIM_MEMORY;
2207 phb_ctb[BDN].type = BDN;
2208 phb_ctb[BDN].service = serv_stat;
2209 pb_read_sim(SIM_BDN, 1, NOT_PRESENT_8BIT);
2210 return;
2211 }
2212
2213 /* Read Service Dialing Numbers from SIM card */
2214 if ((serv_stat = pb_ssc(SRV_SDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2215 AND phb_ctb[SDN].mem EQ NO_PHB_ENTRY)
2216 {
2217 phb_ctb[SDN].mem = SIM_MEMORY;
2218 phb_ctb[SDN].type = SDN;
2219 phb_ctb[SDN].service = serv_stat;
2220 pb_read_sim(SIM_SDN, 1, NOT_PRESENT_8BIT);
2221 return;
2222 }
2223
2224
2225 /* Read Last Numbers Dialed from SIM card */
2226 if ((serv_stat = pb_ssc(SRV_LDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2227 AND phb_ctb[LDN].mem EQ NO_PHB_ENTRY)
2228 {
2229 phb_ctb[LDN].mem = TE_MEMORY;
2230 phb_ctb[LDN].type = LDN;
2231 phb_ctb[LDN].service = serv_stat;
2232 phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3;
2233 phb_ctb[LDN].used_rcd = 0;
2234 phb_ctb[LDN].first_rcd = UNUSED_INDEX;
2235 phb_ctb[LDN].first_trcd = UNUSED_INDEX;
2236 phb_ctb[LDN].first_nrcd = UNUSED_INDEX;
2237 phb_ctb[LDN].first_mtrcd = UNUSED_INDEX;
2238 phb_ctb[LDN].first_mnrcd = UNUSED_INDEX;
2239 pb_read_sim(SIM_LND, 1, NOT_PRESENT_8BIT);
2240 return;
2241 }
2242
2243
2244 #ifdef PHONEBOOK_EXTENSION
2245 /* Read Ext1 Records from SIM card */
2246 if ((serv_stat = pb_ssc(SRV_EXT1,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2247 AND phb_ext_records[EXT1].mem EQ NO_PHB_ENTRY)
2248 {
2249 TRACE_EVENT ("Start reading EXT1");
2250 phb_ext_records[EXT1].mem = SIM_MEMORY;
2251 pb_read_sim(SIM_EXT1, 1, NOT_PRESENT_8BIT);
2252 return;
2253 }
2254
2255 /* Read Ext2 Records from SIM card */
2256 if ((serv_stat = pb_ssc(SRV_EXT2,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2257 AND phb_ext_records[EXT2].mem EQ NO_PHB_ENTRY)
2258 {
2259 TRACE_EVENT ("Start reading EXT2");
2260 phb_ext_records[EXT2].mem = SIM_MEMORY;
2261 pb_read_sim(SIM_EXT2, 1, NOT_PRESENT_8BIT);
2262 return;
2263 }
2264
2265 /* Read Ext3 Records from SIM card */
2266 if ((serv_stat = pb_ssc(SRV_EXT3,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2267 AND phb_ext_records[EXT3].mem EQ NO_PHB_ENTRY)
2268 {
2269 TRACE_EVENT ("Start reading EXT3");
2270 phb_ext_records[EXT3].mem = SIM_MEMORY;
2271 pb_read_sim(SIM_EXT3, 1, NOT_PRESENT_8BIT);
2272 return;
2273 }
2274
2275 /* Read Ext4 Records from SIM card */
2276 if ((serv_stat = pb_ssc(SRV_EXT4,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED
2277 AND phb_ext_records[EXT4].mem EQ NO_PHB_ENTRY)
2278 {
2279 TRACE_EVENT ("Start reading EXT4");
2280 phb_ext_records[EXT4].mem = SIM_MEMORY;
2281 pb_read_sim(SIM_EXT4, 1, NOT_PRESENT_8BIT);
2282 return;
2283 }
2284
2285 #endif
2286
2287 /* Read phonebook from EEPROM */
2288 pb_read_eeprom_req();
2289
2290 #ifdef SIM_TOOLKIT
2291 if (simShrdPrm.fuRef >= 0)
2292 {
2293 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCC_ADD);
2294 }
2295 #endif
2296
2297 }
2298
2299 /*
2300 +--------------------------------------------------------------------+
2301 | PROJECT: MMI-Framework (8417) MODULE: PHB |
2302 | STATE : code ROUTINE: pb_build_req |
2303 +--------------------------------------------------------------------+
2304
2305 PURPOSE : Request to build phonebook.
2306
2307 */
2308
2309 void pb_build_req(T_SIM_MMI_INSERT_IND *sim_mmi_insert_ind)
2310 {
2311 UBYTE simIMSI[MAX_IMSI_LEN+1];
2312 UBYTE pcmIMSI[MAX_IMSI_LEN+1];
2313 EF_IMSI imsi;
2314 UBYTE version;
2315
2316 #ifndef _SIMULATION_
2317 UBYTE classFDN = (UBYTE) CLASS_None;
2318 T_FFS_RET ret_ffs; /* FFS handle */
2319 #endif
2320
2321 TRACE_FUNCTION ("pb_build_req()");
2322
2323 if (fdn_mode EQ NO_OPERATION)
2324 {
2325 /* Read SIM service table from SIM card */
2326 memcpy(sim_service_table, sim_mmi_insert_ind -> sim_serv, MAX_SRV_TBL);
2327
2328 /* Compare IMSI field between SIM and PCM */
2329 imsiFlag = FALSE;
2330 psaSIM_decodeIMSI (sim_mmi_insert_ind->imsi_field.field,
2331 sim_mmi_insert_ind->imsi_field.c_field,
2332 (char *)simIMSI);
2333
2334 if (pcm_ReadFile((UBYTE *) EF_IMSI_ID,SIZE_EF_IMSI,
2335 (UBYTE *) &imsi, &version) EQ PCM_OK)
2336 {
2337 psaSIM_decodeIMSI (imsi.IMSI, imsi.len, (char *)pcmIMSI);
2338 if (!strcmp((char *)simIMSI, (char *)pcmIMSI))
2339 imsiFlag = TRUE;
2340 else
2341 {
2342 /* write the IMSI in PCM */
2343 imsi.len = sim_mmi_insert_ind->imsi_field.c_field;
2344 memcpy(imsi.IMSI, sim_mmi_insert_ind->imsi_field.field, MAX_IMSI-1);
2345 pcm_WriteFile((UBYTE *) EF_IMSI_ID,SIZE_EF_IMSI,
2346 (UBYTE *) &imsi);
2347 }
2348 }
2349
2350 switch (sim_mmi_insert_ind -> func)
2351 {
2352 case SIM_ADN_ENABLED:
2353 case SIM_ADN_BDN_ENABLED:
2354 fdn_mode = FDN_DISABLE;
2355 break;
2356 case SIM_FDN_ENABLED:
2357 case SIM_FDN_BDN_ENABLED:
2358 fdn_mode = FDN_ENABLE;
2359 #ifndef _SIMULATION_
2360 /* read last fdn_classtype from FFS */
2361 ret_ffs = ffs_fread("/mmi/fdnClassType",
2362 &classFDN,
2363 sizeof(classFDN));
2364
2365 if(!(ret_ffs < 1)) /* successful read */
2366 {
2367 /* only these two classes are currently supported */
2368 if ( classFDN EQ (UBYTE) CLASS_VceDatFax OR
2369 classFDN EQ (UBYTE) CLASS_VceDatFaxSms )
2370 {
2371 fdn_classtype = classFDN;
2372 fdn_input_classtype = fdn_classtype;
2373 }
2374 }
2375 #endif
2376 break;
2377 default:
2378 fdn_mode = NO_OPERATION;
2379 break;
2380 }
2381 }
2382 }
2383
2384 /*
2385 +--------------------------------------------------------------------+
2386 | PROJECT: MMI-Framework (8417) MODULE: PHB |
2387 | STATE : code ROUTINE: pb_start_build |
2388 +--------------------------------------------------------------------+
2389
2390 PURPOSE : Start reading the phonebook.
2391
2392 */
2393
2394 T_PHB_RETURN pb_start_build (BOOL unchanged)
2395 {
2396 UBYTE serv_stat;
2397
2398 TRACE_FUNCTION ("pb_start_build()");
2399
2400 read_flag = 0;
2401 phb_stat = PHB_BUSY;
2402 cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, TRUE );
2403
2404 /* Read Abbreviated Dialing Numbers */
2405 if ((serv_stat = pb_ssc(SRV_ADN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED)
2406 {
2407 if (fdn_mode EQ FDN_ENABLE)
2408 {
2409 pb_read_sim_req();
2410 return PHB_OK;
2411 }
2412
2413 if ( phb_ctb[ADN].mem EQ NO_PHB_ENTRY )
2414 {
2415 phb_ctb[ADN].mem = SIM_MEMORY;
2416 phb_ctb[ADN].type = ADN;
2417 phb_ctb[ADN].service = serv_stat;
2418
2419 pb_read_sim(SIM_ADN, 1, NOT_PRESENT_8BIT);
2420 }
2421 else
2422 pb_read_sim_req();
2423 }
2424
2425 else
2426 {
2427 pb_read_sim_req();
2428 }
2429 return PHB_OK;
2430 }
2431
2432 /*
2433 +--------------------------------------------------------------------+
2434 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2435 | STATE : code ROUTINE : pb_update |
2436 +--------------------------------------------------------------------+
2437
2438 PURPOSE : Phonebook update on File Change Notification.
2439
2440 */
2441
2442 #ifdef SIM_TOOLKIT
2443 BOOL pb_update (int ref, T_SIM_FILE_UPDATE_IND *fu)
2444 {
2445 BOOL found = FALSE;
2446 int i;
2447
2448 TRACE_FUNCTION ("pb_update ()");
2449
2450 for (i = 0; i < (int)fu->val_nr; i++)
2451 {
2452 if ( (fu->file_info[i].v_path_info EQ TRUE AND
2453 fu->file_info[i].path_info.df_level1 EQ SIM_DF_TELECOM AND
2454 fu->file_info[i].path_info.v_df_level2 EQ FALSE AND
2455 (fu->file_info[i].datafield EQ SIM_ADN OR /* the extension datafields */
2456 fu->file_info[i].datafield EQ SIM_FDN OR /* have to be added, when */
2457 fu->file_info[i].datafield EQ SIM_BDN OR /* they are really used */
2458 fu->file_info[i].datafield EQ SIM_SDN OR
2459 fu->file_info[i].datafield EQ SIM_MSISDN OR
2460 fu->file_info[i].datafield EQ SIM_LND)) OR /* CQ16301: Added support for LND refresh */
2461
2462 (fu->file_info[i].v_path_info EQ TRUE AND
2463 fu->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND
2464 fu->file_info[i].path_info.v_df_level2 EQ FALSE AND
2465 fu->file_info[i].datafield EQ SIM_SST) )
2466 {
2467 found = TRUE;
2468
2469 /* when SIM service table is changed, the all SIM-phonebooks
2470 will be updated. */
2471 if (fu->file_info[i].datafield EQ SIM_SST)
2472 {
2473 sstUpdateId = TRUE;
2474 break;
2475 }
2476
2477 pb_sat_update_reset(fu->file_info[i].datafield);
2478 }
2479 }
2480
2481 if (found)
2482 {
2483 simShrdPrm.fuRef = ref;
2484 if (sstUpdateId)
2485 {
2486 sstUpdateId = FALSE;
2487
2488 /* Update SIM service table */
2489 if (pb_read_sim_dat(SIM_SST, NOT_PRESENT_8BIT, (UBYTE)256) EQ FALSE )
2490 pb_start_build (FALSE);
2491 }
2492 else
2493 pb_start_build (FALSE);
2494 return FALSE;
2495 }
2496 else
2497 {
2498 simShrdPrm.fuRef = -1; /* no update needed */
2499 return TRUE;
2500 }
2501 }
2502 #endif
2503
2504 /*
2505 +--------------------------------------------------------------------+
2506 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2507 | STATE : code ROUTINE : pb_ssc |
2508 +--------------------------------------------------------------------+
2509
2510 PURPOSE : Check SIM service status.
2511
2512 */
2513
2514 UBYTE pb_ssc (UBYTE nr, UBYTE * serv_table)
2515 {
2516 TRACE_FUNCTION ("pb_ssc()");
2517
2518 if (nr > MAX_SRV_TBL*4)
2519 {
2520 TRACE_ERROR ("serv_table overflow in pb_ssc()");
2521 return NO_ALLOCATED;
2522 }
2523
2524 /* SDN and BDN are not used */
2525 /* if ((nr EQ 18) || (nr EQ31)) */
2526 /* return(NO_ALLOCATED);*/
2527
2528 return ( *(serv_table+(nr-1)/4) >> (((nr-1)&3)*2) & 0x03);
2529 }
2530
2531
2532 /*
2533 +---------------------------------------------------------------------+
2534 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2535 | STATE : code ROUTINE : pb_record_sort |
2536 +---------------------------------------------------------------------+
2537
2538 PURPOSE :
2539
2540 */
2541
2542 void pb_record_sort(SHORT cur_index)
2543 {
2544 SHORT ref_index;
2545 SHORT ptr_index;
2546 UBYTE flag;
2547
2548 /* TRACE_FUNCTION ("pb_record_sort()"); */
2549
2550 if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1)
2551 {
2552 phb_element[cur_index].prev_rcd = UNUSED_INDEX;
2553 phb_element[cur_index].next_rcd = UNUSED_INDEX;
2554 phb_ctb[phb_element[cur_index].type].first_rcd = cur_index;
2555 }
2556 else
2557 {
2558 flag = 0;
2559
2560 ref_index = phb_ctb[phb_element[cur_index].type].first_rcd;
2561 phb_ctb[phb_element[cur_index].type].first_rcd = cur_index;
2562
2563 phb_element[cur_index].prev_rcd = UNUSED_INDEX;
2564 phb_element[cur_index].next_rcd = ref_index;
2565 phb_element[ref_index].prev_rcd = cur_index;
2566
2567 while (ref_index NEQ UNUSED_INDEX)
2568 {
2569 if (phb_element[cur_index].entry.index > phb_element[ref_index].entry.index)
2570 {
2571 ptr_index = phb_element[ref_index].next_rcd;
2572 if (ptr_index != UNUSED_INDEX)
2573 phb_element[ptr_index].prev_rcd = cur_index;
2574 phb_element[cur_index].next_rcd = ptr_index;
2575
2576 ptr_index = phb_element[cur_index].prev_rcd;
2577 if (ptr_index != UNUSED_INDEX)
2578 phb_element[ptr_index].next_rcd = ref_index;
2579
2580 phb_element[ref_index].prev_rcd = phb_element[cur_index].prev_rcd;
2581 phb_element[ref_index].next_rcd = cur_index;
2582 phb_element[cur_index].prev_rcd = ref_index;
2583
2584 /* set the first record in control block */
2585 if(!flag)
2586 {
2587 phb_ctb[phb_element[cur_index].type].first_rcd = ref_index;
2588 flag = 1;
2589 }
2590 ref_index = phb_element[cur_index].next_rcd;
2591 }
2592
2593 else
2594 ref_index = phb_element[ref_index].next_rcd;
2595 }
2596 }
2597 }
2598
2599
2600 /*
2601 +---------------------------------------------------------------------+
2602 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2603 | STATE : code ROUTINE : pb_l_record_sort |
2604 +---------------------------------------------------------------------+
2605
2606 PURPOSE :
2607
2608 */
2609
2610 void pb_l_record_sort(SHORT cur_index)
2611 {
2612 SHORT ref_index;
2613 SHORT ptr_index;
2614 UBYTE flag;
2615
2616 TRACE_FUNCTION ("pb_l_record_sort()");
2617
2618 if (phb_ctb[phb_l_element[cur_index].type].used_rcd EQ 1)
2619 {
2620 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
2621 phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX;
2622 phb_ctb[phb_l_element[cur_index].type].first_rcd = cur_index;
2623 }
2624 else
2625 {
2626 flag = 0;
2627
2628 ref_index = phb_ctb[phb_l_element[cur_index].type].first_rcd;
2629 phb_ctb[phb_l_element[cur_index].type].first_rcd = cur_index;
2630
2631 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
2632 phb_l_element[cur_index].next_rcd = (UBYTE)ref_index;
2633 phb_l_element[ref_index].prev_rcd = (UBYTE)cur_index;
2634
2635 while ((UBYTE)ref_index NEQ UNUSED_BYTE_INDEX)
2636 {
2637 if (phb_l_element[cur_index].entry.index > phb_l_element[ref_index].entry.index)
2638 {
2639 ptr_index = (SHORT)phb_l_element[ref_index].next_rcd;
2640 if ((UBYTE)ptr_index != UNUSED_BYTE_INDEX)
2641 phb_l_element[ptr_index].prev_rcd = (UBYTE)cur_index;
2642 phb_l_element[cur_index].next_rcd = (UBYTE)ptr_index;
2643
2644 ptr_index = (SHORT)phb_l_element[cur_index].prev_rcd;
2645 if ((UBYTE)ptr_index != UNUSED_BYTE_INDEX)
2646 phb_l_element[ptr_index].next_rcd = (UBYTE)ref_index;
2647
2648 phb_l_element[ref_index].prev_rcd = phb_l_element[cur_index].prev_rcd;
2649 phb_l_element[ref_index].next_rcd = (UBYTE)cur_index;
2650 phb_l_element[cur_index].prev_rcd = (UBYTE)ref_index;
2651
2652 /* set the first record in control block */
2653 if(!flag)
2654 {
2655 phb_ctb[phb_l_element[cur_index].type].first_rcd = ref_index;
2656 flag = 1;
2657 }
2658 ref_index = (SHORT)phb_l_element[cur_index].next_rcd;
2659 }
2660
2661 else
2662 ref_index = (SHORT)phb_l_element[ref_index].next_rcd;
2663 }
2664 }
2665 }
2666
2667
2668 /*
2669 +---------------------------------------------------------------------+
2670 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2671 | STATE : code ROUTINE : pb_cvt_alpha_for_cmp |
2672 +---------------------------------------------------------------------+
2673
2674 PURPOSE : convert alpha to lower case when not unicode
2675
2676 */
2677 static void pb_cvt_alpha_for_cmp ( UBYTE *src,
2678 UBYTE *dst,
2679 UBYTE len )
2680 {
2681 int i;
2682
2683 if ( *src NEQ 0x80 )
2684 {
2685 for ( i = 0; i < len; i++ )
2686 dst[i] = (UBYTE)tolower((int)src[i]);
2687
2688 return;
2689 }
2690
2691 for ( i = 0; i < len; i++ )
2692 dst[i] = src[i];
2693 }
2694
2695 /*
2696 +---------------------------------------------------------------------+
2697 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2698 | STATE : code ROUTINE : pb_alpha_sort |
2699 +---------------------------------------------------------------------+
2700
2701 PURPOSE : Insert a new record to alpha sorted chain.
2702
2703 */
2704
2705 void pb_alpha_sort(SHORT cur_index)
2706 {
2707 SHORT ref_index;
2708 SHORT ptr_index;
2709 UBYTE flag, cmpLen = 0;
2710 UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN];
2711 int cmp_res;
2712
2713 /* set the new record as first element */
2714 if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1)
2715 {
2716 phb_element[cur_index].prev_trcd = UNUSED_INDEX;
2717 phb_element[cur_index].next_trcd = UNUSED_INDEX;
2718
2719 phb_ctb[phb_element[cur_index].type].first_trcd = cur_index;
2720 }
2721
2722 if (phb_ctb[phb_element[cur_index].type].used_rcd > 1)
2723 {
2724 ref_index = phb_ctb[phb_element[cur_index].type].first_trcd;
2725 phb_ctb[phb_element[cur_index].type].first_trcd = cur_index;
2726
2727 phb_element[cur_index].prev_trcd = UNUSED_INDEX;
2728 phb_element[cur_index].next_trcd = ref_index;
2729 phb_element[ref_index].prev_trcd = cur_index;
2730
2731 /* insert the new record in the alpha order */
2732 flag = 0;
2733 while (ref_index NEQ UNUSED_INDEX)
2734 {
2735 memset(cur_tag, 0, sizeof ( cur_tag ) );
2736 memset(check_tag, 0, sizeof ( check_tag ) );
2737
2738 /*
2739 this should not cause problems, because in both alphabets
2740 (GSM and ASCII) the most important chars are at the same
2741 positions (A-Z: 65-90 a-z:97-122)
2742 */
2743
2744 if( ext_compare_fct != NULL )
2745 {
2746 cmp_res = ext_compare_fct ( phb_element[cur_index].entry.tag,
2747 phb_element[cur_index].entry.tag_len,
2748 phb_element[ref_index].entry.tag,
2749 phb_element[ref_index].entry.tag_len );
2750 }
2751 else
2752 {
2753 pb_cvt_alpha_for_cmp ( phb_element[cur_index].entry.tag,
2754 cur_tag,
2755 phb_element[cur_index].entry.tag_len );
2756 pb_cvt_alpha_for_cmp ( phb_element[ref_index].entry.tag,
2757 check_tag,
2758 phb_element[ref_index].entry.tag_len );
2759 cmpLen = MINIMUM ( phb_element[cur_index].entry.tag_len,
2760 phb_element[ref_index].entry.tag_len );
2761
2762 cmp_res = cmpString ( cur_tag, check_tag, cmpLen );
2763 }
2764
2765 if (cmp_res EQ 0) /* MINIMUM character match, so check if one string is longer */
2766 { /* ABC should come after AB */
2767 if (phb_element[cur_index].entry.tag_len NEQ phb_element[ref_index].entry.tag_len)
2768 {
2769 if ((phb_element[cur_index].entry.tag_len - phb_element[ref_index].entry.tag_len) > 0)
2770 cmp_res = cmpLen + 1;
2771 else
2772 cmp_res = -cmpLen - 1;
2773 }
2774 }
2775
2776 if(cmp_res > 0)
2777 {
2778 ptr_index = phb_element[ref_index].next_trcd;
2779 if (ptr_index != UNUSED_INDEX)
2780 {
2781 phb_element[ptr_index].prev_trcd = cur_index;
2782 }
2783 phb_element[cur_index].next_trcd = ptr_index;
2784
2785 ptr_index = phb_element[cur_index].prev_trcd;
2786 if (ptr_index != UNUSED_INDEX)
2787 {
2788 phb_element[ptr_index].next_trcd = ref_index;
2789 }
2790
2791 phb_element[ref_index].prev_trcd = phb_element[cur_index].prev_trcd;
2792 phb_element[ref_index].next_trcd = cur_index;
2793 phb_element[cur_index].prev_trcd = ref_index;
2794
2795 /* set the first record in control block */
2796 if(!flag)
2797 {
2798 phb_ctb[phb_element[cur_index].type].first_trcd = ref_index;
2799 flag = 1;
2800 }
2801 ref_index = phb_element[cur_index].next_trcd;
2802 }
2803 else
2804 {
2805 ref_index = phb_element[ref_index].next_trcd;
2806 }
2807 }
2808 }
2809 }
2810
2811
2812 /*
2813 +---------------------------------------------------------------------+
2814 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2815 | STATE : code ROUTINE : pb_num_sort |
2816 +---------------------------------------------------------------------+
2817
2818 PURPOSE :
2819
2820 */
2821
2822 void pb_num_sort(SHORT cur_index)
2823 {
2824 SHORT ref_index;
2825 SHORT ptr_index;
2826 UBYTE flag;
2827 CHAR cur_number[MAX_PHB_NUM_LEN];
2828 CHAR ref_number[MAX_PHB_NUM_LEN];
2829
2830 /* TRACE_FUNCTION ("pb_num_sort()");*/
2831
2832 /* set the new record as first element */
2833 if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1)
2834 {
2835 phb_element[cur_index].prev_nrcd = UNUSED_INDEX;
2836 phb_element[cur_index].next_nrcd = UNUSED_INDEX;
2837
2838 phb_ctb[phb_element[cur_index].type].first_nrcd = cur_index;
2839 }
2840
2841 if (phb_ctb[phb_element[cur_index].type].used_rcd > 1)
2842 {
2843 ref_index = phb_ctb[phb_element[cur_index].type].first_nrcd;
2844 phb_ctb[phb_element[cur_index].type].first_nrcd = cur_index;
2845
2846 phb_element[cur_index].prev_nrcd = UNUSED_INDEX;
2847 phb_element[cur_index].next_nrcd = ref_index;
2848 phb_element[ref_index].prev_nrcd = cur_index;
2849
2850 /* insert the new record in the number order */
2851 flag = 0;
2852 while (ref_index NEQ UNUSED_INDEX)
2853 {
2854 /* convert the number in BCD to string */
2855 cmhPHB_getAdrStr(cur_number,
2856 MAX_PHB_NUM_LEN - 1,
2857 phb_element[cur_index].entry.number,
2858 phb_element[cur_index].entry.len);
2859 cmhPHB_getAdrStr(ref_number,
2860 MAX_PHB_NUM_LEN - 1,
2861 phb_element[ref_index].entry.number,
2862 phb_element[ref_index].entry.len);
2863
2864 if (strcmp((char *)cur_number, (char *)ref_number) > 0)
2865 {
2866 ptr_index = phb_element[ref_index].next_nrcd;
2867 if (ptr_index != UNUSED_INDEX)
2868 phb_element[ptr_index].prev_nrcd = cur_index;
2869 phb_element[cur_index].next_nrcd = ptr_index;
2870
2871 ptr_index = phb_element[cur_index].prev_nrcd;
2872 if (ptr_index != UNUSED_INDEX)
2873 phb_element[ptr_index].next_nrcd = ref_index;
2874
2875 phb_element[ref_index].prev_nrcd = phb_element[cur_index].prev_nrcd;
2876 phb_element[ref_index].next_nrcd = cur_index;
2877 phb_element[cur_index].prev_nrcd = ref_index;
2878
2879 /* set the first logic number record in control block */
2880 if(!flag)
2881 {
2882 phb_ctb[phb_element[cur_index].type].first_nrcd = ref_index;
2883 flag = 1;
2884 }
2885 ref_index = phb_element[cur_index].next_nrcd;
2886 }
2887 else
2888 {
2889 ref_index = phb_element[ref_index].next_nrcd;
2890 }
2891 }
2892 }
2893 }
2894
2895
2896 /*
2897 +---------------------------------------------------------------------+
2898 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2899 | STATE : code ROUTINE : pb_malpha_sort |
2900 +---------------------------------------------------------------------+
2901
2902 PURPOSE : Insert a new record to alpha sorted chain.
2903
2904 */
2905
2906 void pb_malpha_sort(SHORT cur_index)
2907 {
2908 SHORT ref_index;
2909 SHORT ptr_index;
2910 UBYTE flag, cmpLen = 0;
2911 UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN];
2912 int cmp_res;
2913
2914 if (((phb_ctb[ADN].used_rcd EQ 1) AND (phb_ctb[FDN].used_rcd EQ 0))
2915 OR ((phb_ctb[ADN].used_rcd EQ 0) AND (phb_ctb[FDN].used_rcd EQ 1)))
2916 {
2917 phb_element[cur_index].prev_mtrcd = UNUSED_INDEX;
2918 phb_element[cur_index].next_mtrcd = UNUSED_INDEX;
2919
2920 phb_ctb[phb_element[cur_index].type].first_mtrcd = cur_index;
2921 return;
2922 }
2923 else
2924 {
2925 if (phb_ctb[ADN].used_rcd NEQ 0)
2926 {
2927 /* Test whether ADN's first_mtrcd index is already in use or not.
2928 If not and FDN entries exist, take FDN's first_mtrcd. */
2929 if ((phb_ctb[ADN].first_mtrcd EQ UNUSED_INDEX) AND (phb_ctb[FDN].used_rcd NEQ 0))
2930 ref_index = phb_ctb[FDN].first_mtrcd;
2931 else
2932 ref_index = phb_ctb[ADN].first_mtrcd;
2933
2934 phb_ctb[ADN].first_mtrcd = cur_index;
2935 }
2936 else
2937 {
2938 ref_index = phb_ctb[FDN].first_mtrcd;
2939 phb_ctb[FDN].first_mtrcd = cur_index;
2940 }
2941 }
2942
2943 phb_element[cur_index].prev_mtrcd = UNUSED_INDEX;
2944 phb_element[cur_index].next_mtrcd = ref_index;
2945 phb_element[ref_index].prev_mtrcd = cur_index;
2946
2947 /* insert the new record in the alpha order */
2948 flag = 0;
2949 while (ref_index NEQ UNUSED_INDEX)
2950 {
2951 memset(cur_tag, 0, sizeof ( cur_tag ) );
2952 memset(check_tag, 0, sizeof ( check_tag ) );
2953
2954 /*
2955 this should not cause problems, because in both alphabets
2956 (GSM and ASCII) the most important chars are at the same
2957 positions (A-Z: 65-90 a-z:97-122)
2958 */
2959 if( ext_compare_fct != NULL )
2960 {
2961 cmp_res = ext_compare_fct ( phb_element[cur_index].entry.tag,
2962 phb_element[cur_index].entry.tag_len,
2963 phb_element[ref_index].entry.tag,
2964 phb_element[ref_index].entry.tag_len );
2965 }
2966 else
2967 {
2968 pb_cvt_alpha_for_cmp ( phb_element[cur_index].entry.tag,
2969 cur_tag,
2970 phb_element[cur_index].entry.tag_len );
2971 pb_cvt_alpha_for_cmp ( phb_element[ref_index].entry.tag,
2972 check_tag,
2973 phb_element[ref_index].entry.tag_len );
2974 cmpLen = MINIMUM ( phb_element[cur_index].entry.tag_len,
2975 phb_element[ref_index].entry.tag_len );
2976
2977 cmp_res = cmpString ( cur_tag, check_tag, cmpLen );
2978 }
2979
2980 if (cmp_res EQ 0) /* MINIMUM character match, so check if one string is longer */
2981 { /* ABC should come after AB */
2982 if (phb_element[cur_index].entry.tag_len NEQ phb_element[ref_index].entry.tag_len)
2983 {
2984 if ((phb_element[cur_index].entry.tag_len - phb_element[ref_index].entry.tag_len) > 0)
2985 cmp_res = cmpLen + 1;
2986 else
2987 cmp_res = -cmpLen - 1;
2988 }
2989 }
2990
2991 if (cmp_res > 0)
2992 {
2993 ptr_index = phb_element[ref_index].next_mtrcd;
2994 if (ptr_index != UNUSED_INDEX)
2995 phb_element[ptr_index].prev_mtrcd = cur_index;
2996 phb_element[cur_index].next_mtrcd = ptr_index;
2997
2998 ptr_index = phb_element[cur_index].prev_mtrcd;
2999 if (ptr_index != UNUSED_INDEX)
3000 phb_element[ptr_index].next_mtrcd = ref_index;
3001
3002 phb_element[ref_index].prev_mtrcd = phb_element[cur_index].prev_mtrcd;
3003 phb_element[ref_index].next_mtrcd = cur_index;
3004 phb_element[cur_index].prev_mtrcd = ref_index;
3005
3006 /* set the first record in control block */
3007 if(!flag)
3008 {
3009 if (phb_ctb[ADN].used_rcd != 0)
3010 phb_ctb[ADN].first_mtrcd = ref_index;
3011 else
3012 phb_ctb[FDN].first_mtrcd = ref_index;
3013
3014 flag = 1;
3015 }
3016 ref_index = phb_element[cur_index].next_mtrcd;
3017 }
3018 else
3019 ref_index = phb_element[ref_index].next_mtrcd;
3020 }
3021 }
3022
3023
3024 /*
3025 +---------------------------------------------------------------------+
3026 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3027 | STATE : code ROUTINE : pb_mnum_sort |
3028 +---------------------------------------------------------------------+
3029
3030 PURPOSE :
3031
3032 */
3033
3034 void pb_mnum_sort(SHORT cur_index)
3035 {
3036 SHORT ref_index;
3037 SHORT ptr_index;
3038 UBYTE flag;
3039 CHAR cur_number[MAX_PHB_NUM_LEN];
3040 CHAR ref_number[MAX_PHB_NUM_LEN];
3041
3042 /* TRACE_FUNCTION ("pb_num_sort()");*/
3043
3044 if (((phb_ctb[ADN].used_rcd EQ 1) AND (phb_ctb[FDN].used_rcd EQ 0))
3045 OR ((phb_ctb[ADN].used_rcd EQ 0) AND (phb_ctb[FDN].used_rcd EQ 1)))
3046 {
3047 phb_element[cur_index].prev_mnrcd = UNUSED_INDEX;
3048 phb_element[cur_index].next_mnrcd = UNUSED_INDEX;
3049
3050 phb_ctb[phb_element[cur_index].type].first_mnrcd = cur_index;
3051 return;
3052 }
3053 else
3054 {
3055 if (phb_ctb[ADN].used_rcd != 0)
3056 {
3057 /* Test whether ADN's first_mtrcd index is already in use or not.
3058 If not and FDN entries exist, take FDN's first_mtrcd. */
3059 if ((phb_ctb[ADN].first_mnrcd EQ UNUSED_INDEX) AND (phb_ctb[FDN].used_rcd NEQ 0))
3060 ref_index = phb_ctb[FDN].first_mnrcd;
3061 else
3062 ref_index = phb_ctb[ADN].first_mnrcd;
3063
3064 phb_ctb[ADN].first_mnrcd = cur_index;
3065 }
3066 else
3067 {
3068 ref_index = phb_ctb[FDN].first_mnrcd;
3069 phb_ctb[FDN].first_mnrcd = cur_index;
3070 }
3071 }
3072
3073 phb_element[cur_index].prev_mnrcd = UNUSED_INDEX;
3074 phb_element[cur_index].next_mnrcd = ref_index;
3075 phb_element[ref_index].prev_mnrcd = cur_index;
3076
3077 /* insert the new record in the number order */
3078 flag = 0;
3079 while (ref_index NEQ UNUSED_INDEX)
3080 {
3081 /* convert the number in BCD to string */
3082 cmhPHB_getAdrStr(cur_number,
3083 MAX_PHB_NUM_LEN - 1,
3084 phb_element[cur_index].entry.number,
3085 phb_element[cur_index].entry.len);
3086 cmhPHB_getAdrStr(ref_number,
3087 MAX_PHB_NUM_LEN - 1,
3088 phb_element[ref_index].entry.number,
3089 phb_element[ref_index].entry.len);
3090
3091 if (strcmp((char *)cur_number, (char *)ref_number) > 0)
3092 {
3093 ptr_index = phb_element[ref_index].next_mnrcd;
3094 if (ptr_index != UNUSED_INDEX)
3095 phb_element[ptr_index].prev_mnrcd = cur_index;
3096 phb_element[cur_index].next_mnrcd = ptr_index;
3097
3098 ptr_index = phb_element[cur_index].prev_mnrcd;
3099 if (ptr_index != UNUSED_INDEX)
3100 phb_element[ptr_index].next_mnrcd = ref_index;
3101
3102 phb_element[ref_index].prev_mnrcd = phb_element[cur_index].prev_mnrcd;
3103 phb_element[ref_index].next_mnrcd = cur_index;
3104 phb_element[cur_index].prev_mnrcd = ref_index;
3105
3106 /* set the first logic number record in control block */
3107 if(!flag)
3108 {
3109 if (phb_ctb[ADN].used_rcd != 0)
3110 phb_ctb[ADN].first_mnrcd = ref_index;
3111 else
3112 phb_ctb[FDN].first_mnrcd = ref_index;
3113 flag = 1;
3114 }
3115 ref_index = phb_element[cur_index].next_mnrcd;
3116 }
3117 else
3118 ref_index = phb_element[ref_index].next_mnrcd;
3119 }
3120 }
3121
3122
3123 /*
3124 +---------------------------------------------------------------------+
3125 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3126 | STATE : code ROUTINE : pb_add_record |
3127 +---------------------------------------------------------------------+
3128
3129 PURPOSE :
3130
3131 */
3132
3133 T_PHB_RETURN pb_add_record(UBYTE type, UBYTE index, T_PHB_RECORD *entry)
3134 {
3135 UBYTE bit = 0;
3136 UBYTE tag_len;
3137 SHORT new_index;
3138 SHORT cur_index;
3139 SHORT first_id;
3140 SHORT result;
3141 T_PHB_RECORD found_entry;
3142 UBYTE n,m;
3143 UBYTE number[MAX_PHB_NUM_LEN];
3144 T_PHB_RETURN sim_result;
3145 UBYTE old_ext_rcd_num = 0xFF;
3146 int entrylen;
3147 #ifdef PHONEBOOK_EXTENSION
3148 USHORT file_id = 0;
3149 #endif
3150
3151 TRACE_FUNCTION ("pb_add_record()");
3152
3153 /* check whether this phonebook exists */
3154 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3155 return PHB_FAIL;
3156
3157 if (type EQ ECC
3158 OR type EQ ADN
3159 OR type EQ FDN
3160 OR type EQ BDN
3161 OR type EQ UPN)
3162 {
3163 /* Phonebook is full. */
3164 if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd AND !index)
3165 {
3166 return PHB_FULL;
3167 }
3168
3169 //TI-SH-TEST-PATCH for CSR OMAPS00168884
3170 tag_len = entry->tag_len;//pb_get_entry_len( entry->tag, PHB_MAX_TAG_LEN );
3171 /* tag_len = MINIMUM ( tag_len, phb_ctb[type].alpha_len); */
3172 /* Don't truncate a tag if it does not fit onto SIM but raise an error */
3173 if (tag_len > phb_ctb[type].alpha_len)
3174 {
3175 return PHB_TAG_EXCEEDED;
3176 }
3177
3178 /* Search the free record number for this record */
3179 if (!index)
3180 {
3181 T_PHB_RETURN ret;
3182 SHORT first_free;
3183
3184 switch (type)
3185 {
3186 case ADN:
3187 case FDN:
3188 case BDN:
3189 case UPN:
3190 /*
3191 * Use the function pb_first_free() to determine
3192 * the index of the first free record.
3193 */
3194 ret=pb_first_free(type,&first_free);
3195
3196 /*
3197 * Get out if there was a problem, or the phonebook
3198 * is full.
3199 */
3200 if (ret NEQ PHB_OK)
3201 return(ret);
3202
3203 bit=(UBYTE)(first_free-1);
3204 break;
3205
3206 default:
3207 bit=0;
3208 }
3209 }
3210
3211 /* Delete the information in the record, in order to overwrite */
3212 if (index)
3213 {
3214 bit = index - 1;
3215 pb_delete_record(type, index, &old_ext_rcd_num, FALSE);
3216 }
3217
3218 /* search a free element in phonebook element table */
3219 if (pb_create_memory(&new_index) NEQ PHB_OK)
3220 return PHB_FULL;
3221 phb_element[new_index].type = type;
3222 #ifdef PHONEBOOK_EXTENSION
3223 phb_element[new_index].entry.ext_rcd_num = 0xFF;
3224 #endif
3225 phb_ctb[type].used_rcd++;
3226
3227 if (type EQ ADN OR type EQ FDN)
3228 phb_ctb[ADN_FDN].used_rcd++;
3229 n = (UBYTE)bit/8;
3230 m = bit%8;
3231 phb_ctb[type].rcd_bitmap[n] |= 0x01 << m;
3232 phb_element[new_index].entry.index = bit + 1;
3233
3234 /* Copy entry */
3235 phb_element[new_index].entry.tag_len = tag_len;
3236 phb_element[new_index].entry.len = entry->len;
3237 phb_element[new_index].entry.ton_npi = entry->ton_npi;
3238 memset(phb_element[new_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN);
3239 memcpy((char *)phb_element[new_index].entry.tag,
3240 (char *)entry->tag,
3241 tag_len);
3242 memcpy((char *)phb_element[new_index].entry.number,
3243 (char *)entry->number,
3244 PHB_PACKED_NUM_LEN); /* allow number (10 bytes) + a extension (11 bytes) */
3245 #ifdef PHONEBOOK_EXTENSION
3246 memcpy((char *)phb_element[new_index].entry.subaddr,
3247 (char *)entry->subaddr, PHB_PACKED_NUM_LEN);
3248 #endif
3249 phb_element[new_index].entry.cc_id = entry->cc_id;
3250
3251 pb_record_sort(new_index);
3252 pb_alpha_sort(new_index);
3253 pb_num_sort(new_index);
3254
3255 if ((type EQ ADN) OR (type EQ FDN))
3256 {
3257 pb_malpha_sort(new_index);
3258 pb_mnum_sort(new_index);
3259 }
3260
3261 if (phb_ctb[type].mem EQ SIM_MEMORY)
3262 {
3263 /* write this record in SIM card */
3264 memset(data, 0xFF, sizeof(data));
3265 memcpy(data, entry->tag, tag_len);
3266
3267 #if PHONEBOOK_EXTENSION
3268 if (entry->number[10] != 0xFF)
3269 {
3270 data[phb_ctb[type].alpha_len] = 11; /* max. length */
3271 }
3272 else
3273 {
3274 data[phb_ctb[type].alpha_len] = entry->len+1;
3275 }
3276 #else
3277 data[phb_ctb[type].alpha_len] = entry->len+1;
3278 #endif
3279 data[phb_ctb[type].alpha_len+1] = entry->ton_npi;
3280 memcpy((char *)&data[phb_ctb[type].alpha_len+2],
3281 (char *)entry->number, 10);
3282 data[phb_ctb[type].alpha_len+12] = entry->cc_id;
3283
3284 #ifdef PHONEBOOK_EXTENSION
3285 if (entry->number[10] != 0xFF)
3286 {
3287 file_id = pb_get_ext_file_id (type);
3288 if (old_ext_rcd_num NEQ 0xFF)
3289 {
3290 /* use the old extention record */
3291 phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num;
3292 }
3293 else
3294 {
3295 phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (type);
3296 }
3297
3298 /* Not able to find free record in extension file */
3299 if(phb_element[new_index].entry.ext_rcd_num EQ 0xff)
3300 {
3301 /* Free the used record for normal phonebook
3302 * since unable to find free record for extension data */
3303 pb_free_used_record(type, new_index, bit);
3304
3305 return PHB_EXT_FULL;
3306 }
3307
3308 data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num;
3309 }
3310 /* only number extention or subaddress could be store */
3311 else if (entry->subaddr[0] NEQ 0xFF)
3312 {
3313 file_id = pb_get_ext_file_id (type);
3314 if (old_ext_rcd_num NEQ 0xFF)
3315 {
3316 /* use the old extention record */
3317 phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num;
3318 }
3319 else
3320 {
3321 phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (0xFF);
3322 }
3323
3324 /* Not able to find free record in extension file */
3325 if(phb_element[new_index].entry.ext_rcd_num EQ 0xff)
3326 {
3327 /* Free the used record for normal phonebook
3328 * since unable to find free record for extension data */
3329 pb_free_used_record(type, new_index, bit);
3330
3331 return PHB_EXT_FULL;
3332 }
3333
3334 data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num;
3335 }
3336 #endif
3337 sim_result = pb_write_sim(type, phb_element[new_index].entry.index);
3338 #ifdef PHONEBOOK_EXTENSION
3339 if (sim_result NEQ PHB_FAIL)
3340 {
3341 if (phb_element[new_index].entry.ext_rcd_num != 0xFF)
3342 {
3343 pb_prepare_ext_data (phb_element[new_index].entry.number,
3344 phb_element[new_index].entry.len,
3345 phb_element[new_index].entry.subaddr,
3346 10,
3347 file_id);
3348 sim_result = pb_write_sim_ext(file_id, phb_element[new_index].entry.ext_rcd_num);
3349 //TISH set ext record flag
3350 if(sim_result NEQ PHB_FAIL)
3351 pb_set_ext_record_flag(type, phb_element[new_index].entry.ext_rcd_num);
3352
3353 }
3354 else if (old_ext_rcd_num NEQ 0xFF)
3355 {
3356 /* delete the old extention record */
3357 pb_rem_ext_record_flag (type, old_ext_rcd_num);
3358 pb_prepare_ext_data (NULL, 0, NULL, 0, file_id);
3359 sim_result = pb_write_sim_ext(SIM_EXT1, old_ext_rcd_num);
3360 }
3361 }
3362 #endif /* PHONEBOOK_EXTENSION */
3363 return(sim_result);
3364 }
3365 return PHB_OK;
3366 }
3367
3368 else if ((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN))
3369 {
3370 cmhPHB_getAdrStr((char *)number,
3371 MAX_PHB_NUM_LEN - 1,
3372 entry->number,
3373 entry->len);
3374 if (pb_search_number(type, number, PHB_NEW_SEARCH,
3375 &first_id, &result, &found_entry) EQ PHB_OK)
3376 {
3377 if (result)
3378 pb_delete_record(type, (UBYTE)found_entry.index, &old_ext_rcd_num, FALSE);
3379 }
3380
3381 if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd)
3382 {
3383 if ((cur_index = phb_ctb[type].first_rcd) EQ UNUSED_INDEX)
3384 return PHB_FAIL;
3385
3386 while (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX)
3387 cur_index = phb_l_element[cur_index].next_rcd;
3388 if (phb_l_element[cur_index].prev_rcd != UNUSED_BYTE_INDEX)
3389 phb_l_element[phb_l_element[cur_index].prev_rcd].next_rcd = UNUSED_BYTE_INDEX;
3390 }
3391
3392 else
3393 {
3394 if (pb_create_l_memory(&new_index) NEQ PHB_OK)
3395 return PHB_FAIL;
3396 phb_ctb[type].used_rcd++;
3397 cur_index = new_index;
3398 }
3399
3400 phb_l_element[cur_index].type = type;
3401
3402 /* copy record */
3403 /* if ((type EQ LDN) OR (type EQ LRN)) */
3404 /* copy call duration - not jet done */
3405 /* if ((type EQ LRN) OR (type EQ LMN)) */
3406 /* copy call identifier - not jet done */
3407
3408 memcpy((char *)phb_l_element[cur_index].entry.tag,
3409 (char *)entry->tag,
3410 PHB_MAX_TAG_LEN);
3411 phb_l_element[cur_index].entry.tag_len = entry->tag_len;
3412
3413 phb_l_element[cur_index].entry.year = entry->year;
3414 phb_l_element[cur_index].entry.month = entry->month;
3415 phb_l_element[cur_index].entry.day = entry->day;
3416 phb_l_element[cur_index].entry.hour = entry->hour;
3417 phb_l_element[cur_index].entry.minute = entry->minute;
3418 phb_l_element[cur_index].entry.second = entry->second;
3419 phb_l_element[cur_index].entry.len = entry->len;
3420 phb_l_element[cur_index].entry.ton_npi = entry->ton_npi;
3421 phb_l_element[cur_index].entry.line = entry->line;
3422 memcpy((char *)phb_l_element[cur_index].entry.number,
3423 (char *)entry->number,
3424 PHB_PACKED_NUM_LEN);
3425 phb_l_element[cur_index].entry.cc_id = entry->cc_id;
3426
3427 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
3428 if (phb_ctb[type].first_rcd EQ cur_index)
3429 {
3430 phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX;
3431 }
3432 else
3433 {
3434 phb_l_element[cur_index].next_rcd = (UBYTE)phb_ctb[type].first_rcd;
3435 }
3436
3437 /* If it is -1, gardening ! This is possible for the 1rst time a entry is added ??? */
3438 if (phb_ctb[type].first_rcd != UNUSED_BYTE_INDEX)
3439 {
3440 phb_l_element[phb_ctb[type].first_rcd].prev_rcd = (UBYTE)cur_index;
3441 }
3442
3443 phb_ctb[type].first_rcd = cur_index;
3444
3445 new_index = 1;
3446 while (cur_index NEQ UNUSED_BYTE_INDEX)
3447 {
3448 phb_l_element[cur_index].entry.index = (UBYTE)new_index;
3449 new_index++;
3450 cur_index = phb_l_element[cur_index].next_rcd;
3451 }
3452 if ( type EQ LDN )
3453 {
3454 /* ACI-SPR-16301: Write LND entry to 1 record of SIM, to keep it up
3455 to date Actually, the SIM entries will be overwritten by the LND data
3456 in RAM during switch off of the ME. This mechanism here is just to
3457 ensure the we retrieve more current data in the case of a SAT REFRESH
3458 or unexpected RESET. */
3459
3460 /* prepare entry */
3461 entrylen = pb_get_entry_len( entry->tag, PHB_MAX_TAG_LEN );
3462 tag_len = MINIMUM ( phb_ctb[type].alpha_len,
3463 entrylen) ;
3464 memset(data, 0xFF, sizeof(data));
3465 memcpy(data, entry->tag, tag_len);
3466 data[phb_ctb[type].alpha_len] = entry->len+1;
3467 data[phb_ctb[type].alpha_len+1] = entry->ton_npi;
3468 memcpy((char *)&data[phb_ctb[type].alpha_len+2],
3469 (char *)entry->number, 10);
3470 data[phb_ctb[type].alpha_len+12] = entry->cc_id;
3471
3472 /* always update the first entry */
3473 sim_result = pb_write_sim(type, 1);
3474
3475 return sim_result;
3476 }
3477 else
3478 {
3479 return PHB_OK;
3480 }
3481 }
3482 else /* unknown type */
3483 return PHB_FAIL;
3484 }
3485
3486
3487 /*
3488 +------------------------------------------------------------------------+
3489 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3490 | STATE : code ROUTINE : pb_delete_record |
3491 +------------------------------------------------------------------------+
3492
3493 PURPOSE : Delete a record from phonebook.
3494
3495 */
3496
3497 T_PHB_RETURN pb_delete_record(UBYTE type, UBYTE index, UBYTE *ext_rcd_num, BOOL permanent)
3498 {
3499 SHORT cur_index;
3500 UBYTE cur_byte_index, new_byte_index;
3501 UBYTE m,n;
3502 T_PHB_RETURN sim_result;
3503
3504 TRACE_FUNCTION ("pb_delete_record()");
3505
3506 /* check whether this phonebook exists */
3507 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3508 return PHB_FAIL;
3509
3510 if ((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN))
3511 {
3512 cur_byte_index = (UBYTE)phb_ctb[type].first_rcd;
3513 while (cur_byte_index != UNUSED_BYTE_INDEX)
3514 {
3515 if (phb_l_element[cur_byte_index].entry.index EQ index)
3516 {
3517 phb_l_element[cur_byte_index].free = PHB_ELEMENT_FREE;
3518 pb_l_rcd_chain(type,
3519 (SHORT)phb_l_element[cur_byte_index].prev_rcd,
3520 (SHORT)cur_byte_index,
3521 (SHORT)phb_l_element[cur_byte_index].next_rcd);
3522 phb_ctb[type].used_rcd--;
3523
3524 /*
3525 * Delete Record in PCM, else the
3526 * record is back after restart
3527 */
3528 if (phb_ctb[type].mem EQ TE_MEMORY)
3529 {
3530 UBYTE data[SIZE_EF_LDN];
3531
3532 memset (data, 0xFF, SIZE_EF_LDN);
3533
3534 switch (type)
3535 {
3536 case LDN:
3537 TRACE_EVENT ("Delete LDN entry");
3538 pcm_WriteRecord((UBYTE *)EF_LDN_ID,
3539 (USHORT)(cur_byte_index+1),
3540 SIZE_EF_LDN,
3541 data);
3542 break;
3543 case LRN:
3544 TRACE_EVENT ("Delete LRN entry");
3545 pcm_WriteRecord((UBYTE *)EF_LRN_ID,
3546 (USHORT)(cur_byte_index+1),
3547 SIZE_EF_LRN,
3548 data);
3549 break;
3550 case LMN:
3551 TRACE_EVENT ("Delete LMN entry");
3552 pcm_WriteRecord((UBYTE *)EF_LMN_ID,
3553 (USHORT)(cur_byte_index+1),
3554 SIZE_EF_LMN,
3555 data);
3556 break;
3557 }
3558 }
3559 cur_byte_index = (UBYTE)phb_ctb[type].first_rcd;
3560 new_byte_index = 1;
3561 while (cur_byte_index != UNUSED_BYTE_INDEX)
3562 {
3563 phb_l_element[cur_byte_index].entry.index = new_byte_index;
3564 new_byte_index++;
3565 cur_byte_index = phb_l_element[cur_byte_index].next_rcd;
3566 }
3567 return PHB_OK;
3568 }
3569 cur_byte_index = phb_l_element[cur_byte_index].next_rcd;
3570 }
3571 }
3572 else /* SIM related phonebooks */
3573 {
3574 cur_index = phb_ctb[type].first_rcd;
3575
3576 while (cur_index NEQ UNUSED_INDEX)
3577 {
3578 if (phb_element[cur_index].entry.index EQ index)
3579 {
3580 phb_element[cur_index].free = PHB_ELEMENT_FREE;
3581 pb_rcd_chain(type,
3582 phb_element[cur_index].prev_rcd,
3583 cur_index,
3584 phb_element[cur_index].next_rcd);
3585 pb_name_chain(type,
3586 phb_element[cur_index].prev_trcd,
3587 cur_index,
3588 phb_element[cur_index].next_trcd);
3589 pb_num_chain(type,
3590 phb_element[cur_index].prev_nrcd,
3591 cur_index,
3592 phb_element[cur_index].next_nrcd);
3593
3594 if ((type EQ ADN) OR (type EQ FDN))
3595 {
3596 pb_mname_chain(type,
3597 phb_element[cur_index].prev_mtrcd,
3598 cur_index,
3599 phb_element[cur_index].next_mtrcd);
3600 pb_mnum_chain(type,
3601 phb_element[cur_index].prev_mnrcd,
3602 cur_index,
3603 phb_element[cur_index].next_mnrcd);
3604
3605 phb_ctb[ADN_FDN].used_rcd--;
3606 }
3607
3608 phb_ctb[type].used_rcd--;
3609
3610 n = (UBYTE)(phb_element[cur_index].entry.index - 1)/8;
3611 m = (UBYTE)(phb_element[cur_index].entry.index - 1)%8;
3612 phb_ctb[type].rcd_bitmap[n] ^= 0x01 << m;
3613
3614 if (phb_ctb[type].mem EQ SIM_MEMORY)
3615 {
3616 #ifdef PHONEBOOK_EXTENSION
3617 /* store the extention record */
3618 *ext_rcd_num = phb_element[cur_index].entry.ext_rcd_num;
3619 #endif
3620 /* write this record in SIM card */
3621 memset(data, 0xFF, sizeof(data));
3622 if (permanent)
3623 {
3624 sim_result = pb_write_sim(type, index);
3625 #ifdef PHONEBOOK_EXTENSION
3626 if ((sim_result NEQ PHB_FAIL) AND (*ext_rcd_num NEQ 0xFF))
3627 {
3628 pb_rem_ext_record_flag (type, *ext_rcd_num);
3629 pb_prepare_ext_data (NULL, 0, NULL, 0, pb_get_ext_file_id(type));
3630 sim_result = pb_write_sim_ext (pb_get_ext_file_id(type), *ext_rcd_num);
3631 }
3632 #endif
3633 return (sim_result);
3634 }
3635 }
3636 return PHB_OK;
3637 }
3638 cur_index = phb_element[cur_index].next_rcd;
3639 }
3640 }
3641
3642 return PHB_FAIL;
3643 }
3644
3645
3646
3647 void copy_phb_element ( T_PHB_RECORD *entry, T_PHB_AFB_ELEMENT phb_element )
3648 {
3649 memset (entry, 0xff, sizeof(T_PHB_RECORD));
3650
3651 entry->book = phb_element.type;
3652 entry->index = phb_element.entry.index;
3653 entry->tag_len = phb_element.entry.tag_len;
3654 memcpy((char *)entry->tag,
3655 (char *)phb_element.entry.tag,
3656 PHB_MAX_TAG_LEN);
3657 entry->len = phb_element.entry.len;
3658 entry->ton_npi = phb_element.entry.ton_npi;
3659 memcpy((char *)entry->number,
3660 (char *)phb_element.entry.number,
3661 PHB_PACKED_NUM_LEN);
3662 #ifdef PHONEBOOK_EXTENSION
3663 memcpy((char *)entry->subaddr,
3664 (char *)phb_element.entry.subaddr,
3665 PHB_PACKED_NUM_LEN);
3666 #endif
3667 entry->cc_id = phb_element.entry.cc_id;
3668 }
3669
3670
3671 void copy_phb_l_element ( T_PHB_RECORD *entry, T_PHB_RDM_ELEMENT phb_l_element )
3672 {
3673 memset (entry, 0xff, sizeof(T_PHB_RECORD));
3674
3675 entry->book = phb_l_element.type;
3676 entry->index = phb_l_element.entry.index;
3677 entry->tag_len = phb_l_element.entry.tag_len;
3678 memcpy((char *)entry->tag,
3679 (char *)phb_l_element.entry.tag,
3680 PHB_MAX_TAG_LEN);
3681 entry->len = phb_l_element.entry.len;
3682 entry->ton_npi = phb_l_element.entry.ton_npi;
3683 memcpy((char *)entry->number,
3684 (char *)phb_l_element.entry.number,
3685 PHB_PACKED_NUM_LEN);
3686 #ifdef PHONEBOOK_EXTENSION
3687 memcpy((char *)entry->subaddr,
3688 (char *)phb_l_element.entry.subaddr,
3689 PHB_PACKED_NUM_LEN);
3690 #endif
3691 entry->cc_id = phb_l_element.entry.cc_id;
3692 entry->line = phb_l_element.entry.line;
3693
3694 entry->year = phb_l_element.entry.year;
3695 entry->month = phb_l_element.entry.month;
3696 entry->day = phb_l_element.entry.day;
3697 entry->hour = phb_l_element.entry.hour;
3698 entry->minute = phb_l_element.entry.minute;
3699 entry->second = phb_l_element.entry.second;
3700 }
3701
3702
3703
3704
3705 /*
3706 +------------------------------------------------------------------------+
3707 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3708 | STATE : code ROUTINE : pb_read_phys_record |
3709 +------------------------------------------------------------------------+
3710
3711 PURPOSE : Read one record according to physical index from phonebook.
3712
3713 */
3714 T_PHB_RETURN pb_read_phys_record(UBYTE type, SHORT index, T_PHB_RECORD *entry)
3715 {
3716 SHORT cur_index;
3717 SHORT i;
3718
3719 /* TRACE_FUNCTION ("pb_read_phys_record()");*/
3720
3721 /* check whether this phonebook exists */
3722 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3723 return PHB_FAIL;
3724
3725 if (index > phb_ctb[type].max_rcd)
3726 return PHB_INVALID_IDX;
3727
3728 cur_index = phb_ctb[type].first_rcd;
3729 if (cur_index EQ UNUSED_INDEX)
3730 return PHB_FAIL;
3731
3732 if (type EQ ECC
3733 OR type EQ ADN
3734 OR type EQ FDN
3735 OR type EQ BDN
3736 OR type EQ UPN
3737 OR type EQ SDN )
3738 {
3739 for (i=0; i<phb_ctb[type].used_rcd; i++)
3740 {
3741 if (phb_element[cur_index].entry.index EQ index)
3742 {
3743 copy_phb_element (entry, phb_element[cur_index]);
3744 return PHB_OK;
3745 }
3746 cur_index = phb_element[cur_index].next_rcd;
3747 if (cur_index EQ UNUSED_INDEX)
3748 break;
3749 }
3750 }
3751
3752 else if (type EQ LDN
3753 OR type EQ LRN
3754 OR type EQ LMN)
3755 {
3756 for (i=0; i<phb_ctb[type].used_rcd; i++)
3757 {
3758 if (phb_l_element[cur_index].entry.index EQ index)
3759 {
3760 copy_phb_l_element (entry, phb_l_element[cur_index]);
3761 return PHB_OK;
3762 }
3763 cur_index = phb_l_element[cur_index].next_rcd;
3764 if (cur_index EQ UNUSED_INDEX)
3765 break;
3766 }
3767 }
3768
3769 return PHB_FAIL;
3770 }
3771
3772 /*
3773 +------------------------------------------------------------------------+
3774 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3775 | STATE : code ROUTINE : pb_read_index_record |
3776 +------------------------------------------------------------------------+
3777
3778 PURPOSE : Read one record according to index from phonebook.
3779
3780 */
3781
3782 T_PHB_RETURN pb_read_index_record(UBYTE type, SHORT index, T_PHB_RECORD *entry)
3783 {
3784 SHORT cur_index;
3785 SHORT i;
3786
3787 /* TRACE_FUNCTION ("pb_read_index_record()");*/
3788
3789 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3790 return PHB_FAIL;
3791
3792 if (index > phb_ctb[type].max_rcd)
3793 return PHB_INVALID_IDX;
3794
3795 cur_index = phb_ctb[type].first_rcd;
3796 if (cur_index EQ UNUSED_INDEX)
3797 return PHB_FAIL;
3798
3799 if (type EQ ECC
3800 OR type EQ ADN
3801 OR type EQ FDN
3802 OR type EQ BDN
3803 OR type EQ UPN
3804 OR type EQ SDN)
3805 {
3806 for (i=1; i<index; i++)
3807 {
3808 cur_index = phb_element[cur_index].next_rcd;
3809 if (cur_index EQ UNUSED_INDEX)
3810 return PHB_FAIL;
3811 }
3812 copy_phb_element (entry, phb_element[cur_index]);
3813 return PHB_OK;
3814 }
3815
3816 else if (type EQ LDN
3817 OR type EQ LRN
3818 OR type EQ LMN)
3819 {
3820 for (i=1; i<index; i++)
3821 {
3822 cur_index = phb_l_element[cur_index].next_rcd;
3823 if (cur_index EQ UNUSED_BYTE_INDEX)
3824 return PHB_FAIL;
3825 }
3826 copy_phb_l_element (entry, phb_l_element[cur_index]);
3827 return PHB_OK;
3828 }
3829
3830 return PHB_FAIL;
3831 }
3832
3833 /*
3834 +------------------------------------------------------------------------+
3835 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3836 | STATE : code ROUTINE : pb_read_alpha_record |
3837 +------------------------------------------------------------------------+
3838
3839 PURPOSE : Read one record according to alpha index from phonebook.
3840
3841 */
3842
3843 T_PHB_RETURN pb_read_alpha_record(UBYTE type, SHORT index, T_PHB_RECORD *entry)
3844 {
3845 SHORT cur_index;
3846 SHORT i;
3847
3848 /* TRACE_FUNCTION ("pb_read_alpha_record()");*/
3849
3850 if (type EQ ADN_FDN)
3851 {
3852 /* check whether this phonebook exists */
3853 if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY)
3854 AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY))
3855 return PHB_FAIL;
3856
3857 cur_index = phb_ctb[ADN].first_mtrcd;
3858 if (cur_index EQ UNUSED_INDEX)
3859 cur_index = phb_ctb[FDN].first_mtrcd;
3860 if (cur_index EQ UNUSED_INDEX)
3861 return PHB_FAIL;
3862
3863 for (i=1; i<index; i++)
3864 {
3865 cur_index = phb_element[cur_index].next_mtrcd;
3866 if (cur_index EQ UNUSED_INDEX)
3867 return PHB_FAIL;
3868 }
3869 copy_phb_element (entry, phb_element[cur_index]);
3870 return PHB_OK;
3871 }
3872 else if (type EQ ECC
3873 OR type EQ ADN
3874 OR type EQ FDN
3875 OR type EQ BDN
3876 OR type EQ SDN
3877 OR type EQ UPN)
3878 {
3879 /* check whether this phonebook exists */
3880 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3881 return PHB_FAIL;
3882
3883 cur_index = phb_ctb[type].first_trcd;
3884 if (cur_index EQ UNUSED_INDEX)
3885 return PHB_FAIL;
3886
3887 for (i=1; i<index; i++)
3888 {
3889 cur_index = phb_element[cur_index].next_trcd;
3890 if (cur_index EQ UNUSED_INDEX)
3891 return PHB_FAIL;
3892 }
3893 copy_phb_element (entry, phb_element[cur_index]);
3894 return PHB_OK;
3895 }
3896 else /* LDN, LRN, LMN */
3897 return PHB_FAIL;
3898 }
3899
3900 /*
3901 +------------------------------------------------------------------------+
3902 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3903 | STATE : code ROUTINE : pb_read_number_record |
3904 +------------------------------------------------------------------------+
3905
3906 PURPOSE : Read one record according to number index from phonebook.
3907
3908 */
3909
3910 T_PHB_RETURN pb_read_number_record(UBYTE type, SHORT index, T_PHB_RECORD *entry)
3911 {
3912 SHORT cur_index;
3913 SHORT i;
3914
3915 /* TRACE_FUNCTION ("pb_read_number_record()");*/
3916
3917 if (type EQ ADN_FDN)
3918 {
3919 /* check whether this phonebook exists */
3920 if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY)
3921 AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY))
3922 return PHB_FAIL;
3923
3924
3925 cur_index = phb_ctb[ADN].first_mnrcd;
3926 if (cur_index EQ UNUSED_INDEX)
3927 cur_index = phb_ctb[FDN].first_mnrcd;
3928 if (cur_index EQ UNUSED_INDEX)
3929 return PHB_FAIL;
3930
3931 for (i=1; i<index; i++)
3932 {
3933 cur_index = phb_element[cur_index].next_mnrcd;
3934 if (cur_index EQ UNUSED_INDEX)
3935 return PHB_FAIL;
3936 }
3937 copy_phb_element (entry, phb_element[cur_index]);
3938 return PHB_OK;
3939 }
3940 else if (type EQ ECC
3941 OR type EQ ADN
3942 OR type EQ FDN
3943 OR type EQ BDN
3944 OR type EQ SDN
3945 OR type EQ UPN)
3946 {
3947 /* check whether this phonebook exists */
3948 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
3949 return PHB_FAIL;
3950
3951 cur_index = phb_ctb[type].first_nrcd;
3952 if (cur_index EQ UNUSED_INDEX)
3953 return PHB_FAIL;
3954
3955 for (i=1; i<index; i++)
3956 {
3957 cur_index = phb_element[cur_index].next_nrcd;
3958 if (cur_index EQ UNUSED_INDEX)
3959 return PHB_FAIL;
3960 }
3961 copy_phb_element (entry, phb_element[cur_index]);
3962 return PHB_OK;
3963 }
3964 else
3965 /* LDN, LRN, LMN */
3966 return PHB_FAIL;
3967 }
3968
3969 /*
3970 +------------------------------------------------------------------------+
3971 | PROJECT : MMI-Framework (8417) MODULE: PHB |
3972 | STATE : code ROUTINE : pb_search_name |
3973 +------------------------------------------------------------------------+
3974
3975 PURPOSE : Search the string from phonebook
3976
3977 */
3978
3979 T_PHB_RETURN pb_search_name(T_ACI_CMD_SRC srcID,
3980 UBYTE type,
3981 T_ACI_PB_TEXT *search_tag,
3982 UBYTE mode,
3983 SHORT *first_ind,
3984 SHORT *result,
3985 T_PHB_RECORD *entry)
3986 {
3987 static SHORT ptr_index = UNUSED_INDEX;
3988 SHORT cur_index;
3989 SHORT index;
3990 int cmp_res;
3991 int cmp_len;
3992 int max_cmp_len;
3993
3994 /* TRACE_FUNCTION ("pb_search_name()");*/
3995
3996 if (type EQ ADN_FDN)
3997 {
3998 /* check whether this phonebook exists */
3999 if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY)
4000 AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY))
4001 return PHB_FAIL;
4002
4003 if ((phb_ctb[ADN].first_mtrcd EQ UNUSED_INDEX)
4004 AND (phb_ctb[FDN].first_mtrcd EQ UNUSED_INDEX))
4005 return PHB_FAIL;
4006 }
4007 else
4008 {
4009 /* check whether this phonebook exists */
4010 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
4011 return PHB_FAIL;
4012 }
4013
4014 /* search string */
4015 if ( mode EQ PHB_NEW_SEARCH )
4016 {
4017 TRACE_EVENT("pb_search_name() DEB: mode EQ PHB_NEW_SEARCH");
4018 ptr_index = UNUSED_INDEX;
4019 max_cmp_len = 0;
4020 index = 1;
4021 *result = 0;
4022
4023 if (type EQ ADN_FDN)
4024 {
4025 if (phb_ctb[ADN].first_mtrcd != UNUSED_INDEX)
4026 cur_index = phb_ctb[ADN].first_mtrcd;
4027 else
4028 cur_index = phb_ctb[FDN].first_mtrcd;
4029 }
4030 else
4031 cur_index = phb_ctb[type].first_trcd;
4032
4033 while (cur_index != UNUSED_INDEX)
4034 {
4035 /*
4036 this should not cause problems, because in both alphabets
4037 (GSM and ASCII) the most important chars are at the same
4038 positions (A-Z: 65-90 // a-z:97-122)
4039 */
4040 if (ext_compare_fct != NULL)
4041 {
4042 cmp_res = ext_compare_fct (phb_element[cur_index].entry.tag,
4043 phb_element[cur_index].entry.tag_len,
4044 search_tag->data,
4045 search_tag->len);
4046 }
4047 else
4048 {
4049 cmp_res = pb_cmp_phb_entry ( phb_element[cur_index].entry.tag,
4050 phb_element[cur_index].entry.tag_len,
4051 search_tag );
4052 }
4053
4054 #if defined(MFW) OR defined (FF_MMI_RIV)
4055 if (srcID EQ CMD_SRC_LCL)
4056 {
4057 /* if search string is before entry in alphabet */
4058 if (search_tag->len EQ 1 AND
4059 (cmp_res >= 0) AND (phb_element[cur_index].entry.tag[0] NEQ '\0'))
4060 {
4061 cmp_res = 0;
4062 }
4063 }
4064 else
4065 #endif
4066 {
4067 if (cmp_res EQ 0) /* If Searchstring matches the first letters of Phonebook */
4068 {
4069 if (search_tag->len <= phb_element[cur_index].entry.tag_len)
4070 ; /* MATCH */
4071 else
4072 cmp_res = search_tag->len + 1;
4073 }
4074 }
4075
4076 if (cmp_res EQ 0)
4077 {
4078 cmp_len = MINIMUM(phb_element[cur_index].entry.tag_len, search_tag->len);
4079 if ( cmp_len > max_cmp_len )
4080 {
4081 max_cmp_len = cmp_len;
4082 if ( ptr_index EQ UNUSED_INDEX )
4083 {
4084 /* save the index of the first found record */
4085 TRACE_EVENT("pb_search_name() DEB: first index");
4086 }
4087 ptr_index = cur_index;
4088 *first_ind = index;
4089 }
4090 (*result)++;
4091
4092 }
4093 if (type EQ ADN_FDN)
4094 cur_index = phb_element[cur_index].next_mtrcd;
4095 else
4096 cur_index = phb_element[cur_index].next_trcd;
4097 index++;
4098 }
4099 }
4100 else
4101 {
4102 TRACE_EVENT("pb_search_name() DEB: mode EQ PHB_NEXT_SEARCH");
4103 }
4104
4105 if ( ptr_index EQ UNUSED_INDEX )
4106 {
4107 TRACE_EVENT("pb_search_name() ERR: name not found");
4108 return PHB_FAIL;
4109 }
4110
4111 /* copy the found record */
4112 copy_phb_element( entry, phb_element[ptr_index] );
4113
4114 if (type EQ ADN_FDN)
4115 ptr_index = phb_element[ptr_index].next_mtrcd;
4116 else
4117 ptr_index = phb_element[ptr_index].next_trcd;
4118
4119 return PHB_OK;
4120 }
4121
4122 /*
4123 +------------------------------------------------------------------------+
4124 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4125 | STATE : code ROUTINE : pb_search_number |
4126 +------------------------------------------------------------------------+
4127
4128 PURPOSE :
4129
4130 */
4131
4132 T_PHB_RETURN pb_search_number(UBYTE type,
4133 UBYTE *number,
4134 UBYTE mode,
4135 SHORT *first_ind,
4136 SHORT *result,
4137 T_PHB_RECORD *entry)
4138 {
4139 static SHORT count = 0;
4140 static SHORT ptr_index;
4141 SHORT cur_index;
4142 UBYTE cur_byte_index;
4143
4144 UBYTE flag;
4145 SHORT index;
4146 CHAR cur_number[MAX_PHB_NUM_LEN];
4147 static CHAR search_number[MAX_PHB_NUM_LEN];
4148
4149 TRACE_FUNCTION ("pb_search_number()");
4150
4151 if (type EQ ADN_FDN)
4152 {
4153 /* check whether this phonebook exists */
4154 if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY)
4155 AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY))
4156 return PHB_FAIL;
4157
4158 if ((phb_ctb[ADN].first_mnrcd EQ UNUSED_INDEX)
4159 AND (phb_ctb[FDN].first_mnrcd EQ UNUSED_INDEX))
4160 return PHB_FAIL;
4161 }
4162 else
4163 {
4164 /* check whether this phonebook exists */
4165 if (phb_ctb[type].mem EQ NO_PHB_ENTRY AND type NEQ ECC)
4166 return PHB_FAIL;
4167 }
4168
4169 if (type EQ LDN
4170 OR type EQ LRN
4171 OR type EQ LMN)
4172 {
4173 *result = 0;
4174 if (!phb_ctb[type].used_rcd)
4175 return PHB_OK;
4176
4177 cur_byte_index = (UBYTE) phb_ctb[type].first_rcd;
4178
4179 while (cur_byte_index != UNUSED_BYTE_INDEX)
4180 {
4181 /* convert the number in BCD to string */
4182 cmhPHB_getAdrStr(cur_number,
4183 MAX_PHB_NUM_LEN - 1,
4184 phb_l_element[cur_byte_index].entry.number,
4185 phb_l_element[cur_byte_index].entry.len);
4186 if (!strcmp((char *)cur_number, (char *)number))
4187 {
4188 copy_phb_l_element(entry, phb_l_element[cur_byte_index]);
4189
4190 *result = 1;
4191 return PHB_OK;
4192 }
4193 cur_byte_index = phb_l_element[cur_byte_index].next_rcd;
4194 }
4195 }
4196
4197 /* check emergency call */
4198 if (type EQ ECC)
4199 {
4200 *result = 0;
4201
4202 /* if (!strcmp("112", (char *)number) || !strcmp("911", (char *)number) || !strcmp("999", (char *)number))
4203 {
4204 entry->book = ECC;
4205 entry->index = 1;
4206 entry->tag_len = 0;
4207 entry->tag[0] = 0;
4208 cmhPHB_getAdrBcd ( entry->number,
4209 &entry->len,
4210 PHB_PACKED_NUM_LEN, (char *)number );
4211 entry->ton_npi = 0xFF;
4212 entry->cc_id = 0xFF;
4213 *result = 1;
4214 return PHB_OK;
4215 }*/
4216
4217 if (!phb_ctb[type].used_rcd)
4218 return PHB_OK;
4219
4220 cur_index = phb_ctb[type].first_nrcd;
4221
4222 while (cur_index != UNUSED_INDEX)
4223 {
4224 /* convert the number in BCD to string */
4225 cmhPHB_getAdrStr(cur_number,
4226 PHB_PACKED_NUM_LEN - 1,
4227 phb_element[cur_index].entry.number,
4228 phb_element[cur_index].entry.len);
4229 if (!strcmp((char *)cur_number, (char *)number))
4230 {
4231 copy_phb_element (entry, phb_element[cur_index]);
4232 *result = 1;
4233 return PHB_OK;
4234 }
4235 cur_index = phb_element[cur_index].next_nrcd;
4236 }
4237 return PHB_OK;
4238 }
4239
4240 /* search phone number */
4241 if (mode EQ PHB_NEW_SEARCH)
4242 {
4243 count = 0;
4244 flag = 0;
4245 index = 1;
4246 strncpy(search_number, (char *)number, MAX_PHB_NUM_LEN-1);
4247 search_number[MAX_PHB_NUM_LEN-1] = '\0';
4248
4249 if (type EQ ADN_FDN)
4250 {
4251 if (phb_ctb[ADN].first_mnrcd != UNUSED_INDEX)
4252 cur_index = phb_ctb[ADN].first_mnrcd;
4253 else
4254 cur_index = phb_ctb[FDN].first_mnrcd;
4255 }
4256 else
4257 cur_index = phb_ctb[type].first_nrcd;
4258
4259 while (cur_index != UNUSED_INDEX)
4260 {
4261 /* convert the number in BCD to string */
4262 cmhPHB_getAdrStr(cur_number,
4263 MAX_PHB_NUM_LEN - 1,
4264 phb_element[cur_index].entry.number,
4265 phb_element[cur_index].entry.len);
4266
4267 if (pb_check_number(cur_number, (char *)number))
4268 {
4269 if (!flag)
4270 {
4271 ptr_index = cur_index; /* save the index of the first found record */
4272 *first_ind = index;
4273 flag = 1;
4274 }
4275 count++;
4276 }
4277 if (type EQ ADN_FDN)
4278 cur_index = phb_element[cur_index].next_mnrcd;
4279 else
4280 cur_index = phb_element[cur_index].next_nrcd;
4281 index++;
4282 }
4283
4284 *result = count;
4285 }
4286
4287 if (mode EQ PHB_NEXT_SEARCH AND count)
4288 {
4289 while (ptr_index != UNUSED_INDEX)
4290 {
4291 /* convert the number in BCD to string */
4292 cmhPHB_getAdrStr(cur_number,
4293 MAX_PHB_NUM_LEN - 1,
4294 phb_element[ptr_index].entry.number,
4295 phb_element[ptr_index].entry.len);
4296
4297 if (pb_check_number(cur_number, search_number))
4298 break;
4299
4300 if (type EQ ADN_FDN)
4301 ptr_index = phb_element[ptr_index].next_mnrcd;
4302 else
4303 ptr_index = phb_element[ptr_index].next_nrcd;
4304 }
4305 }
4306
4307 /* copy the found record */
4308 if (count)
4309 {
4310 copy_phb_element( entry, phb_element[ptr_index] );
4311 if (type EQ ADN_FDN)
4312 ptr_index = phb_element[ptr_index].next_mnrcd;
4313 else
4314 ptr_index = phb_element[ptr_index].next_nrcd;
4315 count--;
4316 }
4317 else
4318 return PHB_FAIL;
4319
4320 return PHB_OK;
4321 }
4322
4323 /*
4324 +------------------------------------------------------------------------+
4325 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4326 | STATE : code ROUTINE : pb_rcd_chain |
4327 +------------------------------------------------------------------------+
4328
4329 PURPOSE : Chain the element according to record number.
4330
4331 */
4332
4333 void pb_rcd_chain(UBYTE type,
4334 SHORT prev_index,
4335 SHORT cur_index,
4336 SHORT next_index)
4337 {
4338 /* TRACE_FUNCTION ("pb_rcd_chain()");*/
4339
4340 if ((phb_element[cur_index].prev_rcd EQ UNUSED_INDEX)
4341 AND (phb_element[cur_index].next_rcd EQ UNUSED_INDEX))
4342 {
4343 phb_ctb[type].first_rcd = UNUSED_INDEX;
4344 }
4345 else if ((phb_element[cur_index].prev_rcd NEQ UNUSED_INDEX)
4346 AND (phb_element[cur_index].next_rcd EQ UNUSED_INDEX))
4347 {
4348 phb_element[prev_index].next_rcd = UNUSED_INDEX;
4349 }
4350 else if ((phb_element[cur_index].prev_rcd EQ UNUSED_INDEX)
4351 AND (phb_element[cur_index].next_rcd NEQ UNUSED_INDEX))
4352 {
4353 phb_element[next_index].prev_rcd = UNUSED_INDEX;
4354 phb_element[cur_index].next_rcd = UNUSED_INDEX; /* ??? */
4355 phb_ctb[type].first_rcd = next_index;
4356 }
4357 else if ((phb_element[cur_index].prev_rcd NEQ UNUSED_INDEX)
4358 AND (phb_element[cur_index].next_rcd NEQ UNUSED_INDEX))
4359 {
4360 phb_element[prev_index].next_rcd = phb_element[cur_index].next_rcd;
4361 phb_element[next_index].prev_rcd = phb_element[cur_index].prev_rcd;
4362 }
4363 }
4364
4365 /*
4366 +------------------------------------------------------------------------+
4367 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4368 | STATE : code ROUTINE : pb_l_rcd_chain |
4369 +------------------------------------------------------------------------+
4370
4371 PURPOSE : Chain the element according to record number.
4372
4373 */
4374
4375 void pb_l_rcd_chain(UBYTE type,
4376 SHORT prev_index,
4377 SHORT cur_index,
4378 SHORT next_index)
4379 {
4380 /* TRACE_FUNCTION ("pb_l_rcd_chain()"); */
4381
4382 if ((phb_l_element[cur_index].prev_rcd EQ UNUSED_BYTE_INDEX)
4383 AND (phb_l_element[cur_index].next_rcd EQ UNUSED_BYTE_INDEX))
4384 {
4385 phb_ctb[type].first_rcd = UNUSED_INDEX;
4386 }
4387 else if ((phb_l_element[cur_index].prev_rcd NEQ UNUSED_BYTE_INDEX)
4388 AND (phb_l_element[cur_index].next_rcd EQ UNUSED_BYTE_INDEX))
4389 {
4390 phb_l_element[prev_index].next_rcd = UNUSED_BYTE_INDEX;
4391 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
4392 }
4393 else if ((phb_l_element[cur_index].prev_rcd EQ UNUSED_BYTE_INDEX)
4394 AND (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX))
4395 {
4396 phb_l_element[next_index].prev_rcd = UNUSED_BYTE_INDEX;
4397 phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX;
4398 phb_ctb[type].first_rcd = (UBYTE)next_index;
4399 }
4400 else if ((phb_l_element[cur_index].prev_rcd NEQ UNUSED_BYTE_INDEX)
4401 AND (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX))
4402 {
4403 phb_l_element[prev_index].next_rcd = phb_l_element[cur_index].next_rcd;
4404 phb_l_element[next_index].prev_rcd = phb_l_element[cur_index].prev_rcd;
4405 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
4406 phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX;
4407 }
4408 }
4409
4410
4411 /*
4412 +------------------------------------------------------------------------+
4413 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4414 | STATE : code ROUTINE : pb_name_chain |
4415 +------------------------------------------------------------------------+
4416
4417 PURPOSE : Chain the element according to alpha string.
4418
4419 */
4420
4421 void pb_name_chain(UBYTE type,
4422 SHORT prev_index,
4423 SHORT cur_index,
4424 SHORT next_index)
4425 {
4426 SHORT ref_index;
4427 UBYTE flag;
4428
4429 /* TRACE_FUNCTION ("pb_name_chain()");*/
4430
4431 if ((phb_element[cur_index].prev_trcd EQ UNUSED_INDEX)
4432 AND (phb_element[cur_index].next_trcd EQ UNUSED_INDEX))
4433 {
4434 phb_ctb[type].first_trcd = UNUSED_INDEX;
4435 }
4436 else if ((phb_element[cur_index].prev_trcd NEQ UNUSED_INDEX)
4437 AND (phb_element[cur_index].next_trcd EQ UNUSED_INDEX))
4438 {
4439 phb_element[prev_index].next_trcd = UNUSED_INDEX;
4440 }
4441 else if ((phb_element[cur_index].prev_trcd EQ UNUSED_INDEX)
4442 AND (phb_element[cur_index].next_trcd NEQ UNUSED_INDEX))
4443 {
4444 phb_element[next_index].prev_trcd = UNUSED_INDEX;
4445 phb_ctb[type].first_trcd = next_index;
4446 phb_element[cur_index].next_trcd = UNUSED_INDEX;
4447 }
4448 else if ((phb_element[cur_index].prev_trcd NEQ UNUSED_INDEX)
4449 AND (phb_element[cur_index].next_trcd NEQ UNUSED_INDEX))
4450 {
4451 phb_element[prev_index].next_trcd = phb_element[cur_index].next_trcd;
4452 phb_element[next_index].prev_trcd = phb_element[cur_index].prev_trcd;
4453 }
4454
4455 if (phb_ctb[type].first_trcd EQ cur_index)
4456 {
4457 flag = 0;
4458
4459 ref_index = phb_element[cur_index].next_trcd;
4460 while (phb_element[ref_index].next_trcd)
4461 {
4462 if (!flag)
4463 {
4464 phb_ctb[type].first_trcd = ref_index;
4465 flag = 1;
4466 }
4467 ref_index = phb_element[ref_index].next_trcd;
4468 }
4469
4470 if (!phb_element[ref_index].next_trcd AND !flag)
4471 phb_ctb[type].first_trcd = UNUSED_INDEX;
4472 }
4473 }
4474
4475 /*
4476 +------------------------------------------------------------------------+
4477 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4478 | STATE : code ROUTINE : pb_num_chain |
4479 +------------------------------------------------------------------------+
4480
4481 PURPOSE : Chain the element according to phone number.
4482
4483 */
4484
4485 void pb_num_chain(UBYTE type,
4486 SHORT prev_index,
4487 SHORT cur_index,
4488 SHORT next_index)
4489 {
4490 SHORT ref_index;
4491 UBYTE flag;
4492
4493 /* TRACE_FUNCTION ("pb_num_chain()");*/
4494
4495 if ((phb_element[cur_index].prev_nrcd EQ UNUSED_INDEX)
4496 AND (phb_element[cur_index].next_nrcd EQ UNUSED_INDEX))
4497 {
4498 phb_ctb[type].first_nrcd = UNUSED_INDEX;
4499 }
4500 else if ((phb_element[cur_index].prev_nrcd NEQ UNUSED_INDEX)
4501 AND (phb_element[cur_index].next_nrcd EQ UNUSED_INDEX))
4502 {
4503 phb_element[prev_index].next_nrcd = UNUSED_INDEX;
4504 }
4505 else if ((phb_element[cur_index].prev_nrcd EQ UNUSED_INDEX)
4506 AND (phb_element[cur_index].next_nrcd NEQ UNUSED_INDEX))
4507 {
4508 phb_element[next_index].prev_nrcd = UNUSED_INDEX;
4509 phb_ctb[type].first_nrcd = next_index;
4510 }
4511 else if ((phb_element[cur_index].prev_nrcd NEQ UNUSED_INDEX)
4512 AND (phb_element[cur_index].next_nrcd NEQ UNUSED_INDEX))
4513 {
4514 phb_element[prev_index].next_nrcd = phb_element[cur_index].next_nrcd;
4515 phb_element[next_index].prev_nrcd = phb_element[cur_index].prev_nrcd;
4516 }
4517
4518 if (phb_ctb[type].first_nrcd EQ cur_index)
4519 {
4520 flag = 0;
4521
4522 ref_index = phb_element[cur_index].next_nrcd;
4523 while (phb_element[ref_index].next_nrcd)
4524 {
4525 if (!flag)
4526 {
4527 phb_ctb[type].first_nrcd = ref_index;
4528 flag = 1;
4529 }
4530 ref_index = phb_element[ref_index].next_nrcd;
4531 }
4532
4533 if (!phb_element[ref_index].next_nrcd AND !flag)
4534 phb_ctb[type].first_nrcd = UNUSED_INDEX;
4535 }
4536 }
4537
4538
4539 /*
4540 +------------------------------------------------------------------------+
4541 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4542 | STATE : code ROUTINE : pb_mname_chain |
4543 +------------------------------------------------------------------------+
4544
4545 PURPOSE : Chain the element according to merged alpha string.
4546
4547 */
4548
4549 void pb_mname_chain(UBYTE type,
4550 SHORT prev_index,
4551 SHORT cur_index,
4552 SHORT next_index)
4553 {
4554 SHORT ref_index;
4555 UBYTE flag;
4556
4557 /* TRACE_FUNCTION ("pb_mname_chain()");*/
4558
4559 if ((phb_element[cur_index].prev_mtrcd EQ UNUSED_INDEX)
4560 AND (phb_element[cur_index].next_mtrcd EQ UNUSED_INDEX))
4561 {
4562 phb_ctb[type].first_mtrcd = UNUSED_INDEX;
4563 }
4564 else if ((phb_element[cur_index].prev_mtrcd NEQ UNUSED_INDEX)
4565 AND (phb_element[cur_index].next_mtrcd EQ UNUSED_INDEX))
4566 {
4567 phb_element[prev_index].next_mtrcd = UNUSED_INDEX;
4568 }
4569 else if ((phb_element[cur_index].prev_mtrcd EQ UNUSED_INDEX)
4570 AND (phb_element[cur_index].next_mtrcd NEQ UNUSED_INDEX))
4571 {
4572 phb_element[next_index].prev_mtrcd = UNUSED_INDEX;
4573 if (phb_ctb[ADN].used_rcd != 0)
4574 phb_ctb[ADN].first_mtrcd = next_index;
4575 else
4576 phb_ctb[FDN].first_mtrcd = next_index;
4577 }
4578 else if ((phb_element[cur_index].prev_mtrcd NEQ UNUSED_INDEX)
4579 AND (phb_element[cur_index].next_mtrcd NEQ UNUSED_INDEX))
4580 {
4581 phb_element[prev_index].next_mtrcd = phb_element[cur_index].next_mtrcd;
4582 phb_element[next_index].prev_mtrcd = phb_element[cur_index].prev_mtrcd;
4583 }
4584
4585 if ((phb_ctb[ADN].first_mtrcd EQ cur_index)
4586 OR (phb_ctb[FDN].first_mtrcd EQ cur_index))
4587 {
4588 flag = 0;
4589
4590 ref_index = phb_element[cur_index].next_mtrcd;
4591 while (phb_element[ref_index].next_mtrcd)
4592 {
4593 if (!flag)
4594 {
4595 if (phb_ctb[ADN].used_rcd != 0)
4596 phb_ctb[ADN].first_mtrcd = ref_index;
4597 else
4598 phb_ctb[FDN].first_mtrcd = ref_index;
4599 flag = 1;
4600 }
4601 ref_index = phb_element[ref_index].next_mtrcd;
4602 }
4603
4604 if (!phb_element[ref_index].next_mtrcd AND !flag)
4605 {
4606 phb_ctb[ADN].first_mtrcd = UNUSED_INDEX;
4607 phb_ctb[FDN].first_mtrcd = UNUSED_INDEX;
4608 }
4609 }
4610 }
4611
4612 /*
4613 +------------------------------------------------------------------------+
4614 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4615 | STATE : code ROUTINE : pb_mnum_chain |
4616 +------------------------------------------------------------------------+
4617
4618 PURPOSE : Chain the element according to phone number.
4619
4620 */
4621
4622 void pb_mnum_chain(UBYTE type,
4623 SHORT prev_index,
4624 SHORT cur_index,
4625 SHORT next_index)
4626 {
4627 SHORT ref_index;
4628 UBYTE flag;
4629
4630 /* TRACE_FUNCTION ("pb_mnum_chain()");*/
4631
4632 if ((phb_element[cur_index].prev_mnrcd EQ UNUSED_INDEX)
4633 AND (phb_element[cur_index].next_mnrcd EQ UNUSED_INDEX))
4634 {
4635 phb_ctb[ADN].first_mnrcd = UNUSED_INDEX;
4636 phb_ctb[FDN].first_mnrcd = UNUSED_INDEX;
4637 }
4638 else if ((phb_element[cur_index].prev_mnrcd NEQ UNUSED_INDEX)
4639 AND (phb_element[cur_index].next_mnrcd EQ UNUSED_INDEX))
4640 {
4641 phb_element[prev_index].next_mnrcd = UNUSED_INDEX;
4642 }
4643 else if ((phb_element[cur_index].prev_mnrcd EQ UNUSED_INDEX)
4644 AND (phb_element[cur_index].next_mnrcd NEQ UNUSED_INDEX))
4645 {
4646 phb_element[next_index].prev_mnrcd = UNUSED_INDEX;
4647 if (phb_ctb[ADN].used_rcd != 0)
4648 phb_ctb[ADN].first_mnrcd = next_index;
4649 else
4650 phb_ctb[FDN].first_mnrcd = next_index;
4651 }
4652 else if ((phb_element[cur_index].prev_mnrcd NEQ UNUSED_INDEX)
4653 AND (phb_element[cur_index].next_mnrcd NEQ UNUSED_INDEX))
4654 {
4655 phb_element[prev_index].next_mnrcd = phb_element[cur_index].next_mnrcd;
4656 phb_element[next_index].prev_mnrcd = phb_element[cur_index].prev_mnrcd;
4657 }
4658
4659 if ((phb_ctb[ADN].first_mnrcd EQ cur_index)
4660 OR (phb_ctb[FDN].first_mnrcd EQ cur_index))
4661 {
4662 flag = 0;
4663
4664 ref_index = phb_element[cur_index].next_mnrcd;
4665 while (phb_element[ref_index].next_mnrcd)
4666 {
4667 if (!flag)
4668 {
4669 if (phb_ctb[ADN].used_rcd != 0)
4670 phb_ctb[ADN].first_mnrcd = ref_index;
4671 else
4672 phb_ctb[FDN].first_mnrcd = ref_index;
4673 flag = 1;
4674 }
4675 ref_index = phb_element[ref_index].next_mnrcd;
4676 }
4677
4678 if (!phb_element[ref_index].next_mnrcd AND !flag)
4679 {
4680 phb_ctb[ADN].first_mnrcd = UNUSED_INDEX;
4681 phb_ctb[FDN].first_mnrcd = UNUSED_INDEX;
4682 }
4683 }
4684 }
4685
4686 /*
4687 +------------------------------------------------------------------------+
4688 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4689 | STATE : code ROUTINE : pb_read_status |
4690 +------------------------------------------------------------------------+
4691
4692 PURPOSE :
4693
4694 */
4695
4696 T_PHB_RETURN pb_read_status(UBYTE type, UBYTE *service,
4697 SHORT *max_rcd, SHORT *used_rcd,
4698 UBYTE *tag_len, SHORT *avail_rcd,
4699 SHORT *max_ext, SHORT *used_ext)
4700 {
4701 SHORT i;
4702 SHORT count;
4703 UBYTE ext_type;
4704
4705 TRACE_FUNCTION ("pb_read_status()");
4706
4707 TRACE_EVENT_P1("PHB get status of phonebook: %d", type);
4708
4709 /* check whether this phonebook exists */
4710 if (phb_ctb[type].mem EQ NO_PHB_ENTRY)
4711 {
4712 TRACE_EVENT("Phonebook is empty: return PHB_FAIL");
4713 return PHB_FAIL;
4714 }
4715 *service = phb_ctb[type].service;
4716 *used_rcd = phb_ctb[type].used_rcd;
4717 /* ACI-SPR-9421 (mdf): reinstalled after storage increasement for phonebook */
4718 *max_rcd = phb_ctb[type].max_rcd;
4719 *tag_len = MINIMUM ( phb_ctb[type].alpha_len, PHB_MAX_TAG_LEN );
4720
4721 *max_ext = 0;
4722 *used_ext = 0;
4723
4724
4725 count = 0;
4726 switch (type)
4727 {
4728 case ECC:
4729 case ADN:
4730 case FDN:
4731 case SDN:
4732 case BDN:
4733 case ADN_FDN:
4734 case UPN:
4735 for (i=0; i<MAX_AFB_RECORDS; i++)
4736 {
4737 if (phb_element[i].free EQ PHB_ELEMENT_FREE)
4738 count++;
4739 }
4740 TRACE_EVENT_P1("free records from count=%d",count);
4741
4742 if ((phb_ctb[type].max_rcd-phb_ctb[type].used_rcd) >=count)
4743 {
4744 /* avail_rcd should be equal to free records not used records!!! */
4745 *avail_rcd = count;
4746 }
4747 else
4748 {
4749 *avail_rcd = phb_ctb[type].max_rcd - phb_ctb[type].used_rcd;
4750 }
4751 break;
4752 case LDN:
4753 case LRN:
4754 case LMN:
4755 *max_rcd = phb_ctb[type].max_rcd;
4756 *avail_rcd = phb_ctb[type].max_rcd - phb_ctb[type].used_rcd;
4757 break;
4758 }
4759
4760 #ifdef PHONEBOOK_EXTENSION
4761 ext_type = pb_get_ext_type(type);
4762
4763 if(ext_type NEQ 0xFF)
4764 {
4765 pb_read_ext_status(ext_type, max_ext, used_ext);
4766 }
4767 #endif
4768
4769 return PHB_OK;
4770 }
4771
4772
4773 /*
4774 +------------------------------------------------------------------+
4775 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4776 | STATE : code ROUTINE : pb_get_fdn_mode |
4777 +------------------------------------------------------------------+
4778
4779 PURPOSE :
4780
4781 */
4782 void pb_status_req(UBYTE *mode)
4783 {
4784 /* TRACE_FUNCTION ("pb_status_req()");*/
4785
4786 *mode = phb_stat;
4787 }
4788
4789
4790 /*
4791 +------------------------------------------------------------------+
4792 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4793 | STATE : code ROUTINE : pb_first_free |
4794 +------------------------------------------------------------------+
4795
4796 PURPOSE : On exit, "first_free" contains the index of the first free
4797 location in the specified phonebook.
4798
4799 */
4800 T_PHB_RETURN pb_first_free(
4801 UBYTE type,
4802 SHORT *first_free)
4803 {
4804 SHORT i,bit;
4805 UBYTE max_bitmap;
4806 UBYTE pos;
4807
4808 TRACE_FUNCTION ("pb_first_free()");
4809
4810 if (first_free EQ NULL)
4811 {
4812 ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown);
4813 return(PHB_FAIL);
4814 }
4815
4816 switch (type)
4817 {
4818 case SDN:
4819 case ADN:
4820 case FDN:
4821 case BDN:
4822 case UPN:
4823 case ECC:
4824 switch (type)
4825 {
4826 case ADN: max_bitmap=MAX_ADN_BITMAP; break;
4827 case FDN: max_bitmap=MAX_FDN_BITMAP; break;
4828 case BDN: max_bitmap=MAX_BDN_BITMAP; break;
4829 case UPN: max_bitmap=MAX_UPN_BITMAP; break;
4830 case SDN: max_bitmap=MAX_SDN_BITMAP; break;
4831 case ECC: max_bitmap=MAX_ECC_BITMAP; break;
4832
4833 default:
4834 ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown);
4835 return(PHB_FAIL);
4836 }
4837
4838 bit = 0;
4839 for (i=0; i<max_bitmap; i++)
4840 {
4841 pos = 0;
4842 while ((phb_ctb[type].rcd_bitmap[i] & (1<<pos)))
4843 {
4844 bit++;
4845 pos++;
4846 }
4847
4848 if ((bit%8) OR !pos)
4849 {
4850 if (bit>=phb_ctb[type].max_rcd)
4851 {
4852 *first_free=0;
4853 return(PHB_FULL);
4854 }
4855
4856 *first_free=bit+1;
4857 return(PHB_OK);
4858 }
4859 }
4860
4861 *first_free=0;
4862 return(PHB_FULL);
4863
4864 case LDN:
4865 case LMN:
4866 case LRN:
4867 /*
4868 * It is not possible to specify an index when writing to these
4869 * phonebooks. Whenever a number is added, it automatically goes
4870 * in the first entry of the list, hence it could be said that
4871 * the first free entry is always 1.
4872 */
4873 *first_free=1;
4874 return(PHB_OK);
4875
4876 default:
4877 break;
4878 }
4879
4880 ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown);
4881 return(PHB_FAIL);
4882 }
4883
4884
4885 /*
4886 +--------------------------------------------------------------------+
4887 | PROJECT : MMI-Framework (8417) MODULE: PHB |
4888 | STATE : code ROUTINE : pb_switch_adn_fdn |
4889 +--------------------------------------------------------------------+
4890
4891 PURPOSE :
4892
4893 */
4894
4895 T_PHB_RETURN pb_switch_adn_fdn(UBYTE mode, T_ACI_CLASS aci_classFDN)
4896 {
4897 UBYTE classFDN = (UBYTE) CLASS_None;
4898 TRACE_FUNCTION("pb_switch_adn_fdn()");
4899
4900 pb_set_fdn_input_classtype (aci_classFDN);
4901
4902 if ((mode != FDN_DISABLE) AND (mode != FDN_ENABLE))
4903 return PHB_FAIL; /* never used */
4904
4905 fdn_mode = mode;
4906
4907 if ( fdn_classtype NEQ fdn_input_classtype)
4908 {
4909 fdn_classtype = fdn_input_classtype;
4910 classFDN = fdn_input_classtype;
4911 /* write to ffs */
4912 #ifndef _SIMULATION_
4913 if( ffs_fwrite("/mmi/fdnClassType", &classFDN, sizeof(classFDN)) < 1)
4914 {
4915 TRACE_FUNCTION("sAT_PlusCLCK: ME- failed to write ffs");
4916 }
4917 #endif
4918 }
4919
4920 pb_init_afb();
4921 pb_start_build(FALSE);
4922 return PHB_OK; /* never used */
4923 }
4924
4925
4926 /*
4927 +--------------------------------------------------------------------+
4928 | PROJECT : MMI-Framework (8417) MODULE : PHB |
4929 | STATE : code ROUTINE : cmpWild |
4930 +--------------------------------------------------------------------+
4931
4932 PURPOSE : compare two strings with wild character ('?') recognition
4933 in string1. Returns 0 on mismatch, otherwise 1. An empty
4934 string always match.
4935
4936 */
4937
4938 UBYTE cmpWild (char *s1, char *s2)
4939 {
4940 int i1, i2;
4941
4942 i1 = strlen(s1);
4943 i2 = strlen(s2);
4944
4945 if ( i1 != i2 )
4946 return 0;
4947
4948 while (i1 AND i2)
4949 {
4950 i1--;
4951 i2--;
4952 if (s1[i1] != s2[i2] AND s1[i1] != '?')
4953 return 0;
4954 }
4955
4956 return 1;
4957 }
4958
4959 /*
4960 +--------------------------------------------------------------------+
4961 | PROJECT : GSM-F&D (8411) MODULE : PHB |
4962 | STATE : code ROUTINE : cmpPHBString |
4963 +--------------------------------------------------------------------+
4964
4965 PURPOSE : get the length for PHB entry
4966 */
4967 int pb_get_entry_len ( const UBYTE *pb_tag, UBYTE max_pb_len )
4968 {
4969 int pb_len = 0;
4970 UBYTE inc_count = 1;
4971 BOOL ucs2 = FALSE;
4972 UBYTE chars = 0;
4973
4974 if (*pb_tag EQ 0x80)
4975 {
4976 ucs2 = TRUE;
4977 inc_count = 2; /* check two bytes */
4978 pb_len = 1; /* skip the 0x80 */
4979 }
4980 else if (*pb_tag EQ 0x81 OR *pb_tag EQ 0x82)
4981 {
4982 if (*pb_tag EQ 0x81)
4983 pb_len = 3; /* 0x80 + len + pointer */
4984 else
4985 pb_len = 4; /* 0x80 + len + 2xpointer */
4986
4987 chars = pb_tag[1];
4988 pb_tag += pb_len; /* go to data */
4989 while (chars)
4990 {
4991 if (*pb_tag++ & 0x80)
4992 pb_len+=2;
4993 else
4994 pb_len+=1;
4995
4996 pb_tag++;
4997 chars--;
4998 }
4999 return MINIMUM(pb_len,max_pb_len);
5000 }
5001
5002 while (pb_len < max_pb_len)
5003 {
5004 if (ucs2 EQ TRUE)
5005 {
5006 if (!(pb_len+1 < max_pb_len)) /* Check also if we traverse the upper bound */
5007 break; /* so only a "half" UCS2 element is remaining */
5008 }
5009 if (pb_tag[pb_len] EQ 0xFF)
5010 {
5011 /* one 0xFF indicates the end of a non UCS2 string */
5012 if (ucs2 EQ FALSE)
5013 {
5014 break;
5015 }
5016 /* two 0xFF indicates the end of a UCS2 string */
5017 if (pb_tag[pb_len + 1] EQ 0xFF)
5018 {
5019 break;
5020 }
5021 }
5022 pb_len += inc_count;
5023 }
5024
5025 return (pb_len);
5026 }
5027
5028 /*
5029 +--------------------------------------------------------------------+
5030 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5031 | STATE : code ROUTINE : pb_cmp_phb_entry |
5032 +--------------------------------------------------------------------+
5033
5034 PURPOSE : compare PHB entry (SIM) with T_ACI_PB_TEXT.
5035 cannot compare pb_tag with search_tag return - 1
5036 if pb_tag < search_tag return value < 0
5037 if pb_tag = search_tag return value = 0
5038 if pb_tag > search_tag return value > 0
5039 */
5040 static int pb_cmp_phb_entry ( UBYTE *pb_tag,
5041 UBYTE pb_len,
5042 T_ACI_PB_TEXT *search_tag )
5043 {
5044 UBYTE cmp_len;
5045 UBYTE pb_tag_buf[PHB_MAX_TAG_LEN];
5046 UBYTE *cmp_pb_tag;
5047 UBYTE search_tag_buf[PHB_MAX_TAG_LEN];
5048 UBYTE *cmp_search_tag;
5049 int i;
5050
5051 cmp_len = MINIMUM ( pb_len, search_tag->len );
5052
5053 /* convert to lower cases, when not Unicode */
5054 if ( ( search_tag->cs EQ CS_Sim ) AND
5055 ( ( *search_tag->data NEQ 0x80 ) AND ( *pb_tag NEQ 0x80 ) ) )
5056 {
5057 for (i = 0; i < cmp_len; i++)
5058 pb_tag_buf[i] = (UBYTE)tolower((int)pb_tag[i]);
5059 cmp_pb_tag = pb_tag_buf;
5060
5061 for (i = 0; i < cmp_len; i++)
5062 search_tag_buf[i] = (UBYTE)tolower((int)search_tag->data[i]);
5063 cmp_search_tag = search_tag_buf;
5064 }
5065 else
5066 {
5067 cmp_pb_tag = pb_tag;
5068 cmp_search_tag = search_tag->data;
5069 }
5070 /* check the types */
5071 if ( search_tag->cs EQ CS_Sim )
5072 return ( cmpString ( cmp_pb_tag, cmp_search_tag, cmp_len ) );
5073
5074 if ( ( search_tag->cs EQ CS_Ucs2 ) AND ( *pb_tag EQ 0x80 ) )
5075 return ( memcmp ( cmp_pb_tag + 1, cmp_search_tag, cmp_len ) );
5076
5077 if ( ( search_tag->cs EQ CS_Ucs2 ) AND ( *pb_tag NEQ 0x80 ) )
5078 return pb_cmp2Bytes ( cmp_search_tag, cmp_pb_tag, cmp_len, 1 );
5079
5080 if ( ( search_tag->cs EQ CS_GsmDef ) AND ( *pb_tag EQ 0x80 ) )
5081 return pb_cmp2Bytes ( cmp_search_tag, cmp_pb_tag + 1 , cmp_len, 2 );
5082
5083 if ( ( search_tag->cs EQ CS_GsmDef ) AND ( *pb_tag NEQ 0x80 ) )
5084 {
5085 return ( memcmp ( cmp_pb_tag, cmp_search_tag, cmp_len ) );
5086 }
5087
5088 return ( -1 );
5089 }
5090
5091
5092 /*
5093 +--------------------------------------------------------------------+
5094 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5095 | STATE : code ROUTINE : cmpString |
5096 +--------------------------------------------------------------------+
5097
5098 PURPOSE : compare two strings.
5099 if s1 < s2 return value < 0
5100 if s1 = s2 return value = 0
5101 if s1 > s2 return value > 0
5102 */
5103
5104 static int cmpString ( UBYTE *s1, UBYTE *s2, UBYTE len )
5105 {
5106 int n = 0;
5107
5108 /* TRACE_FUNCTION("cmpString()"); */ /* Called too often to trace */
5109
5110 if ((*s1 EQ 0x80) AND
5111 (*s2 NEQ 0x80) )
5112 {
5113 s1++;
5114 len--;
5115 return pb_cmp2Bytes(s1, s2, len, 1);
5116 }
5117 else if ((*s1 NEQ 0x80) AND
5118 (*s2 EQ 0x80) )
5119 {
5120 s2++;
5121 len--;
5122 return pb_cmp2Bytes(s1, s2, len, 2);
5123 }
5124 else
5125 {
5126 while (*s1 EQ *s2)
5127 {
5128 if (*s1 EQ 0xff)
5129 return 0;
5130 s1++;
5131 s2++;
5132 n++;
5133 if (n EQ len)
5134 return 0;
5135 }
5136
5137 if ((*s1 > *s2) AND (*s1 NEQ 0xff))
5138 return 1;
5139
5140 return -1;
5141 }
5142 }
5143
5144 /*
5145 +--------------------------------------------------------------------+
5146 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5147 | STATE : code ROUTINE : pb_cmp2Bytes |
5148 +--------------------------------------------------------------------+
5149
5150 PURPOSE : compare two strings.
5151 if s1 < s2 return value < 0
5152 if s1 = s2 return value = 0
5153 if s1 > s2 return value > 0
5154
5155 flag = 1, s1 is unicode
5156 flag = 2, s2 is unicode
5157 */
5158
5159 static int pb_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag)
5160 {
5161 int n = 0;
5162
5163 /* TRACE_FUNCTION("pb_cmp2Bytes()"); */
5164
5165 if (flag EQ 1)
5166 {
5167 while ( (*s1 EQ 0x00 OR *s1 EQ 0xFF ) AND ( *(s1+1) EQ *s2) )
5168 {
5169 if (*s1 EQ 0xff AND *(s1+1) EQ 0xFF)
5170 return 0;
5171 s1 += 2;
5172 s2++;
5173 n += 2;
5174
5175 if (n >= len)
5176 return 0;
5177 }
5178
5179 if ( ( *s1 > 0 AND *s1 NEQ 0xff ) OR
5180 ( !*s1 AND ( *(s1+1) > *s2 ) ) )
5181 return 1;
5182
5183 return -1;
5184 }
5185
5186 if (flag EQ 2)
5187 {
5188 while ((*s2 EQ 0x00 OR *s2 EQ 0xFF) AND (*s1 EQ *(s2+1)))
5189 {
5190 if (*s2 EQ 0xff AND *(s2+1) EQ 0xFF)
5191 return 0;
5192 s1++;
5193 s2 += 2;
5194 n += 2;
5195
5196 if (n >= len)
5197 return 0;
5198 }
5199
5200 if ((*s2 > 0 AND *s2 NEQ 0xff) OR
5201 (!*s2 AND (*(s2+1) > *s1)) )
5202 return -1;
5203
5204 return 1;
5205 }
5206 return -1;
5207 }
5208
5209 /*
5210 +--------------------------------------------------------------------+
5211 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5212 | STATE : code ROUTINE : pb_check_number |
5213 +--------------------------------------------------------------------+
5214
5215 PURPOSE : compare two numbers. If they are same, return 1.
5216
5217 */
5218
5219 UBYTE pb_check_number(char *cur_number, char *number)
5220 {
5221 UBYTE len1;
5222 UBYTE len2;
5223
5224 len1 = strlen(cur_number);
5225 len2 = strlen((char *)number);
5226
5227 if (!len2)
5228 return 0; /* Bug Fix: the return value was "1" */
5229
5230 if ((len1>=6) AND (len2>=6))
5231 {
5232 if (cmpWild (&cur_number[len1-6], (char *)&number[len2-6]) EQ 1)
5233 return 1;
5234 }
5235 else
5236 {
5237 if (cmpWild ((char *)cur_number, (char *)number) EQ 1)
5238 return 1;
5239 }
5240 return 0;
5241 }
5242
5243
5244 /*
5245 +--------------------------------------------------------------------+
5246 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5247 | STATE : code ROUTINE : pb_check_fdn |
5248 +--------------------------------------------------------------------+
5249
5250 PURPOSE : check whether phone number is in FDN phonebook.
5251
5252 */
5253 GLOBAL T_PHB_RETURN pb_check_fdn (UBYTE toa,
5254 const UBYTE *number)
5255 {
5256 SHORT cur_index;
5257 CHAR cur_number[MAX_PHB_NUM_LEN];
5258 CHAR new_number[MAX_PHB_NUM_LEN];
5259 UBYTE len1;
5260 UBYTE len2;
5261
5262 len1 = strlen((char *)number);
5263
5264 cur_index = phb_ctb[FDN].first_nrcd;
5265 while (cur_index != UNUSED_INDEX)
5266 {
5267 memset(new_number, 0, sizeof(new_number));
5268 cmhPHB_getAdrStr(cur_number,
5269 MAX_PHB_NUM_LEN - 1,
5270 phb_element[cur_index].entry.number,
5271 phb_element[cur_index].entry.len);
5272
5273 len2 = strlen((char *)cur_number);
5274 if (len1 < len2 OR phb_element[cur_index].entry.len EQ 0)
5275 {
5276 cur_index = phb_element[cur_index].next_nrcd;
5277 continue;
5278 }
5279 else
5280 {
5281 strncpy(new_number, (char *)number, len2);
5282 if (cmpWild ((char *)&cur_number, new_number) EQ 1)
5283 {
5284
5285 if ( toa NEQ 0 ) /* ACI-SPR-11927:check whether to test toa or not */
5286 {
5287 if ((toa NEQ phb_element[cur_index].entry.ton_npi) AND
5288 (phb_element[cur_index].entry.ton_npi NEQ 0xFF) ) /* VO patch 02.03.01 */
5289 {
5290 cur_index = phb_element[cur_index].next_nrcd;
5291 continue;
5292 }
5293 }
5294
5295 causeMod = P_CEER_mod; /* Clear module which was set for ceer */
5296 causeCeer = CEER_NotPresent; /* Reset cause - number to dial found in FDN list. */
5297 return PHB_OK;
5298 }
5299 }
5300
5301 cur_index = phb_element[cur_index].next_nrcd;
5302 }
5303 causeMod = P_CEER_sim; /* Set ceer module to sim */
5304 causeCeer = P_CEER_InvalidFDN; /* Set cause - number to dial not found in FDN list.*/
5305 return PHB_FAIL;
5306 }
5307
5308 /*
5309 +------------------------------------------------- -------------+
5310 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5311 | STATE : code ROUTINE : pb_exit |
5312 +---------------------------------------------------------------+
5313
5314 PURPOSE : Save the phonebook in SIM card.
5315
5316 */
5317
5318 void pb_exit()
5319 {
5320 TRACE_FUNCTION("pb_exit()");
5321
5322 pb_write_eeprom();
5323 if(pb_init_sync_sim(LDN) EQ FALSE)
5324 pb_finish_sync_sim(); /* this will otherwise be called after the last record written*/
5325 }
5326
5327
5328 /*
5329 +------------------------------------------------------------------+
5330 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5331 | STATE : code ROUTINE : pb_write_sim_cb |
5332 +------------------------------------------------------------------+
5333
5334
5335 PURPOSE : Call back for write phonebook in SIM card.
5336
5337 */
5338
5339 void pb_write_sim_cb(SHORT table_id)
5340 {
5341 UBYTE type;
5342
5343 TRACE_FUNCTION("pb_write_sim_cb()");
5344
5345 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
5346
5347 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
5348 {
5349 TRACE_ERROR("pb_write_sim_cb(): error for writing");
5350 db_index = UNUSED_INDEX;
5351 phb_stat = PHB_READY;
5352 cmhPHB_StatIndication( PHB_WRITE_FAIL,
5353 (SHORT)cmhSIM_GetCmeFromSim( simShrdPrm.atb[table_id].errCode ),
5354 FALSE ); /* don't indicate for write */
5355 return;
5356 }
5357 if (db_index NEQ UNUSED_INDEX)
5358 {
5359 switch (simShrdPrm.atb[table_id].reqDataFld)
5360 {
5361 case SIM_ADN:
5362 type = ADN;
5363 break;
5364 case SIM_FDN:
5365 type = FDN;
5366 break;
5367 case SIM_BDN:
5368 type = BDN;
5369 break;
5370 case SIM_SDN:
5371 type = SDN;
5372 break;
5373 case SIM_MSISDN:
5374 type = UPN;
5375 break;
5376 default:
5377 return;
5378 }
5379 pb_delete_sim_book(type);
5380 }
5381 else
5382 {
5383 phb_stat = PHB_READY;
5384 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE );
5385 }
5386 }
5387
5388 /*
5389 +-----------------------------------------------------------------+
5390 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5391 | STATE : code ROUTINE : pb_write_sim |
5392 +-----------------------------------------------------------------+
5393
5394
5395 PURPOSE : Write phonebook in SIM card.
5396
5397 */
5398
5399 T_PHB_RETURN pb_write_sim(UBYTE type, UBYTE rcd_num)
5400 {
5401 SHORT table_id;
5402 USHORT data_id;
5403
5404 TRACE_FUNCTION("pb_write_sim()");
5405
5406 switch (type)
5407 {
5408 case ADN:
5409 data_id = SIM_ADN;
5410 break;
5411 case FDN:
5412 data_id = SIM_FDN;
5413 break;
5414 case BDN:
5415 data_id = SIM_BDN;
5416 break;
5417 case SDN:
5418 data_id = SIM_SDN;
5419 break;
5420 case UPN:
5421 data_id = SIM_MSISDN;
5422 break;
5423 case LDN:
5424 data_id = SIM_LND;
5425 break;
5426 default:
5427 return PHB_FAIL;
5428 }
5429
5430 table_id = psaSIM_atbNewEntry();
5431 if(table_id EQ NO_ENTRY)
5432 {
5433 TRACE_ERROR ("pb_write_sim(): no more table entries");
5434 return (PHB_FAIL);
5435 }
5436
5437 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
5438 simShrdPrm.atb[table_id].accType = ACT_WR_REC;
5439 simShrdPrm.atb[table_id].v_path_info = FALSE;
5440 simShrdPrm.atb[table_id].reqDataFld = data_id;
5441 simShrdPrm.atb[table_id].recNr = rcd_num;
5442 simShrdPrm.atb[table_id].dataLen = phb_ctb[type].alpha_len + 14;
5443 simShrdPrm.atb[table_id].exchData = data;
5444 simShrdPrm.atb[table_id].rplyCB = pb_write_sim_cb;
5445
5446 simShrdPrm.aId = table_id;
5447
5448 if(psaSIM_AccessSIMData() < 0)
5449 {
5450 TRACE_EVENT("pb_write_sim(): psaSIM_AccessSIMData() failed");
5451 return (PHB_FAIL);
5452 }
5453
5454 phb_stat = PHB_BUSY;
5455 cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, FALSE );
5456
5457 return (PHB_EXCT);
5458 }
5459
5460
5461
5462 #ifdef PHONEBOOK_EXTENSION
5463 /*
5464 +----------------------------------------------------------------------+
5465 | PROJECT : MODULE : PHB |
5466 | STATE : code ROUTINE : pb_prepare_ext_data |
5467 +----------------------------------------------------------------------+
5468
5469
5470 PURPOSE : Prepare the data for the extention record.
5471 If NULL pointer is given for number and subaddress
5472 then the extention record will marked as unused
5473
5474 */
5475
5476
5477 LOCAL void pb_prepare_ext_data(UBYTE *number, UBYTE no_len,
5478 UBYTE *subaddr, UBYTE sub_len,
5479 USHORT file_id)
5480 {
5481 memset(data, 0xFF, sizeof(data));
5482
5483 if ((subaddr != NULL) AND (*subaddr != 0xFF))
5484 {
5485 TRACE_EVENT ("SUBADDRESS EXTENTION");
5486 data[0] = 1;
5487 data[1] = sub_len;
5488 memcpy (data + 2, subaddr, 11);
5489 }
5490 else if (number != NULL)
5491 {
5492 data[0] = 2;
5493 data[1] = no_len - 10;
5494 memcpy (data + 2, number + 10, no_len);
5495 }
5496 }
5497
5498
5499 /*
5500 +----------------------------------------------------------------------+
5501 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5502 | STATE : code ROUTINE : pb_write_sim_ext_cb |
5503 +----------------------------------------------------------------------+
5504
5505
5506 PURPOSE : Call back for write phonebook in SIM card.
5507
5508 */
5509
5510 void pb_write_sim_ext_cb(SHORT table_id)
5511 {
5512 /* USHORT ext_type;
5513 UBYTE rcd_num;*/
5514
5515 TRACE_FUNCTION("pb_write_sim_ext_cb");
5516
5517 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
5518
5519 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
5520 {
5521 TRACE_ERROR("pb_write_sim_ext_cb (): FATAL ERROR");
5522 }
5523 }
5524
5525
5526 /*
5527 +-------------------------------------------------------------------+
5528 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5529 | STATE : code ROUTINE : pb_write_sim_ext |
5530 +-------------------------------------------------------------------+
5531
5532
5533 PURPOSE : Write phonebook in SIM card.
5534
5535 */
5536
5537 T_PHB_RETURN pb_write_sim_ext(USHORT data_id, UBYTE rcd_num)
5538 {
5539 SHORT table_id;
5540
5541 table_id = psaSIM_atbNewEntry();
5542
5543 if(table_id EQ NO_ENTRY)
5544 {
5545 TRACE_ERROR ("pb_write_sim_ext(): no more table entries");
5546 return (PHB_FAIL);
5547 }
5548
5549 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
5550 simShrdPrm.atb[table_id].accType = ACT_WR_REC;
5551 simShrdPrm.atb[table_id].v_path_info = FALSE;
5552 simShrdPrm.atb[table_id].reqDataFld = data_id;
5553 simShrdPrm.atb[table_id].recNr = rcd_num;
5554 simShrdPrm.atb[table_id].dataLen = 13;
5555 simShrdPrm.atb[table_id].exchData = data;
5556 simShrdPrm.atb[table_id].rplyCB = pb_write_sim_ext_cb;
5557
5558 simShrdPrm.aId = table_id;
5559
5560 if (psaSIM_AccessSIMData() < 0)
5561 {
5562 TRACE_ERROR("pb_write_sim_ext(): psaSIM_AccessSIMData() failed");
5563 return (PHB_FAIL);
5564 }
5565
5566 return (PHB_EXCT);
5567 }
5568 #endif /* PHONEBOOK_EXTENSION */
5569
5570 /*
5571 +------------------------------------------------------------------+
5572 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5573 | STATE : code ROUTINE : pb_write_eepron_req |
5574 +------------------------------------------------------------------+
5575
5576
5577 PURPOSE : Write phonebook in EEPROM.
5578
5579 */
5580
5581 void pb_write_eeprom()
5582 {
5583 SHORT ptr_index;
5584 UBYTE ptr_byte_index;
5585 int i;
5586 UBYTE count;
5587 EF_UPN *p = (EF_UPN *)data;
5588
5589 /* TRACE_FUNCTION ("pb_write_eeprom_req()"); */
5590
5591 /* Write Last Dialing Numbers */
5592 ptr_byte_index = (UBYTE)phb_ctb[LDN].first_rcd;
5593
5594 count = 0;
5595 for (i=0; i<phb_ctb[LDN].max_rcd; i++)
5596 {
5597 if (count < phb_ctb[LDN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5598 {
5599 TRACE_EVENT_P1("--- LDN: copy to eeprom for ptr_byte_index %d", ptr_byte_index);
5600 pb_copy_ldn_record((SHORT)ptr_byte_index, 1);
5601 }
5602 else
5603 memset(&data[0], 0xFF, SIZE_EF_LDN);
5604
5605 if (pcm_WriteRecord((UBYTE *)EF_LDN_ID,
5606 (USHORT)(i+1),
5607 SIZE_EF_LDN,
5608 &data[0]) NEQ DRV_OK)
5609 break;
5610 if (ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5611 ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd;
5612 count++;
5613 }
5614
5615 /* Write Last received Numbers */
5616 ptr_byte_index = (UBYTE)phb_ctb[LRN].first_rcd;
5617
5618 count = 0;
5619 for (i=0; i<phb_ctb[LRN].max_rcd; i++)
5620 {
5621 if (count < phb_ctb[LRN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5622 pb_copy_lrn_record(ptr_byte_index, 1);
5623 else
5624 memset(&data[0], 0xFF, SIZE_EF_LRN);
5625
5626 if (pcm_WriteRecord((UBYTE *)EF_LRN_ID,
5627 (USHORT)(i+1),
5628 SIZE_EF_LRN,
5629 &data[0]) NEQ DRV_OK)
5630 break;
5631 if (ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5632 ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd;
5633 count++;
5634 }
5635
5636 /* Write Last missed Numbers */
5637 ptr_byte_index = (UBYTE)phb_ctb[LMN].first_rcd;
5638
5639 count = 0;
5640 for (i=0; i<phb_ctb[LMN].max_rcd; i++)
5641 {
5642 if (count < phb_ctb[LMN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5643 pb_copy_lmn_record(ptr_byte_index, 1);
5644 else
5645 memset(&data[0], 0xFF, SIZE_EF_LMN);
5646
5647 if (pcm_WriteRecord((UBYTE *)EF_LMN_ID,
5648 (USHORT)(i+1),
5649 SIZE_EF_LMN,
5650 &data[0]) NEQ DRV_OK)
5651 break;
5652 if (ptr_byte_index NEQ UNUSED_BYTE_INDEX)
5653 ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd;
5654 count++;
5655 }
5656
5657 /* Write user person Numbers */
5658 if (phb_ctb[UPN].mem EQ TE_MEMORY)
5659 {
5660 ptr_index = phb_ctb[UPN].first_rcd;
5661
5662 count = 0;
5663 for (i=0; i<phb_ctb[UPN].max_rcd; i++)
5664 {
5665 if (count < phb_ctb[UPN].used_rcd AND ptr_index NEQ UNUSED_INDEX)
5666 {
5667 /* copy record */
5668 memcpy(p->alphId,
5669 phb_element[ptr_index].entry.tag,
5670 10*sizeof(UBYTE));
5671 p->len = phb_element[ptr_index].entry.len;
5672 p->numTp = phb_element[ptr_index].entry.ton_npi;
5673 memcpy(p->usrNum,
5674 phb_element[ptr_index].entry.number,
5675 10*sizeof(UBYTE));
5676 p->ccp = phb_element[ptr_index].entry.cc_id;
5677 }
5678 else
5679 memset(&data[0], 0xFF, SIZE_EF_UPN);
5680
5681 if (pcm_WriteRecord((UBYTE *)EF_UPN_ID,
5682 (USHORT)(i+1),
5683 SIZE_EF_UPN,
5684 &data[0]) NEQ DRV_OK)
5685 break;
5686 if (ptr_index NEQ UNUSED_INDEX)
5687 ptr_index = phb_element[ptr_index].next_rcd;
5688 count++;
5689 }
5690 }
5691 }
5692
5693
5694 /*
5695 +------------------------------------------------------------------+
5696 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5697 | STATE : code ROUTINE : pb_copy_ldn_record |
5698 +------------------------------------------------------------------+
5699
5700
5701 PURPOSE : Copy a LDN record.
5702 flag = 0: from EEPROM to local
5703 flag = 1: from local to EEPROM
5704
5705 */
5706
5707 void pb_copy_ldn_record(SHORT index, UBYTE flag)
5708 {
5709 EF_LDN *p = (EF_LDN *)data;
5710
5711 /* TRACE_FUNCTION ("pb_copy_ldn_record()");*/
5712 if (!flag)
5713 {
5714 phb_l_element[index].entry.year = p->year;
5715 phb_l_element[index].entry.month = p->month;
5716 phb_l_element[index].entry.day = p->day;
5717 phb_l_element[index].entry.hour = p->hour;
5718 phb_l_element[index].entry.minute = p->minute;
5719 phb_l_element[index].entry.second = p->second;
5720 phb_l_element[index].entry.len = p->len;
5721 phb_l_element[index].entry.ton_npi = p->numTp;
5722 memcpy((char *)phb_l_element[index].entry.number,
5723 (char *)&p->dldNum, 10);
5724 phb_l_element[index].entry.cc_id = p->ccp;
5725 }
5726 if (flag EQ 1)
5727 {
5728 p->calDrMsb = 0xFF;
5729 p->calDrLsb = 0xFF;
5730 p->year = phb_l_element[index].entry.year;
5731 p->month = phb_l_element[index].entry.month;
5732 p->day = phb_l_element[index].entry.day;
5733 p->hour = phb_l_element[index].entry.hour;
5734 p->minute = phb_l_element[index].entry.minute;
5735 p->second = phb_l_element[index].entry.second;
5736 p->len = phb_l_element[index].entry.len;
5737 p->numTp = phb_l_element[index].entry.ton_npi;
5738 memcpy((char *)p->dldNum,
5739 (char *)phb_l_element[index].entry.number, 10);
5740 p->ccp = phb_l_element[index].entry.cc_id;
5741 p->ext1 = 0xFF;
5742 }
5743 }
5744
5745
5746 /*
5747 +------------------------------------------------------------------+
5748 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5749 | STATE : code ROUTINE : pb_copy_lrn_record |
5750 +------------------------------------------------------------------+
5751
5752
5753 PURPOSE : Copy a LRN record.
5754 flag = 0: from EEPROM to local
5755 flag = 1: from local to EEPROM
5756
5757 */
5758
5759 void pb_copy_lrn_record(SHORT index, UBYTE flag)
5760 {
5761 EF_LRN *p = (EF_LRN *)data;
5762
5763 /* TRACE_FUNCTION ("pb_copy_lrn_record()");*/
5764
5765 if (!flag)
5766 {
5767 phb_l_element[index].entry.year = p->year;
5768 phb_l_element[index].entry.month = p->month;
5769 phb_l_element[index].entry.day = p->day;
5770 phb_l_element[index].entry.hour = p->hour;
5771 phb_l_element[index].entry.minute = p->minute;
5772 phb_l_element[index].entry.second = p->second;
5773 phb_l_element[index].entry.len = p->len;
5774 phb_l_element[index].entry.ton_npi = p->numTp;
5775 memcpy((char *)phb_l_element[index].entry.number,
5776 (char *)p->dldNum, 10);
5777 phb_l_element[index].entry.cc_id = p->ccp;
5778 }
5779 if (flag EQ 1)
5780 {
5781 p->calDrMsb = 0xFF;
5782 p->calDrLsb = 0xFF;
5783 p->year = phb_l_element[index].entry.year;
5784 p->month = phb_l_element[index].entry.month;
5785 p->day = phb_l_element[index].entry.day;
5786 p->hour = phb_l_element[index].entry.hour;
5787 p->minute = phb_l_element[index].entry.minute;
5788 p->second = phb_l_element[index].entry.second;
5789 p->id = 0xFF;
5790 p->len = phb_l_element[index].entry.len;
5791 p->numTp = phb_l_element[index].entry.ton_npi;
5792 memcpy((char *)p->dldNum,
5793 (char *)phb_l_element[index].entry.number, 10);
5794 p->ccp = phb_l_element[index].entry.cc_id;
5795 p->ext1 = 0xFF;
5796 }
5797 }
5798
5799
5800 /*
5801 +------------------------------------------------------------------+
5802 | PROJECT : MMI-Framework (8417) MODULE : PHB |
5803 | STATE : code ROUTINE : pb_copy_lmn_record |
5804 +------------------------------------------------------------------+
5805
5806
5807 PURPOSE : Copy a LMN record.
5808 flag = 0: from EEPROM to local
5809 flag = 1: from local to EEPROM
5810
5811 */
5812
5813 void pb_copy_lmn_record(SHORT index, UBYTE flag)
5814 {
5815 EF_LMN *p = (EF_LMN *)data;
5816
5817 /* TRACE_FUNCTION ("pb_copy_lmn_record()");*/
5818
5819 if (!flag)
5820 {
5821 phb_l_element[index].entry.year = p->year;
5822 phb_l_element[index].entry.month = p->month;
5823 phb_l_element[index].entry.day = p->day;
5824 phb_l_element[index].entry.hour = p->hour;
5825 phb_l_element[index].entry.minute = p->minute;
5826 phb_l_element[index].entry.second = p->second;
5827 phb_l_element[index].entry.len = p->len;
5828 phb_l_element[index].entry.ton_npi = p->numTp;
5829 memcpy((char *)phb_l_element[index].entry.number,
5830 (char *)p->dldNum, 10);
5831 phb_l_element[index].entry.cc_id = p->ccp;
5832 }
5833 if (flag EQ 1)
5834 {
5835 p->year = phb_l_element[index].entry.year;
5836 p->month = phb_l_element[index].entry.month;
5837 p->day = phb_l_element[index].entry.day;
5838 p->hour = phb_l_element[index].entry.hour;
5839 p->minute = phb_l_element[index].entry.minute;
5840 p->second = phb_l_element[index].entry.second;
5841 p->id = 0xFF;
5842 p->len = phb_l_element[index].entry.len;
5843 p->numTp = phb_l_element[index].entry.ton_npi;
5844 memcpy((char *)p->dldNum,
5845 (char *)phb_l_element[index].entry.number, 10);
5846 p->ccp = phb_l_element[index].entry.cc_id;
5847 p->ext1 = 0xFF;
5848 }
5849 }
5850
5851 /*
5852 +------------------------------------------------------------------------+
5853 | PROJECT : MMI-Framework (8417) MODULE: PHB |
5854 | STATE : code ROUTINE : pb_delete_book |
5855 +------------------------------------------------------------------------+
5856
5857 PURPOSE : Delete a phonebook in SIM card.
5858
5859 */
5860
5861 T_PHB_RETURN pb_delete_book(UBYTE book)
5862 {
5863 SHORT cur_index;
5864
5865 TRACE_FUNCTION("pb_delete_book()");
5866
5867 /* check whether this phonebook exists */
5868 if (phb_ctb[book].mem EQ NO_PHB_ENTRY)
5869 return PHB_FAIL;
5870
5871 phb_stat = PHB_BUSY;
5872 cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, FALSE );
5873
5874 cur_index = phb_ctb[book].first_rcd;
5875 while (cur_index != UNUSED_INDEX)
5876 {
5877 phb_element[cur_index].free = PHB_ELEMENT_FREE;
5878 if ((book EQ ADN) OR (book EQ FDN))
5879 {
5880 pb_mname_chain(book,
5881 phb_element[cur_index].prev_mtrcd,
5882 cur_index,
5883 phb_element[cur_index].next_mtrcd);
5884 pb_mnum_chain(book,
5885 phb_element[cur_index].prev_mnrcd,
5886 cur_index,
5887 phb_element[cur_index].next_mnrcd);
5888 }
5889 cur_index = phb_element[cur_index].next_rcd;
5890 }
5891 phb_ctb[book].used_rcd = 0;
5892 /* phb_ctb[book].first_rcd = UNUSED_INDEX;*/
5893 phb_ctb[book].first_trcd = UNUSED_INDEX;
5894 phb_ctb[book].first_nrcd = UNUSED_INDEX;
5895 phb_ctb[book].first_mtrcd = UNUSED_INDEX; /* ??? */
5896 phb_ctb[book].first_mnrcd = UNUSED_INDEX; /* ??? */
5897 switch (book)
5898 {
5899 case ADN:
5900 memset(phb_ctb[book].rcd_bitmap, 0, MAX_ADN_BITMAP);
5901 break;
5902 case FDN:
5903 memset(phb_ctb[book].rcd_bitmap, 0, MAX_FDN_BITMAP);
5904 break;
5905 case BDN:
5906 memset(phb_ctb[book].rcd_bitmap, 0, MAX_BDN_BITMAP);
5907 break;
5908 case SDN:
5909 memset(phb_ctb[book].rcd_bitmap, 0, MAX_SDN_BITMAP);
5910 break;
5911 case UPN:
5912 memset(phb_ctb[book].rcd_bitmap, 0, MAX_UPN_BITMAP);
5913 break;
5914 default:
5915 break;
5916 }
5917 pb_delete_sim_book(book);
5918 return PHB_OK;
5919 }
5920
5921 /*
5922 +------------------------------------------------------------------------+
5923 | PROJECT : MMI-Framework (8417) MODULE: PHB |
5924 | STATE : code ROUTINE : pb_delete_sim_book |
5925 +------------------------------------------------------------------------+
5926
5927 PURPOSE : Delete a phonebook in SIM card.
5928
5929 */
5930
5931 void pb_delete_sim_book(UBYTE book)
5932 {
5933 if (db_index EQ UNUSED_INDEX)
5934 {
5935 db_index = phb_ctb[book].first_rcd;
5936 phb_ctb[book].first_rcd = UNUSED_INDEX;
5937 }
5938 else
5939 db_index = phb_element[db_index].next_rcd;
5940 if (db_index NEQ UNUSED_INDEX)
5941 {
5942 memset(data, 0xFF, sizeof(data));
5943 if (pb_write_sim(book, phb_element[db_index].entry.index) EQ PHB_FAIL)
5944 {
5945 db_index = UNUSED_INDEX;
5946 phb_stat = PHB_READY;
5947 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE );
5948 }
5949 //TISH delete related EXT element
5950 #ifdef PHONEBOOK_EXTENSION
5951 else
5952 {
5953 if (phb_element[db_index].entry.ext_rcd_num!=0xFF)
5954 {
5955 USHORT file_id = 0;
5956 pb_rem_ext_record_flag (book, phb_element[db_index].entry.ext_rcd_num);
5957 file_id = pb_get_ext_file_id (book);
5958 pb_prepare_ext_data (NULL, 0, NULL, 0, file_id);
5959 pb_write_sim_ext(file_id, phb_element[db_index].entry.ext_rcd_num);
5960 }
5961 }
5962 #endif
5963 }
5964 else
5965 {
5966 db_index = UNUSED_INDEX;
5967 phb_stat = PHB_READY;
5968 cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE );
5969 }
5970 }
5971
5972
5973
5974 /*
5975 +------------------------------------------------------------------------+
5976 | PROJECT : MMI-Framework (8417) MODULE: PHB |
5977 | STATE : code ROUTINE : pb_update_ecc_fu |
5978 +------------------------------------------------------------------------+
5979
5980 PURPOSE : Read emergency call numbers from SIM card.
5981
5982 */
5983 #ifdef SIM_TOOLKIT
5984 BOOL pb_update_ecc_fu(int ref, T_SIM_FILE_UPDATE_IND *fu)
5985 {
5986
5987 BOOL found = FALSE;
5988 UBYTE i;
5989 TRACE_FUNCTION ("pb_update_ecc_fu()");
5990
5991 for (i = 0; i < (int)fu->val_nr; i++)
5992 {
5993 if (!found AND fu->file_info[i].v_path_info EQ TRUE AND
5994 fu->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND
5995 fu->file_info[i].path_info.v_df_level2 EQ FALSE AND
5996 fu->file_info[i].datafield EQ SIM_ECC)
5997 {
5998 found = TRUE;
5999 }
6000 }
6001
6002 if (found)
6003 {
6004 simShrdPrm.fuRef = ref;
6005 pb_update_ecc();
6006 return FALSE; /* reading files */
6007 }
6008 else
6009 {
6010 return TRUE; /* nothing to do */
6011 }
6012 }
6013 #endif
6014
6015 /*
6016 +------------------------------------------------------------------------+
6017 | PROJECT : MMI-Framework (8417) MODULE: PHB |
6018 | STATE : code ROUTINE : pb_update_ecc |
6019 +------------------------------------------------------------------------+
6020
6021 PURPOSE : Read emergency call numbers from SIM card.
6022
6023 */
6024
6025 void pb_update_ecc(void)
6026 {
6027 TRACE_FUNCTION("pb_update_ecc()");
6028 if ((fdn_mode != NO_OPERATION) AND (simShrdPrm.fuRef EQ -1))
6029 return;
6030
6031 phb_ctb[ECC].mem = SIM_MEMORY;
6032
6033 phb_ctb[ECC].type = ECC;
6034 phb_ctb[ECC].first_trcd = UNUSED_INDEX;
6035 pb_read_sim_ecc();
6036
6037 }
6038
6039 /*
6040 +------------------------------------------------------------------------+
6041 | PROJECT : MMI-Framework (8417) MODULE: PHB |
6042 | STATE : code ROUTINE : pb_read_sim_ecc |
6043 +------------------------------------------------------------------------+
6044
6045 PURPOSE : Read EC number from SIM card.
6046
6047 */
6048
6049 void pb_read_sim_ecc (void)
6050 {
6051 TRACE_FUNCTION ("pb_read_sim_ecc()");
6052
6053 if (pb_read_sim_dat(SIM_ECC, NOT_PRESENT_8BIT, (UBYTE)256) EQ FALSE ) /* give the max length 256 */
6054 pb_read_eeprom_ecc();
6055 }
6056
6057 /*
6058 +------------------------------------------------------------------------+
6059 | PROJECT : MMI-Framework (8417) MODULE: PHB |
6060 | STATE : code ROUTINE : pb_read_eeprom_ecc |
6061 +------------------------------------------------------------------------+
6062
6063 PURPOSE : Read EC number from EEPROM.
6064
6065 */
6066
6067 void pb_read_eeprom_ecc (void)
6068 {
6069 EF_ECC efecc;
6070 UBYTE *data_ptr;
6071 UBYTE version;
6072 int i;
6073
6074 phb_ctb[ECC].mem = TE_MEMORY;
6075 phb_ctb[ECC].type = ECC;
6076 phb_ctb[ECC].max_rcd = MAX_ECC_RCD;
6077 phb_ctb[ECC].first_trcd = UNUSED_INDEX;
6078
6079 if (pcm_ReadFile((UBYTE *)EF_ECC_ID,
6080 SIZE_EF_ECC,
6081 (UBYTE *)&efecc,
6082 &version) EQ DRV_OK)
6083 {
6084
6085
6086
6087 { /* workaround when invalid data stored on PCM */
6088 CHAR ecc_number[MAX_PHB_NUM_LEN];
6089 int j;
6090
6091 data_ptr = &efecc.ecc1[0];
6092
6093 for (i=0; i < phb_ctb[ECC].max_rcd; i++)
6094 {
6095 if (*data_ptr NEQ 0xFF)
6096 {
6097 cmhPHB_getAdrStr (ecc_number,
6098 MAX_PHB_NUM_LEN - 1,
6099 data_ptr,
6100 3);
6101 for (j = 0; j < 3; j++)
6102 {
6103 if (!isdigit (ecc_number[j]))
6104 {
6105 TRACE_EVENT_P2 ("[ERR] pb_read_eeprom_ecc(): invalid character found %c (%d)",
6106 ecc_number[j], i);
6107 return;
6108 }
6109 }
6110 }
6111 data_ptr += 3;
6112 }
6113 } /* workaround end */
6114
6115 data_ptr = &efecc.ecc1[0];
6116
6117 for (i=0; i < phb_ctb[ECC].max_rcd; i++)
6118 {
6119 pb_copy_ecc_entry(data_ptr, (UBYTE)i);
6120 data_ptr += 3;
6121 }
6122 }
6123 }
6124
6125 /*
6126 +------------------------------------------------------------------------+
6127 | PROJECT : MMI-Framework (8417) MODULE: PHB |
6128 | STATE : code ROUTINE : pb_copy_ecc_entry |
6129 +------------------------------------------------------------------------+
6130
6131 PURPOSE : Read EC number from EEPROM.
6132
6133 */
6134
6135 void pb_copy_ecc_entry (UBYTE *ecc, UBYTE num)
6136 {
6137 SHORT index;
6138 /* TRACE_FUNCTION("pb_copy_ecc_entry()"); */
6139 if (*ecc NEQ 0xff)
6140 {
6141 /* search a free element in phonebook element table */
6142 if (pb_create_memory(&index) NEQ PHB_OK)
6143 return;
6144
6145 phb_ctb[ECC].used_rcd++;
6146 phb_ctb[ECC].rcd_bitmap[0] |= (UBYTE)(0x01 << num);
6147
6148 phb_element[index].type = ECC;
6149 phb_element[index].entry.index = (UBYTE)(num+1);
6150 phb_element[index].entry.len = 3;
6151 memcpy(phb_element[index].entry.number, ecc, 3);
6152
6153 pb_record_sort(index);
6154 pb_num_sort(index);
6155
6156 phb_element[index].prev_trcd = UNUSED_INDEX;
6157 phb_element[index].next_trcd = UNUSED_INDEX;
6158 }
6159 }
6160
6161
6162 /*
6163 +----------------------------------------------------------------------+
6164 | PROJECT: MMI-Framework (8417) MODULE: PHB |
6165 | STATE : code ROUTINE: pb_read_sim_dat |
6166 +----------------------------------------------------------------------+
6167
6168
6169 PURPOSE : Request to read SIM card.
6170
6171 */
6172
6173 BOOL pb_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length)
6174 {
6175 SHORT table_id;
6176
6177 TRACE_FUNCTION ("pb_read_sim_dat()");
6178
6179 table_id = psaSIM_atbNewEntry();
6180
6181 if(table_id NEQ NO_ENTRY)
6182 {
6183 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
6184 simShrdPrm.atb[table_id].accType = ACT_RD_DAT;
6185 simShrdPrm.atb[table_id].v_path_info = FALSE;
6186 simShrdPrm.atb[table_id].reqDataFld = data_id;
6187 simShrdPrm.atb[table_id].dataOff = 0;
6188 simShrdPrm.atb[table_id].dataLen = len;
6189 simShrdPrm.atb[table_id].recMax = max_length;
6190 simShrdPrm.atb[table_id].exchData = NULL;
6191 simShrdPrm.atb[table_id].rplyCB = pb_read_sim_dat_cb;
6192
6193 simShrdPrm.aId = table_id;
6194
6195 if(psaSIM_AccessSIMData() < 0)
6196 {
6197 TRACE_EVENT("FATAL ERROR");
6198 return FALSE;
6199 }
6200 return TRUE;
6201 }
6202 return FALSE;
6203 }
6204
6205 /*
6206 +----------------------------------------------------------------------+
6207 | PROJECT: MMI-Framework (8417) MODULE: PHB |
6208 | STATE : code ROUTINE: pb_read_sim_dat_cb |
6209 +----------------------------------------------------------------------+
6210
6211
6212 PURPOSE : Call back for SIM read.
6213
6214 */
6215 void pb_read_sim_dat_cb(SHORT table_id)
6216 {
6217 int i;
6218 UBYTE *data_ptr;
6219
6220 TRACE_FUNCTION ("pb_read_sim_dat_cb()");
6221
6222 switch (simShrdPrm.atb[table_id].reqDataFld)
6223 {
6224 case SIM_ECC:
6225 data_ptr = simShrdPrm.atb[table_id].exchData;
6226 if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
6227 {
6228 phb_ctb[ECC].max_rcd = (SHORT)simShrdPrm.atb[table_id].dataLen/3;
6229
6230 for (i=0; i < phb_ctb[ECC].max_rcd; i++)
6231 {
6232 pb_copy_ecc_entry(data_ptr, (UBYTE)i);
6233 data_ptr += 3;
6234 }
6235 #ifdef SIM_TOOLKIT
6236 if (simShrdPrm.fuRef >= 0)
6237 {
6238 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCCESS);
6239 }
6240 #endif
6241 }
6242 else
6243 {
6244 #ifdef SIM_TOOLKIT
6245 if (simShrdPrm.fuRef >= 0)
6246 {
6247 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR);
6248 }
6249 #endif
6250 pb_read_eeprom_ecc();
6251 }
6252 break;
6253
6254 case SIM_SST:
6255 data_ptr = simShrdPrm.atb[table_id].exchData;
6256 if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
6257 {
6258 /* copy SIM service table */
6259 memset(sim_service_table, 0, sizeof(sim_service_table));
6260 memcpy(sim_service_table,
6261 simShrdPrm.atb[table_id].exchData,
6262 MINIMUM(MAX_SRV_TBL, simShrdPrm.atb[table_id].dataLen));
6263
6264 /* initialisation of the all SIM phonebooks */
6265 pb_sat_update_reset(SIM_ADN);
6266 pb_sat_update_reset(SIM_FDN);
6267 pb_sat_update_reset(SIM_BDN);
6268 pb_sat_update_reset(SIM_SDN);
6269 pb_sat_update_reset(SIM_MSISDN);
6270
6271 /* start reading SIM phonebook */
6272 pb_start_build(FALSE);
6273 }
6274 else
6275 pb_start_build(FALSE);
6276 break;
6277
6278 default:
6279 break;
6280 }
6281 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
6282 }
6283
6284 /*
6285 +----------------------------------------------------------------------+
6286 | PROJECT: MMI-Framework MODULE : PHB |
6287 | STATE : code ROUTINE: pb_set_compare |
6288 +----------------------------------------------------------------------+
6289
6290
6291 PURPOSE : set a external MMI compare function for phonebook entries
6292 */
6293
6294 void pb_set_compare_fct (T_PHB_EXT_CMP_FCT compare_fct)
6295 {
6296 ext_compare_fct = compare_fct;
6297 }
6298
6299 /*
6300 +----------------------------------------------------------------------+
6301 | PROJECT: MMI-Framework MODULE : PHB |
6302 | STATE : code ROUTINE: pb_get_fdn_input_classtype |
6303 +----------------------------------------------------------------------+
6304
6305
6306 PURPOSE : get fdn_input_classtype
6307 */
6308
6309 T_ACI_CLASS pb_get_fdn_input_classtype (void)
6310 {
6311 return fdn_input_classtype;
6312 }
6313
6314 /*
6315 +----------------------------------------------------------------------+
6316 | PROJECT: MMI-Framework MODULE : PHB |
6317 | STATE : code ROUTINE: pb_set_fdn_input_classtype |
6318 +----------------------------------------------------------------------+
6319
6320
6321 PURPOSE : set fdn_input_classtype
6322 */
6323
6324 void pb_set_fdn_input_classtype (T_ACI_CLASS classtype)
6325 {
6326 fdn_input_classtype = classtype;
6327 }
6328
6329 /*
6330 +----------------------------------------------------------------------+
6331 | PROJECT: MMI-Framework MODULE : PHB |
6332 | STATE : code ROUTINE: pb_get_fdn_classtype |
6333 +----------------------------------------------------------------------+
6334
6335
6336 PURPOSE : get fdn_classtype
6337 */
6338
6339 T_ACI_CLASS pb_get_fdn_classtype (void)
6340 {
6341 return fdn_classtype;
6342 }
6343
6344 /*
6345 +----------------------------------------------------------------------+
6346 | PROJECT: MMI-Framework MODULE : PHB |
6347 | STATE : code ROUTINE: pb_set_fdn_classtype |
6348 +----------------------------------------------------------------------+
6349
6350
6351 PURPOSE : set fdn_classtype
6352 */
6353
6354 void pb_set_fdn_classtype (T_ACI_CLASS classtype)
6355 {
6356 fdn_classtype = classtype;
6357 }
6358
6359
6360 /*
6361 +----------------------------------------------------------------------+
6362 | PROJECT: MMI-Framework MODULE : PHB |
6363 | STATE : code ROUTINE: pb_get_fdn_mode |
6364 +----------------------------------------------------------------------+
6365
6366 PURPOSE : get fdn_mode
6367 */
6368
6369 UBYTE pb_get_fdn_mode (void)
6370
6371 {
6372 return fdn_mode;
6373 }
6374 /*
6375 +----------------------------------------------------------------------+
6376 | PROJECT: MMI-Framework MODULE : PHB |
6377 | STATE : code ROUTINE: pb_set_fdn_mode |
6378 +----------------------------------------------------------------------+
6379
6380 PURPOSE : set fdn_mode
6381 */
6382
6383 void pb_set_fdn_mode (UBYTE fdnmode)
6384
6385 {
6386 fdn_mode = fdnmode;
6387 }
6388
6389 /*
6390 +--------------------------------------------------------------------+
6391 | PROJECT: MMI-Framework (8417) MODULE : PHB |
6392 | STATE : code ROUTINE: pb_free_used_record |
6393 +--------------------------------------------------------------------+
6394
6395 PURPOSE : Making used record as free, whenever extension record
6396 is not free while adding an entry with extension data
6397 */
6398
6399 LOCAL void pb_free_used_record(UBYTE type, SHORT index, UBYTE rec_num)
6400 {
6401 UBYTE n,m;
6402
6403 TRACE_FUNCTION ("pb_free_used_record()");
6404
6405 phb_element[index].free = PHB_ELEMENT_FREE;
6406
6407 /* Update used records */
6408 phb_ctb[type].used_rcd--;
6409
6410 if ((type EQ ADN) OR (type EQ FDN))
6411 {
6412 phb_ctb[ADN_FDN].used_rcd--;
6413 }
6414
6415 /* Update record bitmap */
6416 n = (UBYTE)rec_num/8;
6417 m = rec_num%8;
6418
6419 phb_ctb[type].rcd_bitmap[n] ^= 0x01 << m;
6420 }
6421
6422
6423 #endif /* #ifndef TI_PS_FFS_PHB */