FreeCalypso > hg > fc-magnetite
comparison src/g23m-aci/aci/phb_sim.c @ 162:53929b40109c
src/g23m-aci: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2016 02:02:43 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
161:4557e2a9c18e | 162:53929b40109c |
---|---|
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 |