comparison src/aci2/aci/phb_sim.c @ 3:93999a60b835

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