comparison src/g23m-aci/aci/phb_sim.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
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 book.
18 +-----------------------------------------------------------------------------
19 */
20 #ifdef TI_PS_FFS_PHB
21
22 #include "aci_all.h"
23 #include "aci_cmh.h"
24 #include "aci_mem.h"
25
26 #include "phb_sim.h"
27 #include "phb_aci.h"
28
29 #include "ffs/ffs.h"
30
31 #ifdef SIM_TOOLKIT
32 #include "psa.h"
33 #include "psa_sim.h"
34 #include "psa_cc.h"
35 #include "psa_sat.h"
36 #endif /* #ifdef SIM_TOOLKIT */
37
38 #include "cmh.h"
39 #include "cmh_phb.h"
40 #include "pcm.h"
41
42 /*
43 * Constants and enumerations
44 */
45
46 #define MAX_ECC_RCD 5
47 #define FFS_IMSI_SIZE 8
48 #define MAX_EXTNS_PER_RECORD 9
49 #define MAX_ELEM_FILES 15
50 #define SIM_MAX_RECORD_SIZE 256 /* Maximum size of a SIM record */
51 #define RDM_DATA_FILE_ID 0xff04 /* File ID to store data related to LDN, LMN and LRN Phonebooks */
52 #define SIZE_DATA_DATE_TIME 12
53 #define MAX_EXT_RECORDS 10
54 #define PHB_PHY_NUM_LENGTH 10
55
56
57 /*
58 * Type definitions
59 */
60
61 typedef struct
62 {
63 /* Handle for the Database */
64 int db_handle;
65
66 /* Maximum number of records */
67 UBYTE max_record[MAX_PHONEBOOK];
68
69 /* Number of used records */
70 UBYTE used_record[MAX_PHONEBOOK];
71
72 /* Records sizes */
73 USHORT record_size[MAX_PHONEBOOK];
74
75 } T_PHB_SIM_DATA;
76
77 /* Maximum no of records for LRN, LDN and LMN Phonebooks. */
78 #define RDM_PHB_DATA_SIZE 10
79
80 /* Record numbers for LDN, LMN and LRN Phonebook data. */
81 #define LDN_DATA_RECNO 1
82 #define LMN_DATA_RECNO 2
83 #define LRN_DATA_RECNO 3
84
85 EXTERN UBYTE cphs_mb_ext_record_num[];
86 /* ECC records */
87 T_PHB_ECC_RECORD phb_ecc_element[MAX_ECC_RCD];
88
89 LOCAL T_PHB_SIM_DATA pbs_data;
90
91 /* Array to hold Reference count for Extension records. */
92 LOCAL UBYTE ext_ref_count[MAX_PHB_EXT][MAX_EXT_RECORDS];
93
94 /* Prototypes for search and compare functions */
95 int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
96 int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
97 int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags);
98 int pb_sim_number_cmp (int db_handle, USHORT field_id,USHORT recno_1,USHORT recno_2, ULONG flags);
99 /*
100 * Prototypes for local functions
101 */
102
103 LOCAL BOOL pb_sim_record_empty (USHORT field_id,
104 USHORT entry_size, const UBYTE *buffer);
105 LOCAL void pb_sim_read_eeprom_ecc (void);
106 LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count);
107 LOCAL void pb_sim_revString(char *);
108 LOCAL void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry);
109 LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr);
110 LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type);
111 LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type);
112 LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id);
113 LOCAL T_EXT_TYPE pb_sim_get_ext_type (USHORT field_id);
114 LOCAL USHORT pb_sim_get_size_except_tag (USHORT field_id);
115
116 LOCAL int pb_sim_cmpString ( UBYTE* cur_tag, UBYTE* check_tag, UBYTE cmpLen );
117 LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE* entry_tag, UBYTE* cur_tag, UBYTE len );
118 LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag);
119 LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id, USHORT rec_num, SHORT ref_type);
120 LOCAL T_PHB_RETURN pb_sim_del_ext_records(T_PHB_TYPE type, USHORT field_id, USHORT db_recno);
121 LOCAL USHORT pb_sim_retrieve_rdm_recno (T_PHB_TYPE type);
122 LOCAL T_PHB_RETURN pb_sim_del_record_internal (T_PHB_TYPE type,
123 USHORT phy_recno,
124 T_DB_CHANGED *rec_affected,
125 BOOL replacement);
126 LOCAL BOOL pb_sim_ext_records_used (T_PHB_TYPE type,
127 USHORT field_id,
128 USHORT db_recno);
129
130
131 LOCAL T_PHB_RETURN pb_sim_update_index (T_PHB_TYPE type,
132 T_DB_CHANGED *rec_affected,
133 USHORT field_id,
134 UBYTE ext_rec_cnt);
135
136 /*
137 +----------------------------------------------------------------------+
138 | PROJECT: MMI-Framework MODULE : PHB |
139 | STATE : code ROUTINE: pb_sim_init |
140 +----------------------------------------------------------------------+
141
142 PURPOSE : Initializes internal data structures for SIM Phonebook.
143 */
144
145 void pb_sim_init (void)
146 {
147 USHORT i;
148
149 TRACE_FUNCTION ("pb_sim_init()");
150 db_init();
151
152 /* Initialise the data structures. */
153
154 /* Initialise ECC Phonebook to contain no records. */
155 for(i = 0; i < MAX_ECC_RCD; i++)
156 {
157 phb_ecc_element[i].phy_idx = 0;
158 memset(phb_ecc_element[i].number,0xFF,ECC_NUM_LEN);
159 }
160
161 return;
162 }
163
164 /*
165 +----------------------------------------------------------------------+
166 | PROJECT: MMI-Framework MODULE : PHB |
167 | STATE : code ROUTINE: pb_sim_exit |
168 +----------------------------------------------------------------------+
169
170 PURPOSE : This function is called by pb_exit() to inform the SIM part
171 of the phonebook to shut down.
172 */
173 void pb_sim_exit (void)
174 {
175 TRACE_FUNCTION ("pb_sim_exit()");
176
177 db_exit();
178
179 return;
180 }
181
182 /*
183 +----------------------------------------------------------------------+
184 | PROJECT: MMI-Framework MODULE : PHB |
185 | STATE : code ROUTINE: pb_sim_record_empty |
186 +----------------------------------------------------------------------+
187
188 PURPOSE : This function is used to determine if a record is
189 considered as empty.
190 */
191 LOCAL BOOL pb_sim_record_empty (USHORT field_id,
192 USHORT entry_size, const UBYTE *data)
193 {
194 USHORT alpha_len;
195
196 /* TRACE_FUNCTION ("pb_sim_record_empty()"); */ /* Trace load */
197
198 /* If the entry contains an alpha identifier it is not empty */
199 if (data[0] NEQ 0xFF)
200 return FALSE;
201
202 alpha_len = entry_size - pb_sim_get_size_except_tag (field_id);
203
204 //TISH for MMISIM sometime entry_size = 0, then alpha_len < 0;
205 #ifdef WIN32
206 if (entry_size == 0)
207 {
208 return TRUE;
209 }
210 #endif
211 if ((data[alpha_len] NEQ 0x00) AND (data[alpha_len + 2] NEQ 0xff))
212 return FALSE;
213 return TRUE; /* No alpha identifier and no phone number => record empty */
214 }
215
216
217 /*
218 +----------------------------------------------------------------------+
219 | PROJECT: MMI-Framework MODULE : PHB |
220 | STATE : code ROUTINE: pb_sim_set_ecc |
221 +----------------------------------------------------------------------+
222
223 PURPOSE : The emergency call numbers are read from SIM card and
224 written to FFS.
225 */
226 T_PHB_RETURN pb_sim_set_ecc (UBYTE ecc_len, const UBYTE *sim_ecc)
227 {
228 USHORT ecc_rec_num;
229 UBYTE *data_ptr;
230
231 TRACE_FUNCTION ("pb_sim_set_ecc()");
232
233 /* Initialise used records for ECC. */
234 pbs_data.used_record[ECC] = 0;
235
236 /* if SIM ECC data is not empty, copy SIM ECC data to phonebook */
237 if ( ecc_len NEQ 0)
238 {
239 data_ptr = ( UBYTE *) sim_ecc;
240 pbs_data.max_record[ECC] = (SHORT)((ecc_len/ECC_NUM_LEN) > MAX_ECC_RCD)? MAX_ECC_RCD: ecc_len/ECC_NUM_LEN;
241 pbs_data.record_size[ECC] = ECC_NUM_LEN;
242
243 /* Store ECC into RAM, since ECC records will be less in number. */
244 /*
245 * For the Issue OMAPS00081622
246 * Replaced MAX_ECC_RCD with pbs_data.max_record[ECC] in the for loop
247 */
248 for (ecc_rec_num = 0; ecc_rec_num < pbs_data.max_record[ECC]; ecc_rec_num++)
249 {
250 if(*data_ptr NEQ 0xff)
251 {
252 memset(&phb_ecc_element[ecc_rec_num],0xFF,sizeof(T_PHB_ECC_RECORD));
253 phb_ecc_element[ecc_rec_num].phy_idx = ecc_rec_num + 1;
254 memcpy(phb_ecc_element[ecc_rec_num].number, data_ptr, ECC_NUM_LEN);
255 data_ptr += ECC_NUM_LEN;
256 (pbs_data.used_record[ECC])++;
257 }
258 }
259 }
260 else
261 {
262 pb_sim_read_eeprom_ecc();
263 }
264
265 return PHB_OK;
266 }
267
268 /*
269 +--------------------------------------------------------------------+
270 | PROJECT: MMI-Framework (8417) MODULE: PHB |
271 | STATE : code ROUTINE: pb_sim_create_ef |
272 +--------------------------------------------------------------------+
273
274 PURPOSE : Creates a SIM elementary file.
275
276 */
277 T_PHB_RETURN pb_sim_create_ef (USHORT ef, USHORT record_size, USHORT records)
278 {
279 T_DB_INFO_FIELD field_info;
280 T_DB_TYPE db_type;
281 int db_result;
282
283 TRACE_FUNCTION ("pb_sim_create_ef()");
284
285 TRACE_EVENT_P1("Elementary file ID = %x",ef);
286 db_result = db_info_field(pbs_data.db_handle, ef, &field_info);
287
288 /* Check whether file already exists. */
289 if(db_result EQ DB_OK)
290 {
291 /* Check for Record size and No. of records in the present field. */
292 if((field_info.record_size EQ record_size) AND (field_info.num_records EQ records))
293 return PHB_OK; /* Preserve the existing field. */
294 else
295 {
296 if(pb_sim_remove_ef(ef) EQ PHB_FAIL) /* Remove the existing file and recreate the field. */
297 return PHB_FAIL;
298 }
299 }
300
301 /* Set DB_TYPE depending on the Elementary file. */
302 switch(ef)
303 {
304 case SIM_ADN:
305 case SIM_FDN:
306 case SIM_BDN:
307 case SIM_SDN:
308 case SIM_EXT1:
309 case SIM_EXT2:
310 case SIM_EXT3:
311 case SIM_EXT4:
312 case SIM_LND:
313 case SIM_OCI:
314 //case SIM_ICI:
315 case FFS_LRN:
316 case FFS_LMN:
317 case FFS_EXT_LRN:
318 case FFS_EXT_LMN:
319 case SIM_EXT5:
320 db_type = DB_FREELIST;
321 break;
322
323 case SIM_MSISDN:
324 case SIM_IMSI:
325 db_type = DB_UNMANAGED;
326 break;
327
328 default:
329 TRACE_ERROR("Invalid ef passed to pb_sim_create_ef()");
330 return PHB_FAIL;
331 }
332
333 db_result = db_create_field(pbs_data.db_handle, db_type, ef, record_size, records);
334
335 if(db_result EQ DB_OK)
336 return PHB_OK;
337
338 /* Return PHB_FAIL since DB has failed to create File. */
339 return PHB_FAIL;
340 }
341
342 /*
343 +--------------------------------------------------------------------+
344 | PROJECT: MMI-Framework (8417) MODULE: PHB |
345 | STATE : code ROUTINE: pb_sim_write_ef |
346 +--------------------------------------------------------------------+
347
348 PURPOSE : Writes entry_size bytes content of buffer at index to the elementary file ef.
349
350 */
351 T_PHB_RETURN pb_sim_write_ef (USHORT ef, USHORT phy_recno,
352 USHORT entry_size, const UBYTE *buffer,
353 BOOL *changed, USHORT *ext_record_ef, UBYTE *ext_record_no)
354 {
355 int i;
356 T_DB_CHANGED records_affected;
357
358 TRACE_FUNCTION ("pb_sim_write_ef()");
359
360 /* Initialise changed to FALSE. */
361 *changed = FALSE;
362
363 /* Default is no extension record */
364 *ext_record_ef = 0;
365 *ext_record_no = 0;
366
367 /* Check for extension records. */
368 if (!pb_sim_record_empty(ef, entry_size, buffer))
369 {
370 /* The record is not empty (deleted) */
371 switch (ef)
372 {
373 case SIM_ADN:
374 case SIM_MSISDN:
375 case SIM_LND:
376 *ext_record_ef = SIM_EXT1;
377 *ext_record_no = buffer[entry_size - 1];
378 break;
379
380 case SIM_FDN:
381 *ext_record_ef = SIM_EXT2;
382 *ext_record_no = buffer[entry_size - 1];
383 break;
384
385 case SIM_SDN:
386 *ext_record_ef = SIM_EXT3;
387 *ext_record_no = buffer[entry_size - 1];
388 break;
389
390 case SIM_BDN:
391 *ext_record_ef = SIM_EXT4;
392 *ext_record_no = buffer[entry_size - 1];
393 break;
394
395 case FFS_LRN:
396 case FFS_LMN:
397 case SIM_OCI: /* Release 1999 and above 31.102 clause 4.2.34 */
398 *ext_record_ef = SIM_EXT5;
399 *ext_record_no = buffer[entry_size - 15]; // Jirli, please check, 14 instead of 15?
400 break;
401
402 case SIM_EXT1: /* Extension records can reference other extension records */
403 case SIM_EXT2:
404 case SIM_EXT3:
405 case SIM_EXT4:
406 case SIM_EXT5:
407 case FFS_EXT_LRN:
408 case FFS_EXT_LMN:
409 //TISH, patch for OMAPS00124850
410 #if 0
411 *ext_record_ef = ef;
412 *ext_record_no = buffer[entry_size - 1];
413 #else
414 if (buffer[entry_size - 1] EQ 255 OR buffer[entry_size-1] EQ (UBYTE)phy_recno)
415 {
416 *ext_record_ef =0;
417 *ext_record_no=0;
418 }
419 else
420 {
421 *ext_record_ef = ef;
422 *ext_record_no = buffer[entry_size - 1];
423 }
424 #endif
425 //end
426 break;
427
428 default: /* No extension record defined for this field */
429 break;
430 }
431
432 /* Record is not referring any extensions. So set ef and record_no to ZERO. */
433 if (*ext_record_no EQ 0xff)
434 {
435 *ext_record_ef = 0;
436 *ext_record_no = 0;
437 }
438
439 /* Handle usage counter of extension records */
440 pb_sim_update_extn_records (*ext_record_ef, *ext_record_no, 1);
441
442 /* Write record into FFS */
443 if(db_write_record(pbs_data.db_handle, ef, phy_recno, 0, entry_size, buffer) > DB_OK)
444 {
445 if(db_read_change_log(pbs_data.db_handle, &records_affected) EQ DB_OK)
446 {
447 for(i = 0; i < records_affected.entries; i++)
448 {
449 /* Checking whether Elementary file in the database is changed. */
450 if((records_affected.field_id[i] EQ ef) AND (records_affected.record[i] EQ phy_recno))
451 {
452 *changed = TRUE;
453 return PHB_OK;
454 }
455 }
456
457 /* Write operation has not changed File in the database. So returning PHB_OK */
458 return PHB_OK;
459 }
460 else /* Unable to read change log from DB. So returning PHB_FAIL. */
461 return PHB_FAIL;
462 }
463 else /* Write failure in DB. So returning PHB_FAIL */
464 return PHB_FAIL;
465 }
466 else
467 {
468 /* Empty record */
469 if (db_delete_record (pbs_data.db_handle, ef, phy_recno) NEQ DB_OK)
470 return PHB_FAIL;
471
472 if(db_read_change_log (pbs_data.db_handle, &records_affected) NEQ DB_OK)
473 return PHB_FAIL;
474
475 *changed = (records_affected.entries NEQ 0);
476 return PHB_OK;
477 }
478 }
479
480
481 /*
482 +--------------------------------------------------------------------+
483 | PROJECT: MMI-Framework (8417) MODULE: PHB |
484 | STATE : code ROUTINE: pb_sim_open |
485 +--------------------------------------------------------------------+
486
487 PURPOSE : Opens the SIM phonebook for the given SIM determined by the IMSI.
488 */
489 T_PHB_RETURN pb_sim_open (const T_imsi_field *imsi_field, BOOL *changed)
490 {
491 T_DB_INFO database_info;
492 UBYTE ffsIMSI[MAX_IMSI_LEN+1];
493 UBYTE simIMSI[MAX_IMSI_LEN+1];
494 UBYTE imsi[FFS_IMSI_SIZE];
495 int db_result,rec_num;
496 UBYTE buffer[RDM_PHB_DATA_SIZE];
497
498 TRACE_FUNCTION("pb_sim_open()");
499
500 /* Initially set SIM changed as TRUE. */
501 *changed = TRUE;
502
503 /* Open the database. */
504 db_result = db_open(FFS_PHB_DIR);
505
506 TRACE_EVENT_P1("DB handle is %d",db_result);
507
508 if(db_result >= DB_OK)
509 {
510 pbs_data.db_handle = db_result;
511
512 /* Get database info. */
513 db_result = db_info(pbs_data.db_handle, &database_info);
514
515 /* Read IMSI from the FFS if Database is clean. */
516 if((db_result EQ DB_OK) AND (database_info.clean EQ TRUE))
517 {
518 db_result = db_read_record(pbs_data.db_handle, SIM_IMSI, 1, 0, FFS_IMSI_SIZE, imsi);
519
520 /* Compare IMSI read from FFS with IMSI got from SIM. */
521 if(db_result > DB_OK)
522 {
523 psaSIM_decodeIMSI ((UBYTE*) imsi_field->field,(UBYTE)imsi_field->c_field, (char *)simIMSI);
524
525 psaSIM_decodeIMSI (imsi, FFS_IMSI_SIZE, (char *)ffsIMSI);
526
527 if (!strcmp((char *)simIMSI, (char *)ffsIMSI))
528 {
529 *changed = FALSE;
530 return PHB_OK;
531 }
532 }
533 else
534 {
535 /* Unable to read IMSI, regenerate database */
536 *changed = TRUE;
537 }
538 }
539
540 /* Remove database whenever database is Inconsistent and SIM is changed. */
541 if(db_close(pbs_data.db_handle) NEQ DB_OK)
542 return PHB_FAIL;
543
544 if(db_remove(FFS_PHB_DIR) NEQ DB_OK)
545 return PHB_FAIL;
546 }/* if(db_result >= DB_OK) */
547
548 /* Create database: For the first time, whenever SIM is changed
549 and whenever database is Inconsistent. */
550 db_result = db_create(FFS_PHB_DIR, MAX_ELEM_FILES, TRUE);
551
552 TRACE_EVENT_P1("DB handle is %d",db_result);
553
554 /* Creating DB is successful and valid db_handle is returned */
555 if(db_result >= DB_OK)
556 {
557 if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, SIM_IMSI, imsi_field->c_field, 1) NEQ DB_OK)
558 return PHB_FAIL;
559
560 if(db_write_record(pbs_data.db_handle, SIM_IMSI, 1, 0, imsi_field->c_field, imsi_field->field) < DB_OK)
561 return PHB_FAIL;
562
563 /* Create Elementary file to store RDM Phonebook data */
564 if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, RDM_DATA_FILE_ID,RDM_PHB_DATA_SIZE,3) NEQ DB_OK)
565 return PHB_FAIL;
566
567 /* Initialise data for Recent call lists */
568 for(rec_num = 1; rec_num <= 3; rec_num++)
569 {
570 memset(buffer,0x00, RDM_PHB_DATA_SIZE);
571
572 if(db_write_record(pbs_data.db_handle, RDM_DATA_FILE_ID, rec_num, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
573 return PHB_FAIL;
574 }
575
576 return PHB_OK;
577 }
578
579 /* Unable to create Database. So returning PHB_FAIL. */
580 return PHB_FAIL;
581 }
582
583 /*
584 +--------------------------------------------------------------------+
585 | PROJECT: MMI-Framework (8417) MODULE: PHB |
586 | STATE : code ROUTINE: pb_sim_read_ef |
587 +--------------------------------------------------------------------+
588
589 PURPOSE : Reads *buffer from elementary file ef at index.
590 */
591 T_PHB_RETURN pb_sim_read_ef (USHORT ef, USHORT recno, USHORT *entry_size, UBYTE *buffer)
592 {
593 int db_result;
594 T_DB_INFO_FIELD field_info;
595
596 TRACE_FUNCTION("pb_sim_read_ef()");
597
598 if(db_info_field(pbs_data.db_handle, ef, &field_info) EQ DB_OK)
599 {
600 *entry_size = field_info.record_size;
601
602 db_result = db_read_record (pbs_data.db_handle,
603 ef,
604 recno,
605 0,
606 field_info.record_size,
607 buffer);
608
609 if (db_result > DB_OK)
610 return PHB_OK; /* Successfully read */
611
612 if (db_result EQ DB_EMPTY_RECORD)
613 {
614 /* Return a deleted record content */
615 memset (buffer, 0xff, *entry_size);
616 return PHB_OK;
617 }
618 return PHB_FAIL; /* Some problem reading record */
619 }
620
621 /* Returning PHB_FAIL, since DB has failed to give Info about the field. */
622 return PHB_FAIL;
623 }
624
625 /*
626 +--------------------------------------------------------------------+
627 | PROJECT: MMI-Framework (8417) MODULE: PHB |
628 | STATE : code ROUTINE: pb_sim_remove_ef |
629 +--------------------------------------------------------------------+
630
631 PURPOSE : Removes elementary file.
632 */
633 T_PHB_RETURN pb_sim_remove_ef (USHORT ef)
634 {
635 T_EXT_TYPE ext_type;
636 USHORT rec_num;
637
638 TRACE_FUNCTION("pb_sim_remove_ef()");
639
640 if(db_remove_field(pbs_data.db_handle, ef) EQ DB_OK)
641
642 {
643 /* Get EXT Type for elementary file */
644 ext_type = pb_sim_get_ext_type(ef);
645
646 /* Reset reference count for extension records */
647 if(ext_type NEQ INVALID_EXT)
648 {
649 for(rec_num = 0; rec_num < MAX_EXT_RECORDS; rec_num++)
650 {
651 ext_ref_count[ext_type][rec_num] = 0;
652 }
653 }
654 return PHB_OK;
655 }
656
657 return PHB_FAIL;
658 }
659
660 /*
661 +--------------------------------------------------------------------+
662 | PROJECT: MMI-Framework (8417) MODULE: PHB |
663 | STATE : code ROUTINE: pb_sim_build_index |
664 +--------------------------------------------------------------------+
665
666 PURPOSE : Builds index for the given phonebook.
667 */
668
669 T_PHB_RETURN pb_sim_build_index (T_PHB_TYPE type)
670 {
671 USHORT field_id;
672
673 TRACE_FUNCTION("pb_sim_build_index()");
674
675 field_id = pb_sim_get_field_id(type);
676
677 if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX, pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
678 return PHB_FAIL;
679
680 if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX, pb_sim_number_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
681 return PHB_FAIL;
682
683 return PHB_OK;
684 }
685
686 /*
687 +--------------------------------------------------------------------+
688 | PROJECT: MMI-Framework (8417) MODULE: PHB |
689 | STATE : code ROUTINE: pb_sim_flush_data |
690 +--------------------------------------------------------------------+
691
692 PURPOSE : This function informs the SIM phonebook that SIM reading has become finished and we reached a consistent state.
693 */
694
695 T_PHB_RETURN pb_sim_flush_data (void)
696 {
697
698 TRACE_FUNCTION("pb_sim_flush_data()");
699
700 if(db_flush(pbs_data.db_handle) EQ DB_OK)
701 return PHB_OK;
702
703 return PHB_FAIL;
704 }
705
706 /*
707 +--------------------------------------------------------------------+
708 | PROJECT: MMI-Framework (8417) MODULE: PHB |
709 | STATE : code ROUTINE: pb_sim_add_record |
710 +--------------------------------------------------------------------+
711
712 PURPOSE : Add a given record at index to the given phonebook.
713 */
714
715 T_PHB_RETURN pb_sim_add_record (T_PHB_TYPE type,
716 USHORT phy_recno,
717 const T_PHB_RECORD *entry,
718 T_DB_CHANGED *rec_affected)
719 {
720 USHORT field_id, ext_file_id, rec_no;
721 UBYTE tag_len, max_tag_len;
722 UBYTE data[SIM_MAX_RECORD_SIZE];
723 UBYTE buffer[RDM_PHB_DATA_SIZE];
724 T_DB_INFO_FIELD info_field, ext_info_field;
725 UBYTE ext_rec_cnt = 0;
726 UBYTE ext_rec_num1, ext_rec_num2;
727 BOOL record_empty;
728 int db_result,i;
729
730 TRACE_FUNCTION("pb_sim_add_record()");
731
732 /* Handling of ECC Phonebook */
733 if(type EQ ECC)
734 {
735 if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
736 {
737 phb_ecc_element[phy_recno - 1].phy_idx = phy_recno;
738 memcpy(phb_ecc_element[phy_recno - 1].number,entry->number, ECC_NUM_LEN);
739
740 return PHB_OK;
741 }
742 else
743 return PHB_FAIL;
744 }
745
746 /* Get Elementary file ID for the Phonebook type. */
747 field_id = pb_sim_get_field_id(type);
748 TRACE_EVENT_P1("pb_sim_get_field_id->Field_id: %x", field_id);
749
750 /* Get Extension file for the Phonebook type. */
751 ext_file_id = pb_sim_get_ext_file(type);
752
753 TRACE_EVENT_P1("Ext_Field_id: %x", ext_file_id);
754
755 db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
756
757 /* Get record size to calculate alpha_len for the entry */
758 if(db_result NEQ DB_OK)
759 {
760 TRACE_EVENT_P1("db_result = %d",db_result);
761 return PHB_FAIL;
762 }
763
764 /* Handling of LDN, LMN and LRN Phonebook records. */
765 if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
766 {
767 if(phy_recno NEQ 1)
768 return PHB_FAIL;
769
770 /* Find free record in the elementary file. */
771 db_result = db_find_free_record( pbs_data.db_handle, field_id);
772
773 /* Get record number for the type of Phonebook. */
774 rec_no = pb_sim_retrieve_rdm_recno(type);
775
776 /* Error handling. */
777 if(rec_no EQ 0)
778 return PHB_FAIL;
779
780 /* Read data related to LDN, LMN and LRN Phonebook from FFS */
781 if(db_read_record(pbs_data.db_handle,
782 RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
783 return PHB_FAIL;
784
785 /* Database is unable to find the free record. So overwrite the oldest one. */
786 if(db_result < 0)
787 phy_recno = buffer[RDM_PHB_DATA_SIZE - 1];
788 else
789 phy_recno = db_result;
790
791 if(info_field.used_records EQ RDM_PHB_DATA_SIZE)
792 i = RDM_PHB_DATA_SIZE - 1;
793 else
794 i = info_field.used_records;
795
796 /* Move the records as new record has to be added. */
797 for(; i > 0; i--)
798 {
799 buffer[i] = buffer[i-1];
800 }
801
802 /* Update the record number of new entry. */
803 buffer[0] = (UBYTE) phy_recno;
804
805 /* Write back RDM data back into the database. */
806 if(db_write_record(pbs_data.db_handle,
807 RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
808 return PHB_FAIL;
809
810 /* Drop information about changed RDM records from the database. */
811 (void)db_read_change_log(pbs_data.db_handle, rec_affected);
812 rec_affected->entries = 0;
813 }
814
815 /* Convert T_PHB_TYPE into data structures as described in ETSI 11.11 */
816 /* Bytes Description M/O Length |
817 ----------------------------------------------------------------------
818 1 to X Alpha Identifier O X bytes
819 X+1 Length of BCD number/SSC contents M 1 byte
820 X+2 TON and NPI M 1 byte
821 X+3 to X+12 Dialling Number/SSC String M 10 bytes
822 X+13 Capability/Configuration Identifier M 1 byte
823 X+14 Extension Record Identifier M 1 byte
824 -------------------------------------------------------
825 Extra fields for LDN, LMN, and LMN Phonebook records (As per 31.102)
826 -------------------------------------------------------
827 X+15 to X+21 Outgoing call date and time M 7 bytes
828 X+22 to X+24 Outgoing call duration M 3 bytes
829 X+26 Line of the call M 1 byte (New field added to
830 store line of call)
831 ----------------------------------------------------------------------*/
832
833 tag_len = pb_sim_get_entry_len(entry->tag, PHB_MAX_TAG_LEN);
834
835 max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
836
837 if(tag_len > max_tag_len)
838 return PHB_TAG_EXCEEDED;
839
840 memset(data, 0xFF, sizeof(data));
841 memcpy(data, entry->tag, tag_len);
842
843 if(entry->number[10] NEQ 0xFF)
844 {
845 data[max_tag_len] = 11; /* max. length */
846 }
847 else
848 {
849 data[max_tag_len] = entry->len + 1;
850 }
851
852 data[max_tag_len+1] = entry->ton_npi;
853 memcpy((char *)&data[max_tag_len+2],
854 (char *)entry->number, 10);
855 data[max_tag_len+12] = entry->cc_id;
856
857 /* Copy data specific to records of Phonebook Types (LRN, LDN and LMN). */
858 if((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN))
859 {
860 if(entry->v_time)
861 {
862 data[max_tag_len+14] = entry->time.year;
863 data[max_tag_len+15] = entry->time.month;
864 data[max_tag_len+16] = entry->time.day;
865 data[max_tag_len+17] = entry->time.hour;
866 data[max_tag_len+18] = entry->time.minute;
867 data[max_tag_len+19] = entry->time.second;
868 data[max_tag_len+20] = entry->time.time_zone;
869
870 data[max_tag_len+21] = (UBYTE)((entry->time.duration >> 16) & 0xff);
871 data[max_tag_len+22] = (UBYTE)((entry->time.duration >> 8) & 0xff);
872 data[max_tag_len+23] = (UBYTE)((entry->time.duration) & 0xff);
873
874 }
875
876 if(entry->v_line)
877 {
878 data[max_tag_len+24] = entry->line;
879 }
880
881 }
882
883 /* Check how many extension records are needed for number */
884 if(entry->number[10] NEQ 0xFF)
885 {
886 ext_rec_cnt = entry ->len - 10;
887
888 if(ext_rec_cnt % 10)
889 ext_rec_cnt = (ext_rec_cnt / 10) + 1;
890 else
891 ext_rec_cnt = (ext_rec_cnt / 10);
892 }
893
894 /* Check how many extension records are needed for subaddress */
895 if(entry->subaddr[0] NEQ 0xFF)
896 {
897 ext_rec_cnt++;
898 }
899
900 if(entry->subaddr[11] NEQ 0xFF)
901 {
902 ext_rec_cnt++;
903 }
904
905 TRACE_EVENT_P1("phy_recno = %d",phy_recno);
906
907 TRACE_EVENT_P2("no_rec = %d, used_rec = %d",info_field.num_records,info_field.used_records);
908
909 /* If record number is not mentioned, search for the free record and add the entry. */
910 if(phy_recno EQ 0)
911 {
912 db_result = db_find_free_record( pbs_data.db_handle, field_id);
913
914 /* Database is unable to find the free record. So returning PHB_FULL. */
915 if(db_result EQ DB_RECORD_NOT_FOUND)
916 return PHB_FULL;
917
918 if(db_result < DB_OK)
919 return PHB_FAIL;
920
921 /* Database has returned the free record number. */
922 phy_recno = db_result;
923 }
924 else
925 {
926 /*
927 * Delete the record, if present to get rid of associated
928 * ext records. This has the effect that when we afterwards are unable to
929 * create the new record (e.g. lack of extension records) the original
930 * record remains deleted. Probably this is not a problem, at least it
931 * should not be a big one.
932 */
933 db_result = db_record_empty (pbs_data.db_handle,
934 field_id, phy_recno, &record_empty);
935 if ((db_result EQ DB_OK) AND !record_empty)
936 {
937 /*
938 * In case ext_rec is needed and the existing record is not using EXT,
939 * check if there is ext_rec available before deleting the existing entry
940 * ext_info_field is used to get this info
941 */
942 if (ext_rec_cnt NEQ 0 AND !pb_sim_ext_records_used(type, field_id,phy_recno))
943 {
944 db_result = db_info_field(pbs_data.db_handle, ext_file_id, &ext_info_field);
945 TRACE_EVENT_P3("before delelet rec; db_result = %d, ext_info_field.num_records = %d, ext_info_field.used_records = %d", db_result, ext_info_field.num_records, ext_info_field.used_records);
946
947 if((ext_info_field.num_records - ext_info_field.used_records) < ext_rec_cnt)
948 return PHB_EXT_FULL;
949 }
950
951 (void)pb_sim_del_record_internal (type, phy_recno, rec_affected, TRUE);
952 }
953 }
954
955 /* Write record if entry does not require extension records */
956 if(ext_rec_cnt EQ 0)
957 {
958 /* Write record into FFS */
959 if(db_write_record(pbs_data.db_handle, field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
960 return PHB_FAIL;
961
962 /* For LDN record also write to SIM_LDN (without date and time Details */
963 if(type EQ LDN)
964 {
965 memset(&data[max_tag_len + pb_sim_get_size_except_tag(field_id)], 0xFF,
966 SIZE_DATA_DATE_TIME);
967
968 /* if(db_info_field(pbs_data.db_handle, SIM_LND, &info_field) NEQ DB_OK)
969 return PHB_FAIL;
970
971 if(db_write_record(pbs_data.db_handle, SIM_LND, phy_recno, 0, info_field.record_size, data) < DB_OK)
972 return PHB_FAIL;*/
973 }
974
975 }
976 else /* We need to find free extension record. */
977 {
978 TRACE_EVENT_P1("Extension records = %d",ext_rec_cnt);
979 /* Search for free extension records */
980
981 /* Check whether extension file has required no. of free records. */
982 db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
983
984 if((info_field.num_records - info_field.used_records) < ext_rec_cnt)
985 {
986 return PHB_EXT_FULL;
987 }
988
989 /* Required no. of free extension records are found */
990 db_result = db_find_free_record( pbs_data.db_handle,ext_file_id);
991
992 /* DB has returned non-zero positive number.
993 (Valid record number which is free). */
994
995 if(db_result EQ DB_RECORD_NOT_FOUND)
996 {
997 return PHB_EXT_FULL;
998 }
999
1000 if(db_result > DB_OK)
1001 { /* Set Extension record Identifier */
1002 ext_rec_num1 = db_result;
1003
1004 data[max_tag_len+13] = ext_rec_num1;
1005
1006 db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
1007
1008 /* Write record into FFS */
1009 if(db_write_record(pbs_data.db_handle,
1010 field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
1011 return PHB_FAIL;
1012
1013 }
1014 else
1015 return PHB_FAIL;
1016
1017 db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
1018
1019 /* Prepare extension data and write into Extension file after finding the free records. */
1020 for(i = 0; i < ext_rec_cnt; i++)
1021 {
1022 //TISH, patch for ASTec34494, added by Jinshu Wang, 2007-08-09
1023 //start
1024 memset(data,0xff,SIM_MAX_RECORD_SIZE);
1025 //end
1026
1027 pb_sim_prepare_ext_data(data, i, (UBYTE*)entry->number, entry->len, (UBYTE*)entry->subaddr);
1028
1029 /* Find next free record to chain the extension records. */
1030 db_result = db_find_free_record( pbs_data.db_handle,ext_file_id);
1031
1032 if(db_result EQ DB_RECORD_NOT_FOUND)
1033 {
1034 return PHB_EXT_FULL;
1035 }
1036
1037 if(db_result > DB_OK)
1038 {
1039 ext_rec_num2 = db_result;
1040 }
1041 else
1042 {
1043 return PHB_FAIL;
1044 }
1045
1046 /* Chain extension records and set last link to "FF" */
1047 if(i NEQ (ext_rec_cnt - 1))
1048 data[12] = ext_rec_num2;
1049
1050 /* Write extension record into FFS */
1051 if(db_write_record(pbs_data.db_handle, ext_file_id, ext_rec_num1, 0, info_field.record_size, data) < DB_OK)
1052 return PHB_FAIL;
1053
1054 if(pb_sim_update_extn_records(ext_file_id, ext_rec_num1, 1) EQ PHB_FAIL)
1055 return PHB_FAIL;
1056
1057 /* Preserve the previous free record number. */
1058 ext_rec_num1 = ext_rec_num2;
1059 }
1060
1061 }
1062
1063 /* Get information about changed records from the database. */
1064 if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
1065 return PHB_FAIL;
1066
1067 /* Implements Measure #167 */
1068 return pb_sim_update_index ( type, rec_affected,field_id, ext_rec_cnt);
1069
1070 }
1071
1072
1073 /*
1074 +----------------------------------------------------------------------------+
1075 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1076 | STATE : code ROUTINE: pb_sim_del_record_internal |
1077 +----------------------------------------------------------------------------+
1078
1079 PURPOSE : Delete a given record at phy_recno from the given phonebook.
1080 If this function is called internally by a replacement operation
1081 on the phonebook this is indicated by the replacement parameter,
1082 in this case neither the change log are read nor the ring buffer
1083 management is touched in case of circular phonebooks.
1084 */
1085 LOCAL T_PHB_RETURN pb_sim_del_record_internal (T_PHB_TYPE type,
1086 USHORT phy_recno,
1087 T_DB_CHANGED *rec_affected,
1088 BOOL replacement)
1089 {
1090 USHORT field_id, db_recno, rec_no;
1091 UBYTE buffer[RDM_PHB_DATA_SIZE], rec_cnt;
1092
1093 TRACE_FUNCTION("pb_sim_del_record_internal()");
1094
1095 /* Handling of ECC Phonebook */
1096 if(type EQ ECC)
1097 {
1098 if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
1099 {
1100 phb_ecc_element[phy_recno - 1].phy_idx = 0;
1101 memset(phb_ecc_element[phy_recno - 1].number, 0xFF, ECC_NUM_LEN);
1102
1103 return PHB_OK;
1104 }
1105 else
1106 return PHB_FAIL;
1107 }
1108
1109 TRACE_EVENT_P1("phy_recno = %d", phy_recno);
1110
1111 /* Get Elementary file ID for the Phonebook type. */
1112 field_id = pb_sim_get_field_id(type);
1113
1114 /* Handling of LDN, LMN and LRN Phonebook records. */
1115 if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
1116 {
1117 /* Get record number for the type of Phonebook. */
1118 rec_no = pb_sim_retrieve_rdm_recno(type);
1119
1120 /* Error handling. */
1121 if(rec_no EQ 0)
1122 return PHB_FAIL;
1123
1124 /* Read data related to LDN, LMN and LRN Phonebook from FFS */
1125 if(db_read_record(pbs_data.db_handle,
1126 RDM_DATA_FILE_ID,rec_no, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
1127 return PHB_FAIL;
1128
1129 /* Retrieve record number in Database from the buffer. */
1130 if((buffer[phy_recno - 1] EQ 0) OR (buffer[phy_recno - 1] > RDM_PHB_DATA_SIZE))
1131 return PHB_FAIL;
1132
1133 db_recno = buffer[phy_recno - 1];
1134
1135 if (!replacement)
1136 {
1137 /* Move the records */
1138 for(rec_cnt = phy_recno -1; rec_cnt < RDM_PHB_DATA_SIZE - 1; rec_cnt ++)
1139 {
1140 buffer[rec_cnt] = buffer[rec_cnt + 1];
1141 }
1142
1143 /* Update the deleted entry record number. */
1144 buffer[RDM_PHB_DATA_SIZE - 1] = 0;
1145
1146 /* Write back RDM data back into the database. */
1147 if(db_write_record(pbs_data.db_handle,
1148 RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
1149 return PHB_FAIL;
1150
1151 /* Drop information about changed RDM records from the database. */
1152 (void)db_read_change_log(pbs_data.db_handle, rec_affected);
1153 rec_affected->entries = 0;
1154 }
1155 }
1156 else
1157 {
1158 db_recno = phy_recno;
1159 }
1160
1161 /* Delete extension records if not referenced. */
1162 (void)pb_sim_del_ext_records(type, field_id, db_recno);
1163
1164 /* Delete record from FFS. */
1165 if(db_delete_record(pbs_data.db_handle, field_id,db_recno) NEQ DB_OK)
1166 return PHB_FAIL;
1167
1168 /* Get final information about changed records from the database. */
1169 if (!replacement)
1170 {
1171 if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
1172 return PHB_FAIL;
1173 }
1174
1175 /* Implements Measure #167 */
1176 return pb_sim_update_index ( type, rec_affected,field_id, 0);
1177
1178 }
1179
1180
1181 /*
1182 +----------------------------------------------------------------------------+
1183 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1184 | STATE : code ROUTINE: pb_sim_del_record |
1185 +----------------------------------------------------------------------------+
1186
1187 PURPOSE : Delete a given record at phy_recno from the given phonebook.
1188 This function reads the change log.
1189
1190 */
1191 T_PHB_RETURN pb_sim_del_record (T_PHB_TYPE type,
1192 USHORT phy_recno,
1193 T_DB_CHANGED *rec_affected)
1194 {
1195 TRACE_FUNCTION ("pb_sim_del_record()");
1196 return (pb_sim_del_record_internal (type, phy_recno, rec_affected, FALSE));
1197 }
1198
1199
1200 /*
1201 +--------------------------------------------------------------------+
1202 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1203 | STATE : code ROUTINE: pb_sim_read_record |
1204 +--------------------------------------------------------------------+
1205
1206 PURPOSE : Read a given physical record from the flash based phonebook.
1207 */
1208
1209 T_PHB_RETURN pb_sim_read_record (T_PHB_TYPE type, USHORT phy_recno, T_PHB_RECORD *entry)
1210 {
1211 USHORT field_id, ext_file_id, rec_no;
1212 USHORT db_recno;
1213 T_DB_INFO_FIELD info_field;
1214 UBYTE buffer[RDM_PHB_DATA_SIZE];
1215 UBYTE *data=NULL, *ptr;
1216 UBYTE max_tag_len;
1217 UBYTE ext_rcd_num;
1218
1219
1220 TRACE_FUNCTION("pb_sim_read_record()");
1221
1222 /* Handling of ECC Phonebook */
1223 if(type EQ ECC)
1224 {
1225 if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
1226 {
1227 memset(entry,0xFF,sizeof(T_PHB_RECORD));
1228 /* Return PHB_FAIL whenever ECC entry is empty */
1229 if((phb_ecc_element[phy_recno - 1].number[0] & 0x0F)
1230 EQ 0x0F)
1231 {
1232 return PHB_FAIL;
1233 }
1234 else
1235 {
1236 entry->phy_recno = phy_recno;
1237 entry->len = ECC_NUM_LEN;
1238 memcpy(entry->number, phb_ecc_element[phy_recno - 1].number, ECC_NUM_LEN);
1239 return PHB_OK;
1240 }
1241 }
1242 else
1243 return PHB_FAIL;
1244 }
1245
1246 /* Get Elementary file ID for the Phonebook type. */
1247 field_id = pb_sim_get_field_id(type);
1248
1249 /* Get Extension file for the Phonebook type. */
1250 ext_file_id = pb_sim_get_ext_file(type);
1251
1252 /* Read record from the database. */
1253 if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
1254 return PHB_FAIL;
1255
1256 if((phy_recno EQ 0 ) OR (phy_recno > info_field.num_records))
1257 return PHB_FAIL;
1258
1259 /* Handling of LDN, LMN and LRN Phonebook records. */
1260 if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
1261 {
1262 /* Get record number for the type of Phonebook. */
1263 rec_no = pb_sim_retrieve_rdm_recno(type);
1264
1265 /* Error handling. */
1266 if(rec_no EQ 0)
1267 return PHB_FAIL;
1268
1269 /* Read data related to LDN,LMN and LRN Phonebook from FFS */
1270 if(db_read_record(pbs_data.db_handle,
1271 RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
1272 return PHB_FAIL;
1273
1274 db_recno = buffer[phy_recno - 1];
1275 }
1276 else
1277 db_recno = phy_recno;
1278
1279 ACI_MALLOC(data,SIM_MAX_RECORD_SIZE);
1280
1281 if(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
1282 {
1283 ACI_MFREE(data);
1284 return PHB_FAIL;
1285 }
1286
1287 /* Convert SIM data to the type T_PHB_RECORD. */
1288 ptr = data;
1289 max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
1290 if (max_tag_len > PHB_MAX_TAG_LEN)
1291 max_tag_len = PHB_MAX_TAG_LEN;
1292
1293 entry->phy_recno = phy_recno;
1294 entry->tag_len = (UBYTE)pb_sim_get_entry_len(ptr, max_tag_len);
1295
1296 memset(entry->tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
1297 memcpy ( (char*)entry->tag, (char*)ptr, entry->tag_len );
1298
1299 ptr += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
1300
1301 max_tag_len = (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
1302
1303 entry->len = *ptr - 1;
1304 ++ptr;
1305 entry->ton_npi = *ptr;
1306 ++ptr;
1307
1308 /*
1309 * This error handling is done to avoid the accidental incorrect
1310 * record length stored in the test SIMs
1311 */
1312 if (entry->len > PHB_PACKED_NUM_LEN)
1313 {
1314 entry->len = PHB_PACKED_NUM_LEN;
1315 }
1316
1317 memset(entry->number, 0xFF, PHB_PACKED_NUM_LEN);
1318 memcpy( (char*)entry->number, (char*)ptr, entry->len );
1319 ptr += 10;
1320 entry->cc_id = *ptr;
1321 ++ptr;
1322
1323 /* Copy data specific to records of LDN, LMN, and LRN phonebook types. */
1324 if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
1325 {
1326 entry->v_time = 1;
1327
1328 entry->time.year=data[max_tag_len+14] ;
1329 entry->time.month=data[max_tag_len+15];
1330 entry->time.day=data[max_tag_len+16];
1331 entry->time.hour=data[max_tag_len+17] ;
1332 entry->time.minute= data[max_tag_len+18];
1333 entry->time.second=data[max_tag_len+19] ;
1334 entry->time.time_zone=data[max_tag_len+20];
1335
1336 entry->time.duration = (data[max_tag_len+21] << 16) +
1337 (data[max_tag_len+22] << 8) +
1338 (data[max_tag_len+23] );
1339
1340 entry->v_line = 1;
1341 entry->line=data[max_tag_len+24];
1342
1343 }
1344
1345 if (*ptr NEQ 0xFF) /* check for extention records */
1346 {
1347 ext_rcd_num =(UBYTE)*ptr;
1348
1349 if(db_info_field(pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
1350 {
1351 ACI_MFREE(data);
1352 return PHB_FAIL;
1353 }
1354
1355 /* Reset pointer to start location. */
1356 ptr = data;
1357
1358 memset(ptr, 0xFF, info_field.record_size);
1359
1360 if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, ptr) < DB_OK)
1361 {
1362 ACI_MFREE(data);
1363 //TISH, patch for OMAPS00123396
1364 //start
1365 // return PHB_FAIL;
1366 return PHB_OK;
1367 //end
1368 }
1369 pb_sim_read_ext(ptr, entry);
1370
1371 while(*(ptr + 12) NEQ 0xFF) /* check if a further EXT entry exists */
1372 {
1373 memset(ptr, 0xFF, info_field.record_size);
1374
1375 db_read_record(pbs_data.db_handle, ext_file_id, (USHORT)*(ptr+12), 0, info_field.record_size,ptr);
1376
1377 pb_sim_read_ext(ptr, entry);
1378 }
1379 }
1380
1381 ACI_MFREE(data);
1382
1383 return PHB_OK;
1384 }
1385
1386 /* Implements Measure #30 */
1387
1388 /*
1389 +--------------------------------------------------------------------+
1390 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1391 | STATE : code ROUTINE: pb_sim_search_name |
1392 +--------------------------------------------------------------------+
1393
1394 PURPOSE : Finds the first entry matching the search tag.
1395 */
1396
1397 T_PHB_RETURN pb_sim_search_name (T_PHB_TYPE type, T_PHB_MATCH match, const T_ACI_PB_TEXT *search_tag, SHORT *order_num)
1398 {
1399 T_ACI_PB_TEXT key;
1400 int res;
1401 USHORT field_id;
1402
1403 TRACE_FUNCTION("pb_sim_search_name()");
1404
1405 /* Get Elementary file ID for the Phonebook type. */
1406 field_id = pb_sim_get_field_id(type);
1407
1408
1409
1410 key.len = search_tag->len;
1411 key.cs = search_tag->cs;
1412 pb_sim_cvt_alpha_for_cmp ((UBYTE*) search_tag->data, (UBYTE*) key.data, search_tag->len);
1413
1414 res = db_search(pbs_data.db_handle, field_id, NAME_IDX, order_num, pb_sim_search_alpha_func, match, (const UBYTE*)&key);
1415
1416 if(res > DB_OK)
1417 {
1418 return PHB_OK;
1419 }
1420
1421 return PHB_FAIL;
1422 }
1423
1424 /*
1425 +--------------------------------------------------------------------+
1426 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1427 | STATE : code ROUTINE: pb_sim_search_number |
1428 +--------------------------------------------------------------------+
1429
1430 PURPOSE : Finds the first entry matching the number.
1431 */
1432
1433 T_PHB_RETURN pb_sim_search_number (T_PHB_TYPE type, const UBYTE *number, SHORT *order_num)
1434 {
1435 int res, i;
1436 CHAR cur_number[MAX_PHB_NUM_LEN];
1437 CHAR rev_number[MAX_PHB_NUM_LEN];
1438 int cmpLen, cmp_res;
1439 USHORT field_id;
1440
1441 TRACE_FUNCTION("pb_sim_search_number()");
1442
1443 /* Handling for ECC Phonebook. */
1444 if(type EQ ECC)
1445 {
1446 for(i = 0; i < pbs_data.max_record[ECC]; i++)
1447 {
1448
1449 cmhPHB_getAdrStr(cur_number, MAX_PHB_NUM_LEN - 1,phb_ecc_element[i].number,pbs_data.record_size[ECC]);
1450
1451 pb_sim_revString(cur_number);
1452
1453 strcpy( rev_number,(const char*)number);
1454
1455 pb_sim_revString(rev_number);
1456
1457 /*cmpLen = MINIMUM(strlen((const char*) cur_number), strlen((const char*)number));*/
1458 cmpLen = strlen((const char*)number);
1459 if(cmpLen > 7)
1460 {
1461 cmpLen = 7;
1462 cmp_res = pb_sim_cmpString((UBYTE*)cur_number, (UBYTE*)rev_number, cmpLen);
1463 }
1464 else
1465 {
1466 cmp_res = strcmp(cur_number,rev_number);
1467 }
1468
1469 /*patch for ASTec29800 EFECC by dongfeng*/
1470 if(cmp_res EQ 0)
1471 return PHB_OK;
1472 }
1473
1474 return PHB_FAIL;
1475 }
1476
1477 /* Get Elementary file ID for the Phonebook type. */
1478 field_id = pb_sim_get_field_id(type);
1479
1480
1481
1482
1483 res = db_search(pbs_data.db_handle, field_id, NUMBER_IDX, order_num, pb_sim_search_num_func, PHB_MATCH_PARTIAL, number);
1484
1485 if(res > DB_OK)
1486 {
1487 return PHB_OK;
1488 }
1489
1490 return PHB_FAIL;
1491 }
1492
1493 /*
1494 +--------------------------------------------------------------------+
1495 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1496 | STATE : code ROUTINE: pb_sim_read_sizes |
1497 +--------------------------------------------------------------------+
1498
1499 PURPOSE : Reads the sizes of a given phonebook.
1500 */
1501
1502 T_PHB_RETURN pb_sim_read_sizes (T_PHB_TYPE type,
1503 SHORT *max_rcd,
1504 SHORT *used_rcd,
1505 UBYTE *tag_len,
1506 SHORT *max_ext,
1507 SHORT *used_ext)
1508 {
1509 T_DB_INFO_FIELD info_field;
1510 USHORT field_id;
1511 T_DB_CODE db_result;
1512
1513 TRACE_FUNCTION("pb_sim_read_sizes()");
1514
1515 /* Set every output parameter to zero for (not there) */
1516 *max_rcd = 0;
1517 *used_rcd = 0;
1518 *tag_len = 0;
1519 *max_ext = 0;
1520 *used_ext = 0;
1521
1522 /* Handling for ECC Phonebook */
1523 if(type EQ ECC)
1524 {
1525 *max_rcd = pbs_data.max_record[ECC];
1526 *used_rcd = pbs_data.used_record[ECC];
1527 *tag_len = 0; /* To Do:Alpha tag will not be there for ECC. So assigning zero here */
1528 return PHB_OK;
1529 }
1530
1531 /* Get elementary file ID for the Phonebook type. */
1532 field_id = pb_sim_get_field_id (type);
1533
1534 /* Query the database about the field */
1535 db_result = db_info_field (pbs_data.db_handle, field_id, &info_field);
1536
1537 if (db_result EQ DB_OK)
1538 {
1539 /* We got results for the main phonebook entries. */
1540 *max_rcd = info_field.num_records;
1541 *used_rcd = info_field.used_records;
1542 *tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
1543
1544 /* Get elementary file ID for the respective extension. */
1545 field_id = pb_sim_get_ext_file (type);
1546 if (field_id NEQ 0)
1547 {
1548 /*
1549 * Extension records may exist for this kind of phonebook.
1550 * Query the database about the ext records.
1551 */
1552 db_result = db_info_field (pbs_data.db_handle, field_id, &info_field);
1553 if (db_result EQ DB_OK)
1554 {
1555 /* There are also extension records present in the database. */
1556 *max_ext = info_field.num_records;
1557 *used_ext = info_field.used_records;
1558 }
1559 /* There is no else as it is not a problem if there are no extension
1560 * records for the phonebook on the SIM as those are optional only. */
1561 }
1562 return PHB_OK;
1563 }
1564 return PHB_FAIL; /* The phonebook does not exist */
1565 }
1566
1567 /*
1568 +--------------------------------------------------------------------+
1569 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1570 | STATE : code ROUTINE: pb_sim_get_entry_len |
1571 +--------------------------------------------------------------------+
1572
1573 PURPOSE : Used to get the length in bytes of a given entry which is coded as given in 11.11 Annex B.
1574 */
1575
1576 int pb_sim_get_entry_len (const UBYTE *pb_tag, UBYTE max_pb_len)
1577 {
1578
1579 int pb_len = 0;
1580 UBYTE inc_count = 1;
1581 BOOL ucs2 = FALSE;
1582 UBYTE chars = 0;
1583
1584 TRACE_FUNCTION("pb_sim_get_entry_len()");
1585
1586 if (*pb_tag EQ 0x80)
1587 {
1588 ucs2 = TRUE;
1589 inc_count = 2; /* check two bytes */
1590 pb_len = 1; /* skip the 0x80 */
1591 }
1592 else if (*pb_tag EQ 0x81 OR *pb_tag EQ 0x82)
1593 {
1594 if (*pb_tag EQ 0x81)
1595 pb_len = 3; /* 0x80 + len + pointer */
1596 else
1597 pb_len = 4; /* 0x80 + len + 2xpointer */
1598
1599 chars = pb_tag[1];
1600 pb_tag += pb_len; /* go to data */
1601 while (chars)
1602 {
1603 if (*pb_tag++ & 0x80)
1604 pb_len+=2;
1605 else
1606 pb_len+=1;
1607
1608 pb_tag++;
1609 chars--;
1610 }
1611 return MINIMUM(pb_len,max_pb_len);
1612 }
1613
1614 while (pb_len < max_pb_len)
1615 {
1616 if (ucs2 EQ TRUE)
1617 {
1618 if (!(pb_len+1 < max_pb_len)) /* Check also if we traverse the upper bound */
1619 break; /* so only a "half" UCS2 element is remaining */
1620 }
1621 if (pb_tag[pb_len] EQ 0xFF)
1622 {
1623 /* one 0xFF indicates the end of a non UCS2 string */
1624 if (ucs2 EQ FALSE)
1625 {
1626 break;
1627 }
1628 /* two 0xFF indicates the end of a UCS2 string */
1629 if (pb_tag[pb_len + 1] EQ 0xFF)
1630 {
1631 break;
1632 }
1633 }
1634 pb_len += inc_count;
1635 }
1636
1637 return (pb_len);
1638 }
1639
1640 /*
1641 +--------------------------------------------------------------------+
1642 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1643 | STATE : code ROUTINE: pb_sim_alpha_cmp |
1644 +--------------------------------------------------------------------+
1645
1646 PURPOSE : Compares alpha identifier of two records.
1647 */
1648 int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags)
1649 {
1650 T_PHB_RECORD entry_1,entry_2;
1651 UBYTE cmpLen = 0;
1652 UBYTE *buffer;
1653 UBYTE max_tag_len;
1654 UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN];
1655 int cmp_res;
1656 T_DB_INFO_FIELD info_field;
1657
1658 TRACE_FUNCTION("pb_sim_alpha_cmp()");
1659
1660
1661 db_info_field(db_handle, field_id, &info_field);
1662
1663 MALLOC(buffer, info_field.record_size);
1664
1665 /* Read the first record. */
1666 db_read_record(db_handle, field_id, recno_1, 0, info_field.record_size, buffer);
1667
1668 /* Unpack record 1 to do a string comparison on the alpha identifier field */
1669 max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
1670 if (max_tag_len > PHB_MAX_TAG_LEN)
1671 max_tag_len = PHB_MAX_TAG_LEN;
1672
1673 entry_1.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
1674
1675 memset(entry_1.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
1676 memcpy ( (char*)entry_1.tag, (char*)buffer, entry_1.tag_len );
1677
1678 pb_sim_cvt_alpha_for_cmp ( entry_1.tag, cur_tag, entry_1.tag_len );
1679
1680 memset(buffer, 0, info_field.record_size);
1681
1682 /* Read the second record. */
1683 db_read_record(db_handle, field_id, recno_2, 0, info_field.record_size, buffer);
1684
1685 /* Unpack record 2 to do a string comparison on the alpha identifier field */
1686 max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
1687 if (max_tag_len > PHB_MAX_TAG_LEN)
1688 max_tag_len = PHB_MAX_TAG_LEN;
1689
1690 entry_2.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
1691
1692 memset(entry_2.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
1693 memcpy ( (char*)entry_2.tag, (char*)buffer, entry_2.tag_len );
1694
1695 pb_sim_cvt_alpha_for_cmp ( entry_2.tag, check_tag, entry_2.tag_len );
1696
1697 cmpLen = MINIMUM ( entry_1.tag_len,
1698 entry_2.tag_len );
1699
1700 TRACE_EVENT_P1("%d", cmpLen);
1701
1702 cmp_res = pb_sim_cmpString ( cur_tag, check_tag, cmpLen );
1703
1704 if (cmp_res EQ 0)
1705 {
1706 /* Correct result when length was different, ACIPHB201 */
1707 if (entry_1.tag_len < entry_2.tag_len)
1708 cmp_res = -1;
1709 else if (entry_1.tag_len > entry_2.tag_len)
1710 cmp_res = 1;
1711 }
1712
1713 MFREE(buffer);
1714
1715 return cmp_res;
1716 }
1717 /*
1718 +--------------------------------------------------------------------+
1719 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1720 | STATE : code ROUTINE: pb_sim_read_number |
1721 +--------------------------------------------------------------------+
1722
1723 PURPOSE : Reads a phine number from a given record
1724 */
1725 LOCAL void pb_sim_read_number (int db_handle,
1726 USHORT field_id,
1727 USHORT recno,
1728 CHAR *number)
1729 {
1730 T_PHB_RECORD entry;
1731 T_DB_INFO_FIELD info_field;
1732 UBYTE *sim_buffer, *buffer;
1733 UBYTE ext_rcd_num;
1734 unsigned ext_rec_cnt;
1735 USHORT ext_id;
1736
1737 TRACE_FUNCTION("pb_sim_read_number()");
1738
1739 ACI_MALLOC(sim_buffer, SIM_MAX_RECORD_SIZE);
1740 buffer = sim_buffer;
1741
1742 db_info_field(db_handle, field_id, &info_field);
1743
1744 /* Read record recno_1 from the database using db_read_record() */
1745 db_read_record (db_handle, field_id, recno, 0, info_field.record_size, buffer);
1746
1747 /* Read only number from the buffer. */
1748 buffer += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
1749 entry.len = *(buffer++) - 1;
1750 entry.ton_npi = *buffer++;
1751
1752 /*
1753 * This error handling is done to avoid the accidental incorrect
1754 * record length stored in the test SIMs
1755 */
1756 if (entry.len > PHB_PHY_NUM_LENGTH)
1757 {
1758 entry.len = PHB_PHY_NUM_LENGTH;
1759 }
1760
1761 memset (entry.number, 0xFF, PHB_PACKED_NUM_LEN);
1762 memcpy (entry.number, buffer, entry.len);
1763 buffer += 10;
1764 entry.cc_id = *buffer++;
1765 ext_rcd_num = (UBYTE)*buffer;
1766 ext_id = pb_sim_get_ext_file_id (field_id);
1767 if ((ext_id NEQ 0) AND
1768 (db_info_field (db_handle, ext_id, &info_field) EQ DB_OK))
1769 {
1770 /* Extension records exist and we can obtain information about it */
1771 ext_rec_cnt = 0;
1772 while ((ext_rcd_num NEQ 0xFF) AND
1773 (ext_rcd_num NEQ 0) AND
1774 (ext_rcd_num <= info_field.num_records) AND
1775 (ext_rec_cnt < info_field.num_records))
1776 {
1777 /*
1778 * Record not empty, in range 1..max num of ext records
1779 * Impossible to have read all records (avoid infinite loop)
1780 */
1781 ext_rec_cnt++;
1782 (void)db_read_record (db_handle, ext_id, ext_rcd_num,
1783 0, info_field.record_size,
1784 buffer);
1785 pb_sim_read_ext (buffer, &entry);
1786 ext_rcd_num = sim_buffer[12];
1787 }
1788 }
1789
1790 cmhPHB_getAdrStr(number,
1791 MAX_PHB_NUM_LEN - 1,
1792 entry.number,
1793 entry.len);
1794
1795 ACI_MFREE (sim_buffer);
1796 }
1797
1798 /*
1799 +--------------------------------------------------------------------+
1800 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1801 | STATE : code ROUTINE: pb_sim_number_cmp |
1802 +--------------------------------------------------------------------+
1803
1804 PURPOSE : Compares two numbers of two records.
1805 */
1806 int pb_sim_number_cmp (int db_handle,
1807 USHORT field_id,
1808 USHORT recno_1,
1809 USHORT recno_2,
1810 ULONG flags)
1811 {
1812 CHAR cur_number[MAX_PHB_NUM_LEN];
1813 CHAR ref_number[MAX_PHB_NUM_LEN];
1814
1815 TRACE_FUNCTION("pb_sim_number_cmp()");
1816
1817 /* Read the numbers */
1818 pb_sim_read_number (db_handle, field_id, recno_1, cur_number);
1819 pb_sim_read_number (db_handle, field_id, recno_2, ref_number);
1820
1821 /* Reverse the numbers to compare number from right. */
1822 pb_sim_revString(cur_number);
1823 pb_sim_revString(ref_number);
1824
1825 return pb_sim_cmpWild ((char *)cur_number, (char *)ref_number, MAX_PHB_NUM_LEN);
1826 }
1827
1828 /*
1829 +--------------------------------------------------------------------+
1830 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1831 | STATE : code ROUTINE: pb_sim_read_ext |
1832 +--------------------------------------------------------------------+
1833
1834 PURPOSE : Reads extension records from the database and copies them to number.
1835 */
1836 /* Extesion records will be stored as per 11.11.
1837 Bytes Description M/O Length
1838 --------------------------------------
1839 1 Record type M 1 byte
1840 2 to 12 Extension data M 11 bytes
1841 13 Identifier M 1 byte
1842 --------------------------------------*/
1843
1844 void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry)
1845 {
1846 UBYTE data_len;
1847 UBYTE data_type;
1848 UBYTE *data;
1849
1850 TRACE_FUNCTION("pb_sim_read_ext()");
1851
1852 /* If this extension record is not empty, it is written in phonebook. */
1853 data = buffer;
1854
1855 data_type = *data;
1856 data_len = *(data+1);
1857
1858 switch (data_type)
1859 {
1860
1861 case 1: /* Called Party Subaddress */
1862 {
1863 int sa_len = 0;
1864 while (sa_len<PHB_PACKED_NUM_LEN) /* get length of possible already stored subaddr if more than one EXT is used */
1865 {
1866 if (entry->subaddr[sa_len] EQ 0xFF)
1867 break;
1868 else if ((entry->subaddr[sa_len] & 0xF0) EQ 0xF0)
1869 {
1870 sa_len++;
1871 break;
1872 }
1873 else
1874 sa_len++;
1875 }
1876
1877 pb_sim_nibblecopy (entry->subaddr,
1878 sa_len,
1879 data + 2,
1880 data_len);
1881 }
1882 break;
1883
1884 case 2: /* Additional data */
1885 entry->len =
1886 pb_sim_nibblecopy (entry->number,
1887 entry->len,
1888 data + 2,
1889 data_len);
1890 break;
1891
1892 default: /* unknown type */
1893 break;
1894 }
1895
1896 return;
1897 }
1898
1899 /*
1900 +--------------------------------------------------------------------+
1901 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1902 | STATE : code ROUTINE: pb_sim_revString |
1903 +--------------------------------------------------------------------+
1904
1905 PURPOSE : Reverses a string within the same variable.
1906 */
1907
1908 void pb_sim_revString(char *str)
1909 {
1910 UBYTE i, j,str_len;
1911 char ch;
1912
1913 TRACE_FUNCTION("pb_sim_revString()");
1914
1915 str_len = strlen(str);
1916
1917 for(i = 0, j = str_len - 1;i < (str_len / 2); i++, j--)
1918 {
1919 ch = *(str + i);
1920 *(str + i) = *(str + j);
1921 *(str + j) = ch;
1922 }
1923 }
1924
1925 /*
1926 +--------------------------------------------------------------------+
1927 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1928 | STATE : code ROUTINE: pb_sim_search_alpha_func |
1929 +--------------------------------------------------------------------+
1930
1931 PURPOSE : Searches for a given alpha key in the database.
1932 */
1933
1934 int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num)
1935 {
1936 T_ACI_PB_TEXT *search_key;
1937 T_PHB_RECORD entry;
1938 UBYTE cmpLen = 0;
1939 T_PHB_TYPE phb_type;
1940 UBYTE cur_tag[PHB_MAX_TAG_LEN];
1941 int cmp_res;
1942
1943 TRACE_FUNCTION("pb_sim_search_alpha_func()");
1944
1945 /* Cast search key to appropriate data structure */
1946 search_key = (T_ACI_PB_TEXT *)key;
1947
1948 /* Get PHB type from field ID using PHB_ACI function. */
1949 phb_type = pb_get_phb_type_from_ef(field_id);
1950
1951 /* Read record from the database. */
1952 pb_sim_read_record(phb_type, rec_num, &entry);
1953
1954 pb_sim_cvt_alpha_for_cmp ( entry.tag, cur_tag, entry.tag_len );
1955
1956 cmpLen = search_key->len;
1957
1958 if(flags EQ PHB_MATCH_PARTIAL)
1959 cmpLen = MINIMUM ( entry.tag_len, cmpLen);
1960
1961 TRACE_EVENT_P1( "cmpLen=%d", cmpLen );
1962
1963 cmp_res = pb_sim_cmpString ( cur_tag, search_key->data, cmpLen );
1964
1965 return cmp_res;
1966 }
1967
1968
1969 /*
1970 +----------------------------------------------------------------------------+
1971 | PROJECT: MMI-Framework (8417) MODULE: PHB |
1972 | STATE : code ROUTINE: pb_sim_search_num_func |
1973 +----------------------------------------------------------------------------+
1974
1975 PURPOSE : Searches for a given number key in the database.
1976 */
1977 int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle,
1978 USHORT field_id, USHORT rec_num)
1979 {
1980 T_PHB_RECORD entry;
1981 UBYTE cmpLen = 0;
1982 T_PHB_TYPE phb_type;
1983 CHAR cur_number[MAX_PHB_NUM_LEN];
1984 CHAR rev_key[MAX_PHB_NUM_LEN];
1985 int cmp_res;
1986 size_t strg_len;
1987
1988 TRACE_FUNCTION("pb_sim_search_num_func()");
1989
1990 /* Get PHB type from field ID using PHB_ACI function. */
1991 phb_type = pb_get_phb_type_from_ef(field_id);
1992
1993 /* Read record from the database. */
1994 if(pb_sim_read_record(phb_type, rec_num, &entry) NEQ PHB_OK)
1995 return -1;
1996
1997 cmhPHB_getAdrStr(cur_number,
1998 MAX_PHB_NUM_LEN - 1,
1999 entry.number,
2000 entry.len);
2001
2002 /* Reverse the first number to compare number from right. */
2003 pb_sim_revString(cur_number);
2004
2005 /* Reverse the second number to compare number from right. */
2006
2007 strcpy (rev_key, (const char*) key);
2008
2009 pb_sim_revString(rev_key);
2010
2011 cmpLen = strlen(rev_key);
2012
2013 if(flags EQ PHB_MATCH_PARTIAL)
2014 {
2015 strg_len = strlen(cur_number);
2016 cmpLen = MINIMUM(strg_len, cmpLen);
2017 }
2018
2019 TRACE_EVENT_P1("Number to be compared: %s", cur_number);
2020 TRACE_EVENT_P1("Number to be searched: %s", rev_key);
2021 if(cmpLen > 7)
2022 {
2023 cmpLen = 7;
2024 }
2025
2026 cmp_res = pb_sim_cmpWild((char*)cur_number, (char*)rev_key, cmpLen);
2027
2028
2029 TRACE_EVENT_P1("Result of the comparison: %d", cmp_res);
2030
2031 return cmp_res;
2032
2033 }
2034
2035 /*
2036 +--------------------------------------------------------------------+
2037 | PROJECT: MMI-Framework (8417) MODULE: PHB |
2038 | STATE : code ROUTINE: pb_sim_nibblecopy |
2039 +--------------------------------------------------------------------+
2040
2041 PURPOSE : Used to convert BCD nibbles to string.
2042 */
2043
2044 LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count)
2045 {
2046
2047 int i;
2048 int nibble;
2049
2050 int destnibble=destlen*2;
2051
2052 TRACE_FUNCTION("pb_sim_nibblecopy()");
2053
2054 if (destnibble)
2055 {
2056 if ((dest[destlen-1] & 0xF0) == 0xF0) /* check if there is space in last nibble */
2057 destnibble--;
2058 }
2059
2060 for ( i=0; i<count*2; i++ )
2061 {
2062 /* check if we access out of bounds */
2063 if (destnibble/2 >= PHB_PACKED_NUM_LEN)
2064 return PHB_PACKED_NUM_LEN;
2065
2066 /* get nibble */
2067 if (i%2 == 0)
2068 nibble = src[i/2] & 0x0F;
2069 else
2070 nibble = (src[i/2] & 0xF0) >> 4;
2071
2072 if (nibble == 0xF) /* end of number detected */
2073 break;
2074
2075 /* put nibble */
2076 if (destnibble%2 == 0)
2077 {
2078 dest[destnibble/2] &= 0xF0;
2079 dest[destnibble/2] |= nibble;
2080 }
2081 else
2082 {
2083 dest[destnibble/2] &= 0x0F;
2084 dest[destnibble/2] |= nibble << 4;
2085 }
2086
2087 destnibble++;
2088 }
2089 return destnibble/2 + destnibble%2; /* round up */
2090 }
2091
2092 /*
2093 +------------------------------------------------------------------------+
2094 | PROJECT : MMI-Framework (8417) MODULE: PHB |
2095 | STATE : code ROUTINE : pb_sim_read_eeprom_ecc |
2096 +------------------------------------------------------------------------+
2097
2098 PURPOSE : Read EC number from EEPROM.
2099
2100 */
2101 LOCAL void pb_sim_read_eeprom_ecc (void)
2102 {
2103 EF_ECC efecc;
2104 UBYTE *data_ptr;
2105 UBYTE version;
2106 int rec_ctr;
2107
2108 TRACE_FUNCTION("pb_sim_read_eeprom_ecc()");
2109
2110 /* Initialise ECC Phonebook Info. */
2111 pbs_data.max_record[ECC] = MAX_ECC_RCD;
2112 pbs_data.used_record[ECC] = 0;
2113
2114 if (pcm_ReadFile((UBYTE *)EF_ECC_ID,
2115 SIZE_EF_ECC,
2116 (UBYTE *)&efecc,
2117 &version) EQ DRV_OK)
2118 {
2119 { /* workaround when invalid data stored on PCM */
2120 CHAR ecc_number[MAX_PHB_NUM_LEN];
2121 int num_len;
2122
2123 data_ptr = efecc.ecc1;
2124
2125 for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
2126 {
2127 if (*data_ptr NEQ 0xFF)
2128 {
2129 cmhPHB_getAdrStr (ecc_number,
2130 MAX_PHB_NUM_LEN - 1,
2131 data_ptr,
2132 ECC_NUM_LEN);
2133 for (num_len = 0; num_len < ECC_NUM_LEN; num_len++)
2134 {
2135 if (!isdigit (ecc_number[num_len]))
2136 {
2137 TRACE_EVENT_P2 ("[ERR] pb_read_eeprom_ecc(): invalid character found %c (%d)",
2138 ecc_number[num_len], rec_ctr);
2139 return;
2140 }
2141 }
2142 }
2143 data_ptr += ECC_NUM_LEN;
2144 }
2145 } /* workaround end */
2146
2147 data_ptr = &efecc.ecc1[0];
2148
2149 memset( phb_ecc_element,0xFF, (pbs_data.max_record[ECC] * sizeof(T_PHB_ECC_RECORD)) );
2150
2151 for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
2152 {
2153 if(*data_ptr NEQ 0xff)
2154 {
2155 phb_ecc_element[rec_ctr].phy_idx = rec_ctr + 1;
2156 memcpy(phb_ecc_element[rec_ctr].number, data_ptr, ECC_NUM_LEN);
2157 data_ptr += ECC_NUM_LEN;
2158 (pbs_data.used_record[ECC])++;
2159 }
2160 }
2161 }
2162 }
2163
2164 /*
2165 +----------------------------------------------------------------------+
2166 | PROJECT : MODULE : PHB |
2167 | STATE : code ROUTINE : pb_sim_prepare_ext_data |
2168 +----------------------------------------------------------------------+
2169
2170
2171 PURPOSE : Prepare the data for the extention record.
2172 If NULL pointer is given for number and subaddress
2173 then the extention record will marked as unused
2174
2175 */
2176 /* Extesion records will be stored as per 11.11.
2177 Bytes Description M/O Length
2178 --------------------------------------
2179 1 Record type M 1 byte
2180 2 to 12 Extension data M 11 bytes
2181 13 Identifier M 1 byte
2182 --------------------------------------*/
2183
2184 LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr)
2185 {
2186 UBYTE *data_num = NULL;
2187 UBYTE *data_subadd = NULL;
2188
2189 TRACE_FUNCTION("pb_sim_prepare_ext_data()");
2190
2191 if(number[10] NEQ 0xFF)
2192 data_num = number + ((ext_count + 1) * 10);
2193
2194 data_subadd = subaddr + (ext_count * 11);
2195
2196 memset(ext_data, 0xFF, sizeof(ext_data));
2197
2198 if ((data_num NEQ NULL) AND (*data_num NEQ 0xFF))
2199 {
2200 /* Set record type to 2 which corresponds to Additional data. Record type as per 11.11 */
2201 ext_data[0] = 2;
2202 ext_data[1] = no_len - ((ext_count + 1) * 10);
2203 memcpy (ext_data + 2, data_num, 10);
2204 }
2205 else if ((data_subadd NEQ NULL) AND (*data_subadd NEQ 0xFF))
2206 {
2207 TRACE_EVENT ("SUBADDRESS EXTENTION");
2208 /* Set record type to 1 which corresponds to Called Party Subaddress. Record type as per 11.11 */
2209 ext_data[0] = 1;
2210 memcpy (ext_data + 1, data_subadd, 11);
2211 }
2212 }
2213
2214 /*
2215 +----------------------------------------------------------------------+
2216 | PROJECT : MODULE : PHB |
2217 | STATE : code ROUTINE : pb_sim_get_field_id |
2218 +----------------------------------------------------------------------+
2219
2220
2221 PURPOSE : Returns field ID for the corresponding Phonebook type.
2222
2223 */
2224 LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type)
2225 {
2226 USHORT field_id;
2227
2228 TRACE_FUNCTION("pb_sim_get_field_id()");
2229
2230 /* Get Elementary file ID for the Phonebook type. */
2231 switch(type)
2232 {
2233 case ADN:
2234 field_id = SIM_ADN;
2235 break;
2236
2237 case LDN:
2238 field_id = SIM_OCI;
2239 break;
2240
2241 case LRN:
2242 field_id = FFS_LRN;
2243 break;
2244
2245 case LMN:
2246 field_id = FFS_LMN;
2247 break;
2248
2249 case UPN:
2250 field_id = SIM_MSISDN;
2251 break;
2252
2253 case FDN:
2254 field_id = SIM_FDN;
2255 break;
2256
2257 case SDN:
2258 field_id = SIM_SDN;
2259 break;
2260
2261 case BDN:
2262 field_id = SIM_BDN;
2263 break;
2264
2265 default:
2266 TRACE_ERROR ("No such field");
2267 TRACE_EVENT_P1 ("No such field for type = %04X", type);
2268 field_id = 0;
2269 break;
2270 }
2271
2272 return field_id;
2273 }
2274
2275 /*
2276 +----------------------------------------------------------------------+
2277 | PROJECT : MODULE : PHB |
2278 | STATE : code ROUTINE : pb_sim_get_ext_file |
2279 +----------------------------------------------------------------------+
2280
2281
2282 PURPOSE : Returns field ID for the corresponding Phonebook type.
2283
2284 */
2285 LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type)
2286 {
2287 USHORT ext_file_id;
2288
2289 TRACE_FUNCTION("pb_sim_get_ext_file()");
2290
2291 /* Get Extension Elementary file ID for the Phonebook type. */
2292 switch(type)
2293 {
2294 case ADN:
2295 case UPN:
2296 ext_file_id = SIM_EXT1;
2297 break;
2298
2299 case FDN:
2300 ext_file_id = SIM_EXT2;
2301 break;
2302
2303 case SDN:
2304 ext_file_id = SIM_EXT3;
2305 break;
2306
2307 case BDN:
2308 ext_file_id = SIM_EXT4;
2309 break;
2310
2311 case LDN:
2312 ext_file_id = SIM_EXT5;
2313 break;
2314
2315 case LRN:
2316 ext_file_id = FFS_EXT_LRN;
2317 break;
2318
2319 case LMN:
2320 ext_file_id = FFS_EXT_LMN;
2321 break;
2322
2323 default:
2324 ext_file_id = 0; /* No extension records available */
2325 break;
2326 }
2327
2328 return ext_file_id;
2329 }
2330
2331 /*
2332 +---------------------------------------------------------------------+
2333 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2334 | STATE : code ROUTINE : pb_sim_cvt_alpha_for_cmp |
2335 +---------------------------------------------------------------------+
2336
2337 PURPOSE : convert alpha to lower case when not unicode
2338
2339 */
2340 LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE *src,
2341 UBYTE *dst,
2342 UBYTE len )
2343 {
2344 int i;
2345
2346 TRACE_FUNCTION("pb_sim_cvt_alpha_for_cmp()");
2347
2348 if (*src NEQ 0x80) /* 11.11 Annex B 0x80 is the UCS2 indicator */
2349 {
2350 for ( i = 0; i < len; i++ )
2351 dst[i] = (UBYTE)tolower((int)src[i]);
2352 }
2353 else
2354 {
2355 memcpy (dst, src, len);
2356 }
2357 }
2358
2359 /*
2360 +----------------------------------------------------------------------+
2361 | PROJECT : MODULE : PHB |
2362 | STATE : code ROUTINE : pb_sim_get_ext_file_id |
2363 +----------------------------------------------------------------------+
2364
2365
2366 PURPOSE : Returns Extension field ID for the corresponding field ID of a Phonebook.
2367
2368 */
2369 LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id)
2370 {
2371 USHORT ext_file_id;
2372
2373 TRACE_FUNCTION("pb_sim_get_ext_file_id()");
2374
2375 /* Get Extension Elementary file ID for the Phonebook type. */
2376 switch(field_id)
2377 {
2378 case SIM_ADN:
2379 case SIM_LND:
2380 case SIM_MSISDN:
2381 ext_file_id = SIM_EXT1;
2382 break;
2383
2384 case SIM_FDN:
2385 ext_file_id = SIM_EXT2;
2386 break;
2387
2388 case SIM_SDN:
2389 ext_file_id = SIM_EXT3;
2390 break;
2391
2392 case SIM_BDN:
2393 ext_file_id = SIM_EXT4;
2394 break;
2395
2396 case SIM_OCI:
2397 ext_file_id = SIM_EXT5;
2398 break;
2399
2400 case FFS_LRN:
2401 ext_file_id = FFS_EXT_LRN;
2402 break;
2403
2404 case FFS_LMN:
2405 ext_file_id = FFS_EXT_LMN;
2406 break;
2407
2408 default:
2409 ext_file_id = 0;
2410 break;
2411 }
2412
2413 return ext_file_id;
2414 }
2415
2416 /*
2417 +----------------------------------------------------------------------+
2418 | PROJECT : MODULE : PHB |
2419 | STATE : code ROUTINE : pb_sim_get_ext_type |
2420 +----------------------------------------------------------------------+
2421
2422
2423 PURPOSE : Returns Extension Type ID for the corresponding
2424 field ID of a Phonebook.
2425
2426 */
2427 LOCAL T_EXT_TYPE pb_sim_get_ext_type (USHORT field_id)
2428 {
2429 T_EXT_TYPE ext_type;
2430
2431 /* Get Extension Type for the Phonebook field ID. */
2432 switch(field_id)
2433 {
2434 case SIM_ADN:
2435 case SIM_LND:
2436 case SIM_MSISDN:
2437 ext_type = EXT1;
2438 break;
2439
2440 case SIM_FDN:
2441 ext_type = EXT2;
2442 break;
2443
2444 case SIM_SDN:
2445 ext_type = EXT3;
2446 break;
2447
2448 case SIM_BDN:
2449 ext_type = EXT4;
2450 break;
2451
2452 case SIM_OCI:
2453 ext_type = EXT5;
2454 break;
2455
2456 case FFS_LRN:
2457 ext_type = EXT_LRN;
2458 break;
2459
2460 case FFS_LMN:
2461 ext_type = EXT_LMN;
2462 break;
2463
2464 default:
2465 ext_type = INVALID_EXT;
2466 break;
2467 }
2468
2469 return ext_type;
2470 }
2471
2472 /*
2473 +----------------------------------------------------------------------+
2474 | PROJECT : MODULE : PHB |
2475 | STATE : code ROUTINE : pb_sim_find_free_record |
2476 +----------------------------------------------------------------------+
2477
2478
2479 PURPOSE : Returns free record number for the Phonebook type.
2480
2481 */
2482 GLOBAL int pb_sim_find_free_record (T_PHB_TYPE type)
2483 {
2484 int db_result;
2485 unsigned i;
2486 USHORT field_id;
2487
2488 TRACE_FUNCTION("pb_sim_find_free_record()");
2489
2490 switch (type)
2491 {
2492 case ECC: /* ECC not stored in DB, special handling */
2493 for (i = 0; i < pbs_data.max_record[ECC]; i++)
2494 {
2495 if (phb_ecc_element[i].phy_idx EQ 0)
2496 return i + 1;
2497 }
2498 return 0; /* No free record found */
2499
2500 case LDN:
2501 case LRN:
2502 case LMN:
2503 return 1; /* For cyclic entries always the first */
2504
2505 default:
2506 /* Get Elementary file ID for the Phonebook type. */
2507 field_id = pb_sim_get_field_id(type);
2508
2509 db_result = db_find_free_record(pbs_data.db_handle, field_id);
2510
2511 if (db_result <= 0)
2512 return 0; /* No free record */
2513
2514 return db_result;
2515 }
2516 }
2517
2518 GLOBAL int pb_sim_find_free_ext_record ()
2519 {
2520 int db_result;
2521 unsigned i;
2522 USHORT field_id;
2523
2524 TRACE_FUNCTION("pb_find_ext_free_record()");
2525
2526 field_id =SIM_EXT1;
2527
2528 db_result = db_find_free_record(pbs_data.db_handle, field_id);
2529
2530 if (db_result <= 0)
2531 return 0; /* No free record */
2532
2533 return db_result;
2534 }
2535
2536
2537
2538
2539
2540 /*
2541 +-------------------------------------------------------------------------------+
2542 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2543 | STATE : code ROUTINE : pb_sim_get_size_except_tag |
2544 +-------------------------------------------------------------------------------+
2545
2546 PURPOSE : Returns size of data excluding length of tag (alpha identifier)
2547 */
2548 USHORT pb_sim_get_size_except_tag (USHORT field_id)
2549 {
2550
2551 TRACE_FUNCTION("pb_sim_get_size_except_tag()");
2552 switch(field_id)
2553 {
2554 case SIM_ADN:
2555 case SIM_FDN:
2556 case SIM_BDN:
2557 case SIM_MSISDN:
2558 case SIM_SDN:
2559 return 14; /* 11.11 */
2560
2561 case FFS_LRN:
2562 case FFS_LMN:
2563 case SIM_OCI:
2564 return 27; /* Using EF_OCI, 31.102 4.2.34 */
2565
2566 //case SIM_ICI:
2567 // return 28; /* Using EF_ICI, 31.102 4.2.33 */
2568
2569 default:
2570 TRACE_ERROR("Invalid field ID passed !");
2571 return 0;
2572 }
2573 }
2574 /*
2575 +--------------------------------------------------------------------+
2576 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2577 | STATE : code ROUTINE : pb_sim_cmpString |
2578 +--------------------------------------------------------------------+
2579
2580 PURPOSE : compare two strings.
2581 if s1 < s2 return value < 0
2582 if s1 = s2 return value = 0
2583 if s1 > s2 return value > 0
2584 */
2585
2586 static int pb_sim_cmpString ( UBYTE *s1, UBYTE *s2, UBYTE len )
2587 {
2588 int n = 0;
2589
2590 /* TRACE_FUNCTION("pb_sim_cmpString()"); */ /* Called too often to trace */
2591
2592 if ((*s1 EQ 0x80) AND
2593 (*s2 NEQ 0x80) )
2594 {
2595 s1++;
2596 len--;
2597 return pb_sim_cmp2Bytes(s1, s2, len, 1);
2598 }
2599 else if ((*s1 NEQ 0x80) AND
2600 (*s2 EQ 0x80) )
2601 {
2602 s2++;
2603 len--;
2604 return pb_sim_cmp2Bytes(s1, s2, len, 2);
2605 }
2606 else
2607 {
2608 while (*s1 EQ *s2)
2609 {
2610 if (*s1 EQ 0xff)
2611 return 0;
2612 s1++;
2613 s2++;
2614 n++;
2615 if (n EQ len)
2616 return 0;
2617 }
2618
2619 if ((*s1 > *s2) AND (*s1 NEQ 0xff))
2620 return 1;
2621
2622 return -1;
2623 }
2624 }
2625
2626 /*
2627 +--------------------------------------------------------------------+
2628 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2629 | STATE : code ROUTINE : pb_sim_cmp2Bytes |
2630 +--------------------------------------------------------------------+
2631
2632 PURPOSE : compare two strings.
2633 if s1 < s2 return value < 0
2634 if s1 = s2 return value = 0
2635 if s1 > s2 return value > 0
2636
2637 flag = 1, s1 is unicode
2638 flag = 2, s2 is unicode
2639 */
2640
2641 LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag)
2642 {
2643 int n = 0;
2644
2645 /* TRACE_FUNCTION("pb_sim_cmp2Bytes()"); */
2646
2647 if (flag EQ 1)
2648 {
2649 while ( (*s1 EQ 0x00 OR *s1 EQ 0xFF ) AND ( *(s1+1) EQ *s2) )
2650 {
2651 if (*s1 EQ 0xff AND *(s1+1) EQ 0xFF)
2652 return 0;
2653
2654 s1 += 2;
2655 s2++;
2656 n += 2;
2657
2658 if (n >= len)
2659 return 0;
2660 }
2661
2662 if ( ( *s1 > 0 AND *s1 NEQ 0xff ) OR
2663 ( !*s1 AND ( *(s1+1) > *s2 ) ) )
2664 return 1;
2665
2666 return -1;
2667 }
2668
2669 if (flag EQ 2)
2670 {
2671 while ((*s2 EQ 0x00 OR *s2 EQ 0xFF) AND (*s1 EQ *(s2+1)))
2672 {
2673 if (*s2 EQ 0xff AND *(s2+1) EQ 0xFF)
2674 return 0;
2675
2676 s1++;
2677 s2 += 2;
2678 n += 2;
2679
2680 if (n >= len)
2681 return 0;
2682 }
2683
2684 if ((*s2 > 0 AND *s2 NEQ 0xff) OR
2685 (!*s2 AND (*(s2+1) > *s1)) )
2686 return -1;
2687
2688 return 1;
2689 }
2690 return -1;
2691 }
2692
2693
2694 /*
2695 +----------------------------------------------------------------------------+
2696 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2697 | STATE : code ROUTINE : pb_sim_update_extn_records |
2698 +----------------------------------------------------------------------------+
2699
2700 PURPOSE : Update reference count for extension record and delete if record
2701 is not referenced at all.
2702 ETSI 11.11 clause 11.5.1 states that reference counts not only
2703 have to be maintained for EXT1 but also for other EXT records.
2704 */
2705 LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id,
2706 USHORT rec_num,
2707 SHORT ref_type)
2708 {
2709 T_EXT_TYPE ext_type;
2710 UBYTE *refptr;
2711 int db_result;
2712 UBYTE dummy_ref;
2713
2714 switch (ext_field_id)
2715 {
2716 case SIM_EXT1: ext_type = EXT1; break;
2717 case SIM_EXT2: ext_type = EXT2; break;
2718 case SIM_EXT3: ext_type = EXT3; break;
2719 case SIM_EXT4: ext_type = EXT4; break;
2720 case SIM_EXT5: ext_type = EXT5; break;
2721 case FFS_EXT_LRN: ext_type = EXT_LRN; break;
2722 case FFS_EXT_LMN: ext_type = EXT_LMN; break;
2723 default:
2724 return PHB_FAIL;
2725 }
2726
2727 if (rec_num <= MAX_EXT_RECORDS)
2728 {
2729 refptr = &ext_ref_count[ext_type][rec_num - 1];
2730 }
2731 else
2732 {
2733 /* Could become improved by using dynamic memory but better as using an
2734 * illegal array index. Only ref counters will have a problem here. */
2735 TRACE_ERROR ("SIM exceeds MAX_EXT_RECORDS");
2736 dummy_ref = 1;
2737 refptr = &dummy_ref;
2738 }
2739
2740 if (ref_type EQ -1)
2741 {
2742 /* Decrement usage counter */
2743 if (*refptr > 0)
2744 {
2745 *refptr += ref_type;
2746 }
2747 else
2748 {
2749 TRACE_ERROR ("EXT usage counter below zero");
2750 }
2751
2752 if (*refptr EQ 0)
2753 {
2754 db_result = db_delete_record(pbs_data.db_handle, ext_field_id, rec_num);
2755 if(db_result < DB_OK)
2756 return PHB_FAIL;
2757 }
2758 }
2759 else if (ref_type EQ 1)
2760 {
2761 *refptr += ref_type;
2762 }
2763 else
2764 return PHB_FAIL; /* add_val not in -1, +1 */
2765
2766 TRACE_EVENT_P3 ("Usage count of EXT %04X, record %d = %d",
2767 ext_field_id, rec_num, *refptr);
2768
2769 return PHB_OK;
2770 }
2771
2772 /*
2773 +----------------------------------------------------------------------------+
2774 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2775 | STATE : code ROUTINE : pb_sim_del_ext_records |
2776 +----------------------------------------------------------------------------+
2777
2778 PURPOSE : Read extension records and update the records.
2779
2780 */
2781 #define RETURN(x) { retVal = x; goto cleanup_exit; }
2782 /*lint -e{801} Use of goto*/
2783 LOCAL T_PHB_RETURN pb_sim_del_ext_records (T_PHB_TYPE type,
2784 USHORT field_id,
2785 USHORT db_recno)
2786 {
2787 int db_result;
2788 T_PHB_RETURN retVal;
2789 USHORT ext_file_id;
2790 T_DB_INFO_FIELD info_field;
2791 UBYTE *data;
2792 UBYTE ext_rcd_num;
2793
2794 TRACE_FUNCTION("pb_sim_del_ext_records()");
2795
2796 ACI_MALLOC (data, SIM_MAX_RECORD_SIZE);
2797
2798 /* Get Extension file for the Phonebook type. */
2799 ext_file_id = pb_sim_get_ext_file(type);
2800
2801 /* Read record from the database. */
2802 if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
2803 RETURN (PHB_FAIL)
2804
2805 db_result = db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data);
2806 if (db_result EQ DB_EMPTY_RECORD)
2807 RETURN (PHB_OK) /* Nothing to do */
2808
2809 if (db_result < DB_OK)
2810 RETURN (PHB_FAIL) /* Some other problem */
2811
2812 /* Get extension record identifier */
2813 ext_rcd_num = data[info_field.record_size - 1];
2814
2815 while (ext_rcd_num NEQ 0xFF) /* check for extension records */
2816 {
2817 if(db_info_field (pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
2818 RETURN (PHB_FAIL)
2819
2820 if ((ext_rcd_num EQ 0) OR (ext_rcd_num > info_field.num_records))
2821 {
2822 TRACE_EVENT_P1 ("illegal ext record number %d ignored", ext_rcd_num);
2823 RETURN (PHB_OK)
2824 }
2825
2826 if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, data) < DB_OK)
2827 RETURN (PHB_FAIL)
2828
2829 if (pb_sim_update_extn_records(ext_file_id, ext_rcd_num, -1) EQ PHB_FAIL)
2830 RETURN (PHB_FAIL)
2831
2832 ext_rcd_num = data[12];
2833 }
2834 RETURN (PHB_OK)
2835
2836 cleanup_exit:
2837 ACI_MFREE (data);
2838 return retVal;
2839 }
2840 #undef RETURN
2841
2842 /*
2843 +----------------------------------------------------------------------------+
2844 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2845 | STATE : code ROUTINE : pb_sim_ext_records_used |
2846 +----------------------------------------------------------------------------+
2847
2848 PURPOSE : check if extension records is used by one phone book record (ADN & FDN).
2849
2850 */
2851 #define RETURN(x) { retVal = x; goto cleanup_exit; }
2852 /*lint -e{801} Use of goto*/
2853 LOCAL BOOL pb_sim_ext_records_used (T_PHB_TYPE type,
2854 USHORT field_id,
2855 USHORT db_recno)
2856 {
2857 int db_result;
2858 BOOL retVal;
2859 USHORT ext_file_id;
2860 T_DB_INFO_FIELD info_field;
2861 UBYTE *data;
2862 UBYTE ext_rcd_num;
2863
2864 TRACE_FUNCTION("pb_sim_ext_records_used()");
2865
2866 ACI_MALLOC (data, SIM_MAX_RECORD_SIZE);
2867
2868 /* Get Extension file for the Phonebook type. */
2869 ext_file_id = pb_sim_get_ext_file(type);
2870
2871 /* Read record from the database. */
2872 if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
2873 RETURN (FALSE)
2874
2875 db_result = db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data);
2876 if (db_result < DB_OK)
2877 RETURN (FALSE) /* record can not be read - so no EXTn used */
2878
2879 /* Get extension record identifier */
2880 ext_rcd_num = data[info_field.record_size - 1];
2881
2882 TRACE_EVENT_P1("pb_sim_ext_records_used() --1-- ext_rcd_num = %d", ext_rcd_num);
2883
2884 if (ext_rcd_num NEQ 0xFF) /* check for extension records */
2885 {
2886 if(db_info_field (pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
2887 RETURN (FALSE)
2888
2889 if ((ext_rcd_num EQ 0) OR (ext_rcd_num > info_field.num_records))
2890 {
2891 TRACE_EVENT_P1 ("illegal ext record number %d ignored", ext_rcd_num);
2892 RETURN (FALSE)
2893 }
2894
2895 if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, data) < DB_OK)
2896 RETURN (FALSE)
2897
2898 ext_rcd_num = data[12];
2899 TRACE_EVENT_P1("pb_sim_ext_records_used() --2-- ext_rcd_num = %d", ext_rcd_num);
2900
2901 RETURN (TRUE) //return TRUE here since ext_rcd_num is valid
2902 }
2903 else
2904 {
2905 RETURN (FALSE)
2906 }
2907 cleanup_exit:
2908 ACI_MFREE (data);
2909 return retVal;
2910 }
2911 #undef RETURN
2912
2913 /*
2914 +--------------------------------------------------------------------+
2915 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2916 | STATE : code ROUTINE : pb_sim_retrieve_rdm_recno |
2917 +--------------------------------------------------------------------+
2918
2919 PURPOSE : Retrieving record number for LDN, LMN and LRN Phonebook.
2920
2921 */
2922
2923 LOCAL USHORT pb_sim_retrieve_rdm_recno (T_PHB_TYPE type)
2924 {
2925 USHORT rec_no;
2926
2927 TRACE_FUNCTION("pb_sim_retrieve_rdm_recno()");
2928
2929 switch(type)
2930 {
2931 case LDN:
2932 rec_no = LDN_DATA_RECNO;
2933 break;
2934
2935 case LMN:
2936 rec_no = LMN_DATA_RECNO;
2937 break;
2938
2939 case LRN:
2940 rec_no = LRN_DATA_RECNO;
2941 break;
2942
2943 default:
2944 rec_no = 0;
2945 break;
2946 }
2947
2948 return rec_no;
2949 }
2950
2951 /*
2952 +--------------------------------------------------------------------+
2953 | PROJECT : MMI-Framework (8417) MODULE : PHB |
2954 | STATE : code ROUTINE : pb_sim_cmpWild |
2955 +--------------------------------------------------------------------+
2956
2957 PURPOSE : compare two strings considering wildcard.
2958 if s1 < s2 return value < 0
2959 if s1 = s2 return value = 0
2960 if s1 > s2 return value > 0
2961 */
2962
2963 GLOBAL int pb_sim_cmpWild ( const char *s1, const char *s2, size_t cmp_len )
2964 {
2965 TRACE_FUNCTION("pb_sim_cmpWild()");
2966
2967 if (cmp_len EQ 0)
2968 return 0; /* Nothing to compare */
2969
2970 while ((*s1 EQ *s2) OR (*s1 EQ PHB_WILD_CRD) OR (*s2 EQ PHB_WILD_CRD))
2971 {
2972 /* Character matches */
2973 cmp_len--;
2974
2975 if (cmp_len EQ 0)
2976 return 0;
2977
2978 if ((*s1 EQ '\0') AND (*s2 EQ '\0'))
2979 return 0;
2980
2981 if (*s2 EQ '\0') /* Means *s1 > '\0' */
2982 return 1;
2983
2984 if (*s1 EQ '\0') /* Means *s2 > '\0' */
2985 return -1;
2986
2987 s1++;
2988 s2++;
2989 }
2990 /* Character does not match */
2991 if (*s1 > *s2)
2992 return 1;
2993 else
2994 return -1;
2995
2996 }
2997
2998
2999 /* Implements Measure #30 */
3000 /*
3001 +------------------------------------------------------------------------+
3002 | PROJECT: MMI-Framework (8417) MODULE: PHB |
3003 | STATE : code ROUTINE: pb_sim_read_alpha_num_record |
3004 +------------------------------------------------------------------------+
3005
3006 PURPOSE : Read a given physical record from the flash based phonebook
3007 in alphabetical order Or in number sorted order
3008 */
3009
3010 GLOBAL T_PHB_RETURN pb_sim_read_alpha_num_record (T_PHB_TYPE type,
3011 USHORT order_num,
3012 T_PHB_RECORD *entry,
3013 UBYTE sort_index)
3014 {
3015 int db_result;
3016 USHORT field_id;
3017
3018 TRACE_FUNCTION("pb_sim_read_alpha_num_record()");
3019
3020 /* Get Elementary file ID for the Phonebook type. */
3021 field_id = pb_sim_get_field_id(type);
3022
3023 /* Read record from the FFS. */
3024 db_result = db_get_phy_from_idx(pbs_data.db_handle, field_id,
3025 sort_index, order_num);
3026
3027 if(db_result > DB_OK)
3028 {
3029 return pb_sim_read_record(type, (USHORT)db_result, entry) ;
3030 }
3031
3032 /* Check whether index is vaild. */
3033 if(db_result EQ DB_INVALID_INDEX)
3034 {
3035 return PHB_INVALID_IDX;
3036 }
3037
3038 /*
3039 * Unable to get record from the database.
3040 * Hence returning PHB_FAIL.
3041 */
3042 return PHB_FAIL;
3043 }
3044
3045 /* Implements Measure #167 */
3046 /*
3047 +------------------------------------------------------------------------+
3048 | PROJECT: MMI-Framework (8417) MODULE: PHB |
3049 | STATE : code ROUTINE: pb_sim_read_alpha_num_record |
3050 +------------------------------------------------------------------------+
3051
3052 PURPOSE : Function check for extention records
3053 */
3054 LOCAL T_PHB_RETURN pb_sim_update_index (T_PHB_TYPE type,
3055 T_DB_CHANGED *rec_affected,
3056 USHORT field_id,
3057 UBYTE ext_rec_cnt)
3058 {
3059 TRACE_FUNCTION("pb_sim_update_index()");
3060
3061 if((type NEQ LDN) AND (type NEQ LMN) AND (type NEQ LRN))
3062 {
3063 /* Update the sorted indexes. */
3064 if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX,
3065 pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
3066 {
3067 return PHB_FAIL;
3068 }
3069
3070 if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX,
3071 pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
3072 {
3073 return PHB_FAIL;
3074 }
3075 }
3076 return PHB_OK;
3077 }
3078
3079 void pb_update_cphs_mb_ext_record(void)
3080 {
3081 UBYTE i;
3082 USHORT ext_file_id;
3083
3084 /* Get Extension file for the Phonebook type. */
3085 ext_file_id = SIM_EXT1;
3086
3087 for(i =0; i< 4; i++)
3088 {
3089 if(cphs_mb_ext_record_num[i] NEQ 0xff)
3090 {
3091 db_update_ext_bitmap(pbs_data.db_handle,ext_file_id,cphs_mb_ext_record_num[i],TRUE);
3092 pb_sim_update_extn_records(ext_file_id, cphs_mb_ext_record_num[i], 1);
3093 }
3094 }
3095 }
3096 GLOBAL void pb_sim_update_ext_bitmap(UBYTE rec_num, BOOL flag)
3097 {
3098 USHORT ext_file_id;
3099
3100 /* Get Extension file for the Phonebook type. */
3101 ext_file_id = SIM_EXT1;
3102
3103 db_update_ext_bitmap(pbs_data.db_handle,ext_file_id,rec_num, flag);
3104 if(flag EQ TRUE)
3105 {
3106 pb_sim_update_extn_records(ext_file_id, rec_num, 1);
3107 }
3108 else
3109 {
3110 pb_sim_update_extn_records(ext_file_id, rec_num, -1);
3111 }
3112 }
3113
3114
3115 #endif /* #ifdef TI_PS_FFS_PHB */
3116
3117