line source
+ − /*
+ − +-----------------------------------------------------------------------------
+ − | Project : MMI-Framework (8417)
+ − | Modul : PHB
+ − +-----------------------------------------------------------------------------
+ − | Copyright 2002 Texas Instruments Berlin, AG
+ − | All rights reserved.
+ − |
+ − | This file is confidential and a trade secret of Texas
+ − | Instruments Berlin, AG
+ − | The receipt of or possession of this file does not convey
+ − | any rights to reproduce or disclose its contents or to
+ − | manufacture, use, or sell anything it may describe, in
+ − | whole, or in part, without the specific written consent of
+ − | Texas Instruments Berlin, AG.
+ − +-----------------------------------------------------------------------------
+ − | Purpose : This modul contains the functions to establish the phone book.
+ − +-----------------------------------------------------------------------------
+ − */
+ − #ifdef TI_PS_FFS_PHB
+ −
+ − #include "aci_all.h"
+ − #include "aci_cmh.h"
+ − #include "aci_mem.h"
+ −
+ − #include "phb_sim.h"
+ − #include "phb_aci.h"
+ −
+ − #include "ffs/ffs.h"
+ −
+ − #ifdef SIM_TOOLKIT
+ − #include "psa.h"
+ − #include "psa_sim.h"
+ − #include "psa_cc.h"
+ − #include "psa_sat.h"
+ − #endif /* #ifdef SIM_TOOLKIT */
+ −
+ − #include "cmh.h"
+ − #include "cmh_phb.h"
+ − #include "pcm.h"
+ −
+ − /*
+ − * Constants and enumerations
+ − */
+ −
+ − #define MAX_ECC_RCD 5
+ − #define FFS_IMSI_SIZE 8
+ − #define MAX_EXTNS_PER_RECORD 9
+ − #define MAX_ELEM_FILES 15
+ − #define SIM_MAX_RECORD_SIZE 256 /* Maximum size of a SIM record */
+ − #define RDM_DATA_FILE_ID 0xff04 /* File ID to store data related to LDN, LMN and LRN Phonebooks */
+ − #define SIZE_DATA_DATE_TIME 12
+ − #define MAX_EXT_RECORDS 10
+ − #define PHB_PHY_NUM_LENGTH 10
+ −
+ −
+ − /*
+ − * Type definitions
+ − */
+ −
+ − typedef struct
+ − {
+ − /* Handle for the Database */
+ − int db_handle;
+ −
+ − /* Maximum number of records */
+ − UBYTE max_record[MAX_PHONEBOOK];
+ −
+ − /* Number of used records */
+ − UBYTE used_record[MAX_PHONEBOOK];
+ −
+ − /* Records sizes */
+ − USHORT record_size[MAX_PHONEBOOK];
+ −
+ − } T_PHB_SIM_DATA;
+ −
+ − /* Maximum no of records for LRN, LDN and LMN Phonebooks. */
+ − #define RDM_PHB_DATA_SIZE 10
+ −
+ − /* Record numbers for LDN, LMN and LRN Phonebook data. */
+ − #define LDN_DATA_RECNO 1
+ − #define LMN_DATA_RECNO 2
+ − #define LRN_DATA_RECNO 3
+ −
+ − EXTERN UBYTE cphs_mb_ext_record_num[];
+ − /* ECC records */
+ − T_PHB_ECC_RECORD phb_ecc_element[MAX_ECC_RCD];
+ −
+ − LOCAL T_PHB_SIM_DATA pbs_data;
+ −
+ − /* Array to hold Reference count for Extension records. */
+ − LOCAL UBYTE ext_ref_count[MAX_PHB_EXT][MAX_EXT_RECORDS];
+ −
+ − /* Prototypes for search and compare functions */
+ − int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
+ − int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
+ − int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags);
+ − int pb_sim_number_cmp (int db_handle, USHORT field_id,USHORT recno_1,USHORT recno_2, ULONG flags);
+ − /*
+ − * Prototypes for local functions
+ − */
+ −
+ − LOCAL BOOL pb_sim_record_empty (USHORT field_id,
+ − USHORT entry_size, const UBYTE *buffer);
+ − LOCAL void pb_sim_read_eeprom_ecc (void);
+ − LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count);
+ − LOCAL void pb_sim_revString(char *);
+ − LOCAL void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry);
+ − LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr);
+ − LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type);
+ − LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type);
+ − LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id);
+ − LOCAL T_EXT_TYPE pb_sim_get_ext_type (USHORT field_id);
+ − LOCAL USHORT pb_sim_get_size_except_tag (USHORT field_id);
+ −
+ − LOCAL int pb_sim_cmpString ( UBYTE* cur_tag, UBYTE* check_tag, UBYTE cmpLen );
+ − LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE* entry_tag, UBYTE* cur_tag, UBYTE len );
+ − LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag);
+ − LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id, USHORT rec_num, SHORT ref_type);
+ − LOCAL T_PHB_RETURN pb_sim_del_ext_records(T_PHB_TYPE type, USHORT field_id, USHORT db_recno);
+ − LOCAL USHORT pb_sim_retrieve_rdm_recno (T_PHB_TYPE type);
+ − LOCAL T_PHB_RETURN pb_sim_del_record_internal (T_PHB_TYPE type,
+ − USHORT phy_recno,
+ − T_DB_CHANGED *rec_affected,
+ − BOOL replacement);
+ − LOCAL BOOL pb_sim_ext_records_used (T_PHB_TYPE type,
+ − USHORT field_id,
+ − USHORT db_recno);
+ −
+ −
+ − LOCAL T_PHB_RETURN pb_sim_update_index (T_PHB_TYPE type,
+ − T_DB_CHANGED *rec_affected,
+ − USHORT field_id,
+ − UBYTE ext_rec_cnt);
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework MODULE : PHB |
+ − | STATE : code ROUTINE: pb_sim_init |
+ − +----------------------------------------------------------------------+
+ −
+ − PURPOSE : Initializes internal data structures for SIM Phonebook.
+ − */
+ −
+ − void pb_sim_init (void)
+ − {
+ − USHORT i;
+ −
+ − TRACE_FUNCTION ("pb_sim_init()");
+ − db_init();
+ −
+ − /* Initialise the data structures. */
+ −
+ − /* Initialise ECC Phonebook to contain no records. */
+ − for(i = 0; i < MAX_ECC_RCD; i++)
+ − {
+ − phb_ecc_element[i].phy_idx = 0;
+ − memset(phb_ecc_element[i].number,0xFF,ECC_NUM_LEN);
+ − }
+ −
+ − return;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework MODULE : PHB |
+ − | STATE : code ROUTINE: pb_sim_exit |
+ − +----------------------------------------------------------------------+
+ −
+ − PURPOSE : This function is called by pb_exit() to inform the SIM part
+ − of the phonebook to shut down.
+ − */
+ − void pb_sim_exit (void)
+ − {
+ − TRACE_FUNCTION ("pb_sim_exit()");
+ −
+ − db_exit();
+ −
+ − return;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework MODULE : PHB |
+ − | STATE : code ROUTINE: pb_sim_record_empty |
+ − +----------------------------------------------------------------------+
+ −
+ − PURPOSE : This function is used to determine if a record is
+ − considered as empty.
+ − */
+ − LOCAL BOOL pb_sim_record_empty (USHORT field_id,
+ − USHORT entry_size, const UBYTE *data)
+ − {
+ − USHORT alpha_len;
+ −
+ − /* TRACE_FUNCTION ("pb_sim_record_empty()"); */ /* Trace load */
+ −
+ − /* If the entry contains an alpha identifier it is not empty */
+ − if (data[0] NEQ 0xFF)
+ − return FALSE;
+ −
+ − alpha_len = entry_size - pb_sim_get_size_except_tag (field_id);
+ −
+ − //TISH for MMISIM sometime entry_size = 0, then alpha_len < 0;
+ − #ifdef WIN32
+ − if (entry_size == 0)
+ − {
+ − return TRUE;
+ − }
+ − #endif
+ − if ((data[alpha_len] NEQ 0x00) AND (data[alpha_len + 2] NEQ 0xff))
+ − return FALSE;
+ − return TRUE; /* No alpha identifier and no phone number => record empty */
+ − }
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework MODULE : PHB |
+ − | STATE : code ROUTINE: pb_sim_set_ecc |
+ − +----------------------------------------------------------------------+
+ −
+ − PURPOSE : The emergency call numbers are read from SIM card and
+ − written to FFS.
+ − */
+ − T_PHB_RETURN pb_sim_set_ecc (UBYTE ecc_len, const UBYTE *sim_ecc)
+ − {
+ − USHORT ecc_rec_num;
+ − UBYTE *data_ptr;
+ −
+ − TRACE_FUNCTION ("pb_sim_set_ecc()");
+ −
+ − /* Initialise used records for ECC. */
+ − pbs_data.used_record[ECC] = 0;
+ −
+ − /* if SIM ECC data is not empty, copy SIM ECC data to phonebook */
+ − if ( ecc_len NEQ 0)
+ − {
+ − data_ptr = ( UBYTE *) sim_ecc;
+ − pbs_data.max_record[ECC] = (SHORT)((ecc_len/ECC_NUM_LEN) > MAX_ECC_RCD)? MAX_ECC_RCD: ecc_len/ECC_NUM_LEN;
+ − pbs_data.record_size[ECC] = ECC_NUM_LEN;
+ −
+ − /* Store ECC into RAM, since ECC records will be less in number. */
+ − /*
+ − * For the Issue OMAPS00081622
+ − * Replaced MAX_ECC_RCD with pbs_data.max_record[ECC] in the for loop
+ − */
+ − for (ecc_rec_num = 0; ecc_rec_num < pbs_data.max_record[ECC]; ecc_rec_num++)
+ − {
+ − if(*data_ptr NEQ 0xff)
+ − {
+ − memset(&phb_ecc_element[ecc_rec_num],0xFF,sizeof(T_PHB_ECC_RECORD));
+ − phb_ecc_element[ecc_rec_num].phy_idx = ecc_rec_num + 1;
+ − memcpy(phb_ecc_element[ecc_rec_num].number, data_ptr, ECC_NUM_LEN);
+ − data_ptr += ECC_NUM_LEN;
+ − (pbs_data.used_record[ECC])++;
+ − }
+ − }
+ − }
+ − else
+ − {
+ − pb_sim_read_eeprom_ecc();
+ − }
+ −
+ − return PHB_OK;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_create_ef |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Creates a SIM elementary file.
+ −
+ − */
+ − T_PHB_RETURN pb_sim_create_ef (USHORT ef, USHORT record_size, USHORT records)
+ − {
+ − T_DB_INFO_FIELD field_info;
+ − T_DB_TYPE db_type;
+ − int db_result;
+ −
+ − TRACE_FUNCTION ("pb_sim_create_ef()");
+ −
+ − TRACE_EVENT_P1("Elementary file ID = %x",ef);
+ − db_result = db_info_field(pbs_data.db_handle, ef, &field_info);
+ −
+ − /* Check whether file already exists. */
+ − if(db_result EQ DB_OK)
+ − {
+ − /* Check for Record size and No. of records in the present field. */
+ − if((field_info.record_size EQ record_size) AND (field_info.num_records EQ records))
+ − return PHB_OK; /* Preserve the existing field. */
+ − else
+ − {
+ − if(pb_sim_remove_ef(ef) EQ PHB_FAIL) /* Remove the existing file and recreate the field. */
+ − return PHB_FAIL;
+ − }
+ − }
+ −
+ − /* Set DB_TYPE depending on the Elementary file. */
+ − switch(ef)
+ − {
+ − case SIM_ADN:
+ − case SIM_FDN:
+ − case SIM_BDN:
+ − case SIM_SDN:
+ − case SIM_EXT1:
+ − case SIM_EXT2:
+ − case SIM_EXT3:
+ − case SIM_EXT4:
+ − case SIM_LND:
+ − case SIM_OCI:
+ − //case SIM_ICI:
+ − case FFS_LRN:
+ − case FFS_LMN:
+ − case FFS_EXT_LRN:
+ − case FFS_EXT_LMN:
+ − case SIM_EXT5:
+ − db_type = DB_FREELIST;
+ − break;
+ −
+ − case SIM_MSISDN:
+ − case SIM_IMSI:
+ − db_type = DB_UNMANAGED;
+ − break;
+ −
+ − default:
+ − TRACE_ERROR("Invalid ef passed to pb_sim_create_ef()");
+ − return PHB_FAIL;
+ − }
+ −
+ − db_result = db_create_field(pbs_data.db_handle, db_type, ef, record_size, records);
+ −
+ − if(db_result EQ DB_OK)
+ − return PHB_OK;
+ −
+ − /* Return PHB_FAIL since DB has failed to create File. */
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_write_ef |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Writes entry_size bytes content of buffer at index to the elementary file ef.
+ −
+ − */
+ − T_PHB_RETURN pb_sim_write_ef (USHORT ef, USHORT phy_recno,
+ − USHORT entry_size, const UBYTE *buffer,
+ − BOOL *changed, USHORT *ext_record_ef, UBYTE *ext_record_no)
+ − {
+ − int i;
+ − T_DB_CHANGED records_affected;
+ −
+ − TRACE_FUNCTION ("pb_sim_write_ef()");
+ −
+ − /* Initialise changed to FALSE. */
+ − *changed = FALSE;
+ −
+ − /* Default is no extension record */
+ − *ext_record_ef = 0;
+ − *ext_record_no = 0;
+ −
+ − /* Check for extension records. */
+ − if (!pb_sim_record_empty(ef, entry_size, buffer))
+ − {
+ − /* The record is not empty (deleted) */
+ − switch (ef)
+ − {
+ − case SIM_ADN:
+ − case SIM_MSISDN:
+ − case SIM_LND:
+ − *ext_record_ef = SIM_EXT1;
+ − *ext_record_no = buffer[entry_size - 1];
+ − break;
+ −
+ − case SIM_FDN:
+ − *ext_record_ef = SIM_EXT2;
+ − *ext_record_no = buffer[entry_size - 1];
+ − break;
+ −
+ − case SIM_SDN:
+ − *ext_record_ef = SIM_EXT3;
+ − *ext_record_no = buffer[entry_size - 1];
+ − break;
+ −
+ − case SIM_BDN:
+ − *ext_record_ef = SIM_EXT4;
+ − *ext_record_no = buffer[entry_size - 1];
+ − break;
+ −
+ − case FFS_LRN:
+ − case FFS_LMN:
+ − case SIM_OCI: /* Release 1999 and above 31.102 clause 4.2.34 */
+ − *ext_record_ef = SIM_EXT5;
+ − *ext_record_no = buffer[entry_size - 15]; // Jirli, please check, 14 instead of 15?
+ − break;
+ −
+ − case SIM_EXT1: /* Extension records can reference other extension records */
+ − case SIM_EXT2:
+ − case SIM_EXT3:
+ − case SIM_EXT4:
+ − case SIM_EXT5:
+ − case FFS_EXT_LRN:
+ − case FFS_EXT_LMN:
+ − //TISH, patch for OMAPS00124850
+ − #if 0
+ − *ext_record_ef = ef;
+ − *ext_record_no = buffer[entry_size - 1];
+ − #else
+ − if (buffer[entry_size - 1] EQ 255 OR buffer[entry_size-1] EQ (UBYTE)phy_recno)
+ − {
+ − *ext_record_ef =0;
+ − *ext_record_no=0;
+ − }
+ − else
+ − {
+ − *ext_record_ef = ef;
+ − *ext_record_no = buffer[entry_size - 1];
+ − }
+ − #endif
+ − //end
+ − break;
+ −
+ − default: /* No extension record defined for this field */
+ − break;
+ − }
+ −
+ − /* Record is not referring any extensions. So set ef and record_no to ZERO. */
+ − if (*ext_record_no EQ 0xff)
+ − {
+ − *ext_record_ef = 0;
+ − *ext_record_no = 0;
+ − }
+ −
+ − /* Handle usage counter of extension records */
+ − pb_sim_update_extn_records (*ext_record_ef, *ext_record_no, 1);
+ −
+ − /* Write record into FFS */
+ − if(db_write_record(pbs_data.db_handle, ef, phy_recno, 0, entry_size, buffer) > DB_OK)
+ − {
+ − if(db_read_change_log(pbs_data.db_handle, &records_affected) EQ DB_OK)
+ − {
+ − for(i = 0; i < records_affected.entries; i++)
+ − {
+ − /* Checking whether Elementary file in the database is changed. */
+ − if((records_affected.field_id[i] EQ ef) AND (records_affected.record[i] EQ phy_recno))
+ − {
+ − *changed = TRUE;
+ − return PHB_OK;
+ − }
+ − }
+ −
+ − /* Write operation has not changed File in the database. So returning PHB_OK */
+ − return PHB_OK;
+ − }
+ − else /* Unable to read change log from DB. So returning PHB_FAIL. */
+ − return PHB_FAIL;
+ − }
+ − else /* Write failure in DB. So returning PHB_FAIL */
+ − return PHB_FAIL;
+ − }
+ − else
+ − {
+ − /* Empty record */
+ − if (db_delete_record (pbs_data.db_handle, ef, phy_recno) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(db_read_change_log (pbs_data.db_handle, &records_affected) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − *changed = (records_affected.entries NEQ 0);
+ − return PHB_OK;
+ − }
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_open |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Opens the SIM phonebook for the given SIM determined by the IMSI.
+ − */
+ − T_PHB_RETURN pb_sim_open (const T_imsi_field *imsi_field, BOOL *changed)
+ − {
+ − T_DB_INFO database_info;
+ − UBYTE ffsIMSI[MAX_IMSI_LEN+1];
+ − UBYTE simIMSI[MAX_IMSI_LEN+1];
+ − UBYTE imsi[FFS_IMSI_SIZE];
+ − int db_result,rec_num;
+ − UBYTE buffer[RDM_PHB_DATA_SIZE];
+ −
+ − TRACE_FUNCTION("pb_sim_open()");
+ −
+ − /* Initially set SIM changed as TRUE. */
+ − *changed = TRUE;
+ −
+ − /* Open the database. */
+ − db_result = db_open(FFS_PHB_DIR);
+ −
+ − TRACE_EVENT_P1("DB handle is %d",db_result);
+ −
+ − if(db_result >= DB_OK)
+ − {
+ − pbs_data.db_handle = db_result;
+ −
+ − /* Get database info. */
+ − db_result = db_info(pbs_data.db_handle, &database_info);
+ −
+ − /* Read IMSI from the FFS if Database is clean. */
+ − if((db_result EQ DB_OK) AND (database_info.clean EQ TRUE))
+ − {
+ − db_result = db_read_record(pbs_data.db_handle, SIM_IMSI, 1, 0, FFS_IMSI_SIZE, imsi);
+ −
+ − /* Compare IMSI read from FFS with IMSI got from SIM. */
+ − if(db_result > DB_OK)
+ − {
+ − psaSIM_decodeIMSI ((UBYTE*) imsi_field->field,(UBYTE)imsi_field->c_field, (char *)simIMSI);
+ −
+ − psaSIM_decodeIMSI (imsi, FFS_IMSI_SIZE, (char *)ffsIMSI);
+ −
+ − if (!strcmp((char *)simIMSI, (char *)ffsIMSI))
+ − {
+ − *changed = FALSE;
+ − return PHB_OK;
+ − }
+ − }
+ − else
+ − {
+ − /* Unable to read IMSI, regenerate database */
+ − *changed = TRUE;
+ − }
+ − }
+ −
+ − /* Remove database whenever database is Inconsistent and SIM is changed. */
+ − if(db_close(pbs_data.db_handle) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(db_remove(FFS_PHB_DIR) NEQ DB_OK)
+ − return PHB_FAIL;
+ − }/* if(db_result >= DB_OK) */
+ −
+ − /* Create database: For the first time, whenever SIM is changed
+ − and whenever database is Inconsistent. */
+ − db_result = db_create(FFS_PHB_DIR, MAX_ELEM_FILES, TRUE);
+ −
+ − TRACE_EVENT_P1("DB handle is %d",db_result);
+ −
+ − /* Creating DB is successful and valid db_handle is returned */
+ − if(db_result >= DB_OK)
+ − {
+ − if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, SIM_IMSI, imsi_field->c_field, 1) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(db_write_record(pbs_data.db_handle, SIM_IMSI, 1, 0, imsi_field->c_field, imsi_field->field) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Create Elementary file to store RDM Phonebook data */
+ − if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, RDM_DATA_FILE_ID,RDM_PHB_DATA_SIZE,3) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Initialise data for Recent call lists */
+ − for(rec_num = 1; rec_num <= 3; rec_num++)
+ − {
+ − memset(buffer,0x00, RDM_PHB_DATA_SIZE);
+ −
+ − if(db_write_record(pbs_data.db_handle, RDM_DATA_FILE_ID, rec_num, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
+ − return PHB_FAIL;
+ − }
+ −
+ − return PHB_OK;
+ − }
+ −
+ − /* Unable to create Database. So returning PHB_FAIL. */
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_ef |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reads *buffer from elementary file ef at index.
+ − */
+ − T_PHB_RETURN pb_sim_read_ef (USHORT ef, USHORT recno, USHORT *entry_size, UBYTE *buffer)
+ − {
+ − int db_result;
+ − T_DB_INFO_FIELD field_info;
+ −
+ − TRACE_FUNCTION("pb_sim_read_ef()");
+ −
+ − if(db_info_field(pbs_data.db_handle, ef, &field_info) EQ DB_OK)
+ − {
+ − *entry_size = field_info.record_size;
+ −
+ − db_result = db_read_record (pbs_data.db_handle,
+ − ef,
+ − recno,
+ − 0,
+ − field_info.record_size,
+ − buffer);
+ −
+ − if (db_result > DB_OK)
+ − return PHB_OK; /* Successfully read */
+ −
+ − if (db_result EQ DB_EMPTY_RECORD)
+ − {
+ − /* Return a deleted record content */
+ − memset (buffer, 0xff, *entry_size);
+ − return PHB_OK;
+ − }
+ − return PHB_FAIL; /* Some problem reading record */
+ − }
+ −
+ − /* Returning PHB_FAIL, since DB has failed to give Info about the field. */
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_remove_ef |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Removes elementary file.
+ − */
+ − T_PHB_RETURN pb_sim_remove_ef (USHORT ef)
+ − {
+ − T_EXT_TYPE ext_type;
+ − USHORT rec_num;
+ −
+ − TRACE_FUNCTION("pb_sim_remove_ef()");
+ −
+ − if(db_remove_field(pbs_data.db_handle, ef) EQ DB_OK)
+ −
+ − {
+ − /* Get EXT Type for elementary file */
+ − ext_type = pb_sim_get_ext_type(ef);
+ −
+ − /* Reset reference count for extension records */
+ − if(ext_type NEQ INVALID_EXT)
+ − {
+ − for(rec_num = 0; rec_num < MAX_EXT_RECORDS; rec_num++)
+ − {
+ − ext_ref_count[ext_type][rec_num] = 0;
+ − }
+ − }
+ − return PHB_OK;
+ − }
+ −
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_build_index |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Builds index for the given phonebook.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_build_index (T_PHB_TYPE type)
+ − {
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_build_index()");
+ −
+ − field_id = pb_sim_get_field_id(type);
+ −
+ − if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX, pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX, pb_sim_number_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − return PHB_OK;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_flush_data |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : This function informs the SIM phonebook that SIM reading has become finished and we reached a consistent state.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_flush_data (void)
+ − {
+ −
+ − TRACE_FUNCTION("pb_sim_flush_data()");
+ −
+ − if(db_flush(pbs_data.db_handle) EQ DB_OK)
+ − return PHB_OK;
+ −
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_add_record |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Add a given record at index to the given phonebook.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_add_record (T_PHB_TYPE type,
+ − USHORT phy_recno,
+ − const T_PHB_RECORD *entry,
+ − T_DB_CHANGED *rec_affected)
+ − {
+ − USHORT field_id, ext_file_id, rec_no;
+ − UBYTE tag_len, max_tag_len;
+ − UBYTE data[SIM_MAX_RECORD_SIZE];
+ − UBYTE buffer[RDM_PHB_DATA_SIZE];
+ − T_DB_INFO_FIELD info_field, ext_info_field;
+ − UBYTE ext_rec_cnt = 0;
+ − UBYTE ext_rec_num1, ext_rec_num2;
+ − BOOL record_empty;
+ − int db_result,i;
+ −
+ − TRACE_FUNCTION("pb_sim_add_record()");
+ −
+ − /* Handling of ECC Phonebook */
+ − if(type EQ ECC)
+ − {
+ − if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+ − {
+ − phb_ecc_element[phy_recno - 1].phy_idx = phy_recno;
+ − memcpy(phb_ecc_element[phy_recno - 1].number,entry->number, ECC_NUM_LEN);
+ −
+ − return PHB_OK;
+ − }
+ − else
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ − TRACE_EVENT_P1("pb_sim_get_field_id->Field_id: %x", field_id);
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = pb_sim_get_ext_file(type);
+ −
+ − TRACE_EVENT_P1("Ext_Field_id: %x", ext_file_id);
+ −
+ − db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
+ −
+ − /* Get record size to calculate alpha_len for the entry */
+ − if(db_result NEQ DB_OK)
+ − {
+ − TRACE_EVENT_P1("db_result = %d",db_result);
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Handling of LDN, LMN and LRN Phonebook records. */
+ − if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+ − {
+ − if(phy_recno NEQ 1)
+ − return PHB_FAIL;
+ −
+ − /* Find free record in the elementary file. */
+ − db_result = db_find_free_record( pbs_data.db_handle, field_id);
+ −
+ − /* Get record number for the type of Phonebook. */
+ − rec_no = pb_sim_retrieve_rdm_recno(type);
+ −
+ − /* Error handling. */
+ − if(rec_no EQ 0)
+ − return PHB_FAIL;
+ −
+ − /* Read data related to LDN, LMN and LRN Phonebook from FFS */
+ − if(db_read_record(pbs_data.db_handle,
+ − RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Database is unable to find the free record. So overwrite the oldest one. */
+ − if(db_result < 0)
+ − phy_recno = buffer[RDM_PHB_DATA_SIZE - 1];
+ − else
+ − phy_recno = db_result;
+ −
+ − if(info_field.used_records EQ RDM_PHB_DATA_SIZE)
+ − i = RDM_PHB_DATA_SIZE - 1;
+ − else
+ − i = info_field.used_records;
+ −
+ − /* Move the records as new record has to be added. */
+ − for(; i > 0; i--)
+ − {
+ − buffer[i] = buffer[i-1];
+ − }
+ −
+ − /* Update the record number of new entry. */
+ − buffer[0] = (UBYTE) phy_recno;
+ −
+ − /* Write back RDM data back into the database. */
+ − if(db_write_record(pbs_data.db_handle,
+ − RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Drop information about changed RDM records from the database. */
+ − (void)db_read_change_log(pbs_data.db_handle, rec_affected);
+ − rec_affected->entries = 0;
+ − }
+ −
+ − /* Convert T_PHB_TYPE into data structures as described in ETSI 11.11 */
+ − /* Bytes Description M/O Length |
+ − ----------------------------------------------------------------------
+ − 1 to X Alpha Identifier O X bytes
+ − X+1 Length of BCD number/SSC contents M 1 byte
+ − X+2 TON and NPI M 1 byte
+ − X+3 to X+12 Dialling Number/SSC String M 10 bytes
+ − X+13 Capability/Configuration Identifier M 1 byte
+ − X+14 Extension Record Identifier M 1 byte
+ − -------------------------------------------------------
+ − Extra fields for LDN, LMN, and LMN Phonebook records (As per 31.102)
+ − -------------------------------------------------------
+ − X+15 to X+21 Outgoing call date and time M 7 bytes
+ − X+22 to X+24 Outgoing call duration M 3 bytes
+ − X+26 Line of the call M 1 byte (New field added to
+ − store line of call)
+ − ----------------------------------------------------------------------*/
+ −
+ − tag_len = pb_sim_get_entry_len(entry->tag, PHB_MAX_TAG_LEN);
+ −
+ − max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+ −
+ − if(tag_len > max_tag_len)
+ − return PHB_TAG_EXCEEDED;
+ −
+ − memset(data, 0xFF, sizeof(data));
+ − memcpy(data, entry->tag, tag_len);
+ −
+ − if(entry->number[10] NEQ 0xFF)
+ − {
+ − data[max_tag_len] = 11; /* max. length */
+ − }
+ − else
+ − {
+ − data[max_tag_len] = entry->len + 1;
+ − }
+ −
+ − data[max_tag_len+1] = entry->ton_npi;
+ − memcpy((char *)&data[max_tag_len+2],
+ − (char *)entry->number, 10);
+ − data[max_tag_len+12] = entry->cc_id;
+ −
+ − /* Copy data specific to records of Phonebook Types (LRN, LDN and LMN). */
+ − if((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN))
+ − {
+ − if(entry->v_time)
+ − {
+ − data[max_tag_len+14] = entry->time.year;
+ − data[max_tag_len+15] = entry->time.month;
+ − data[max_tag_len+16] = entry->time.day;
+ − data[max_tag_len+17] = entry->time.hour;
+ − data[max_tag_len+18] = entry->time.minute;
+ − data[max_tag_len+19] = entry->time.second;
+ − data[max_tag_len+20] = entry->time.time_zone;
+ −
+ − data[max_tag_len+21] = (UBYTE)((entry->time.duration >> 16) & 0xff);
+ − data[max_tag_len+22] = (UBYTE)((entry->time.duration >> 8) & 0xff);
+ − data[max_tag_len+23] = (UBYTE)((entry->time.duration) & 0xff);
+ −
+ − }
+ −
+ − if(entry->v_line)
+ − {
+ − data[max_tag_len+24] = entry->line;
+ − }
+ −
+ − }
+ −
+ − /* Check how many extension records are needed for number */
+ − if(entry->number[10] NEQ 0xFF)
+ − {
+ − ext_rec_cnt = entry ->len - 10;
+ −
+ − if(ext_rec_cnt % 10)
+ − ext_rec_cnt = (ext_rec_cnt / 10) + 1;
+ − else
+ − ext_rec_cnt = (ext_rec_cnt / 10);
+ − }
+ −
+ − /* Check how many extension records are needed for subaddress */
+ − if(entry->subaddr[0] NEQ 0xFF)
+ − {
+ − ext_rec_cnt++;
+ − }
+ −
+ − if(entry->subaddr[11] NEQ 0xFF)
+ − {
+ − ext_rec_cnt++;
+ − }
+ −
+ − TRACE_EVENT_P1("phy_recno = %d",phy_recno);
+ −
+ − TRACE_EVENT_P2("no_rec = %d, used_rec = %d",info_field.num_records,info_field.used_records);
+ −
+ − /* If record number is not mentioned, search for the free record and add the entry. */
+ − if(phy_recno EQ 0)
+ − {
+ − db_result = db_find_free_record( pbs_data.db_handle, field_id);
+ −
+ − /* Database is unable to find the free record. So returning PHB_FULL. */
+ − if(db_result EQ DB_RECORD_NOT_FOUND)
+ − return PHB_FULL;
+ −
+ − if(db_result < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Database has returned the free record number. */
+ − phy_recno = db_result;
+ − }
+ − else
+ − {
+ − /*
+ − * Delete the record, if present to get rid of associated
+ − * ext records. This has the effect that when we afterwards are unable to
+ − * create the new record (e.g. lack of extension records) the original
+ − * record remains deleted. Probably this is not a problem, at least it
+ − * should not be a big one.
+ − */
+ − db_result = db_record_empty (pbs_data.db_handle,
+ − field_id, phy_recno, &record_empty);
+ − if ((db_result EQ DB_OK) AND !record_empty)
+ − {
+ − /*
+ − * In case ext_rec is needed and the existing record is not using EXT,
+ − * check if there is ext_rec available before deleting the existing entry
+ − * ext_info_field is used to get this info
+ − */
+ − if (ext_rec_cnt NEQ 0 AND !pb_sim_ext_records_used(type, field_id,phy_recno))
+ − {
+ − db_result = db_info_field(pbs_data.db_handle, ext_file_id, &ext_info_field);
+ − 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);
+ −
+ − if((ext_info_field.num_records - ext_info_field.used_records) < ext_rec_cnt)
+ − return PHB_EXT_FULL;
+ − }
+ −
+ − (void)pb_sim_del_record_internal (type, phy_recno, rec_affected, TRUE);
+ − }
+ − }
+ −
+ − /* Write record if entry does not require extension records */
+ − if(ext_rec_cnt EQ 0)
+ − {
+ − /* Write record into FFS */
+ − if(db_write_record(pbs_data.db_handle, field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* For LDN record also write to SIM_LDN (without date and time Details */
+ − if(type EQ LDN)
+ − {
+ − memset(&data[max_tag_len + pb_sim_get_size_except_tag(field_id)], 0xFF,
+ − SIZE_DATA_DATE_TIME);
+ −
+ − /* if(db_info_field(pbs_data.db_handle, SIM_LND, &info_field) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(db_write_record(pbs_data.db_handle, SIM_LND, phy_recno, 0, info_field.record_size, data) < DB_OK)
+ − return PHB_FAIL;*/
+ − }
+ −
+ − }
+ − else /* We need to find free extension record. */
+ − {
+ − TRACE_EVENT_P1("Extension records = %d",ext_rec_cnt);
+ − /* Search for free extension records */
+ −
+ − /* Check whether extension file has required no. of free records. */
+ − db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
+ −
+ − if((info_field.num_records - info_field.used_records) < ext_rec_cnt)
+ − {
+ − return PHB_EXT_FULL;
+ − }
+ −
+ − /* Required no. of free extension records are found */
+ − db_result = db_find_free_record( pbs_data.db_handle,ext_file_id);
+ −
+ − /* DB has returned non-zero positive number.
+ − (Valid record number which is free). */
+ −
+ − if(db_result EQ DB_RECORD_NOT_FOUND)
+ − {
+ − return PHB_EXT_FULL;
+ − }
+ −
+ − if(db_result > DB_OK)
+ − { /* Set Extension record Identifier */
+ − ext_rec_num1 = db_result;
+ −
+ − data[max_tag_len+13] = ext_rec_num1;
+ −
+ − db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
+ −
+ − /* Write record into FFS */
+ − if(db_write_record(pbs_data.db_handle,
+ − field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − }
+ − else
+ − return PHB_FAIL;
+ −
+ − db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
+ −
+ − /* Prepare extension data and write into Extension file after finding the free records. */
+ − for(i = 0; i < ext_rec_cnt; i++)
+ − {
+ − //TISH, patch for ASTec34494, added by Jinshu Wang, 2007-08-09
+ − //start
+ − memset(data,0xff,SIM_MAX_RECORD_SIZE);
+ − //end
+ −
+ − pb_sim_prepare_ext_data(data, i, (UBYTE*)entry->number, entry->len, (UBYTE*)entry->subaddr);
+ −
+ − /* Find next free record to chain the extension records. */
+ − db_result = db_find_free_record( pbs_data.db_handle,ext_file_id);
+ −
+ − if(db_result EQ DB_RECORD_NOT_FOUND)
+ − {
+ − return PHB_EXT_FULL;
+ − }
+ −
+ − if(db_result > DB_OK)
+ − {
+ − ext_rec_num2 = db_result;
+ − }
+ − else
+ − {
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Chain extension records and set last link to "FF" */
+ − if(i NEQ (ext_rec_cnt - 1))
+ − data[12] = ext_rec_num2;
+ −
+ − /* Write extension record into FFS */
+ − if(db_write_record(pbs_data.db_handle, ext_file_id, ext_rec_num1, 0, info_field.record_size, data) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − if(pb_sim_update_extn_records(ext_file_id, ext_rec_num1, 1) EQ PHB_FAIL)
+ − return PHB_FAIL;
+ −
+ − /* Preserve the previous free record number. */
+ − ext_rec_num1 = ext_rec_num2;
+ − }
+ −
+ − }
+ −
+ − /* Get information about changed records from the database. */
+ − if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Implements Measure #167 */
+ − return pb_sim_update_index ( type, rec_affected,field_id, ext_rec_cnt);
+ −
+ − }
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_del_record_internal |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Delete a given record at phy_recno from the given phonebook.
+ − If this function is called internally by a replacement operation
+ − on the phonebook this is indicated by the replacement parameter,
+ − in this case neither the change log are read nor the ring buffer
+ − management is touched in case of circular phonebooks.
+ − */
+ − LOCAL T_PHB_RETURN pb_sim_del_record_internal (T_PHB_TYPE type,
+ − USHORT phy_recno,
+ − T_DB_CHANGED *rec_affected,
+ − BOOL replacement)
+ − {
+ − USHORT field_id, db_recno, rec_no;
+ − UBYTE buffer[RDM_PHB_DATA_SIZE], rec_cnt;
+ −
+ − TRACE_FUNCTION("pb_sim_del_record_internal()");
+ −
+ − /* Handling of ECC Phonebook */
+ − if(type EQ ECC)
+ − {
+ − if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+ − {
+ − phb_ecc_element[phy_recno - 1].phy_idx = 0;
+ − memset(phb_ecc_element[phy_recno - 1].number, 0xFF, ECC_NUM_LEN);
+ −
+ − return PHB_OK;
+ − }
+ − else
+ − return PHB_FAIL;
+ − }
+ −
+ − TRACE_EVENT_P1("phy_recno = %d", phy_recno);
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ − /* Handling of LDN, LMN and LRN Phonebook records. */
+ − if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+ − {
+ − /* Get record number for the type of Phonebook. */
+ − rec_no = pb_sim_retrieve_rdm_recno(type);
+ −
+ − /* Error handling. */
+ − if(rec_no EQ 0)
+ − return PHB_FAIL;
+ −
+ − /* Read data related to LDN, LMN and LRN Phonebook from FFS */
+ − if(db_read_record(pbs_data.db_handle,
+ − RDM_DATA_FILE_ID,rec_no, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Retrieve record number in Database from the buffer. */
+ − if((buffer[phy_recno - 1] EQ 0) OR (buffer[phy_recno - 1] > RDM_PHB_DATA_SIZE))
+ − return PHB_FAIL;
+ −
+ − db_recno = buffer[phy_recno - 1];
+ −
+ − if (!replacement)
+ − {
+ − /* Move the records */
+ − for(rec_cnt = phy_recno -1; rec_cnt < RDM_PHB_DATA_SIZE - 1; rec_cnt ++)
+ − {
+ − buffer[rec_cnt] = buffer[rec_cnt + 1];
+ − }
+ −
+ − /* Update the deleted entry record number. */
+ − buffer[RDM_PHB_DATA_SIZE - 1] = 0;
+ −
+ − /* Write back RDM data back into the database. */
+ − if(db_write_record(pbs_data.db_handle,
+ − RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Drop information about changed RDM records from the database. */
+ − (void)db_read_change_log(pbs_data.db_handle, rec_affected);
+ − rec_affected->entries = 0;
+ − }
+ − }
+ − else
+ − {
+ − db_recno = phy_recno;
+ − }
+ −
+ − /* Delete extension records if not referenced. */
+ − (void)pb_sim_del_ext_records(type, field_id, db_recno);
+ −
+ − /* Delete record from FFS. */
+ − if(db_delete_record(pbs_data.db_handle, field_id,db_recno) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − /* Get final information about changed records from the database. */
+ − if (!replacement)
+ − {
+ − if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Implements Measure #167 */
+ − return pb_sim_update_index ( type, rec_affected,field_id, 0);
+ −
+ − }
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_del_record |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Delete a given record at phy_recno from the given phonebook.
+ − This function reads the change log.
+ −
+ − */
+ − T_PHB_RETURN pb_sim_del_record (T_PHB_TYPE type,
+ − USHORT phy_recno,
+ − T_DB_CHANGED *rec_affected)
+ − {
+ − TRACE_FUNCTION ("pb_sim_del_record()");
+ − return (pb_sim_del_record_internal (type, phy_recno, rec_affected, FALSE));
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_record |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Read a given physical record from the flash based phonebook.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_read_record (T_PHB_TYPE type, USHORT phy_recno, T_PHB_RECORD *entry)
+ − {
+ − USHORT field_id, ext_file_id, rec_no;
+ − USHORT db_recno;
+ − T_DB_INFO_FIELD info_field;
+ − UBYTE buffer[RDM_PHB_DATA_SIZE];
+ − UBYTE *data=NULL, *ptr;
+ − UBYTE max_tag_len;
+ − UBYTE ext_rcd_num;
+ −
+ −
+ − TRACE_FUNCTION("pb_sim_read_record()");
+ −
+ − /* Handling of ECC Phonebook */
+ − if(type EQ ECC)
+ − {
+ − if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+ − {
+ − memset(entry,0xFF,sizeof(T_PHB_RECORD));
+ − /* Return PHB_FAIL whenever ECC entry is empty */
+ − if((phb_ecc_element[phy_recno - 1].number[0] & 0x0F)
+ − EQ 0x0F)
+ − {
+ − return PHB_FAIL;
+ − }
+ − else
+ − {
+ − entry->phy_recno = phy_recno;
+ − entry->len = ECC_NUM_LEN;
+ − memcpy(entry->number, phb_ecc_element[phy_recno - 1].number, ECC_NUM_LEN);
+ − return PHB_OK;
+ − }
+ − }
+ − else
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = pb_sim_get_ext_file(type);
+ −
+ − /* Read record from the database. */
+ − if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+ − return PHB_FAIL;
+ −
+ − if((phy_recno EQ 0 ) OR (phy_recno > info_field.num_records))
+ − return PHB_FAIL;
+ −
+ − /* Handling of LDN, LMN and LRN Phonebook records. */
+ − if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+ − {
+ − /* Get record number for the type of Phonebook. */
+ − rec_no = pb_sim_retrieve_rdm_recno(type);
+ −
+ − /* Error handling. */
+ − if(rec_no EQ 0)
+ − return PHB_FAIL;
+ −
+ − /* Read data related to LDN,LMN and LRN Phonebook from FFS */
+ − if(db_read_record(pbs_data.db_handle,
+ − RDM_DATA_FILE_ID, rec_no, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
+ − return PHB_FAIL;
+ −
+ − db_recno = buffer[phy_recno - 1];
+ − }
+ − else
+ − db_recno = phy_recno;
+ −
+ − ACI_MALLOC(data,SIM_MAX_RECORD_SIZE);
+ −
+ − if(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+ − {
+ − ACI_MFREE(data);
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Convert SIM data to the type T_PHB_RECORD. */
+ − ptr = data;
+ − max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+ − if (max_tag_len > PHB_MAX_TAG_LEN)
+ − max_tag_len = PHB_MAX_TAG_LEN;
+ −
+ − entry->phy_recno = phy_recno;
+ − entry->tag_len = (UBYTE)pb_sim_get_entry_len(ptr, max_tag_len);
+ −
+ − memset(entry->tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+ − memcpy ( (char*)entry->tag, (char*)ptr, entry->tag_len );
+ −
+ − ptr += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+ −
+ − max_tag_len = (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+ −
+ − entry->len = *ptr - 1;
+ − ++ptr;
+ − entry->ton_npi = *ptr;
+ − ++ptr;
+ −
+ − /*
+ − * This error handling is done to avoid the accidental incorrect
+ − * record length stored in the test SIMs
+ − */
+ − if (entry->len > PHB_PACKED_NUM_LEN)
+ − {
+ − entry->len = PHB_PACKED_NUM_LEN;
+ − }
+ −
+ − memset(entry->number, 0xFF, PHB_PACKED_NUM_LEN);
+ − memcpy( (char*)entry->number, (char*)ptr, entry->len );
+ − ptr += 10;
+ − entry->cc_id = *ptr;
+ − ++ptr;
+ −
+ − /* Copy data specific to records of LDN, LMN, and LRN phonebook types. */
+ − if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+ − {
+ − entry->v_time = 1;
+ −
+ − entry->time.year=data[max_tag_len+14] ;
+ − entry->time.month=data[max_tag_len+15];
+ − entry->time.day=data[max_tag_len+16];
+ − entry->time.hour=data[max_tag_len+17] ;
+ − entry->time.minute= data[max_tag_len+18];
+ − entry->time.second=data[max_tag_len+19] ;
+ − entry->time.time_zone=data[max_tag_len+20];
+ −
+ − entry->time.duration = (data[max_tag_len+21] << 16) +
+ − (data[max_tag_len+22] << 8) +
+ − (data[max_tag_len+23] );
+ −
+ − entry->v_line = 1;
+ − entry->line=data[max_tag_len+24];
+ −
+ − }
+ −
+ − if (*ptr NEQ 0xFF) /* check for extention records */
+ − {
+ − ext_rcd_num =(UBYTE)*ptr;
+ −
+ − if(db_info_field(pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
+ − {
+ − ACI_MFREE(data);
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Reset pointer to start location. */
+ − ptr = data;
+ −
+ − memset(ptr, 0xFF, info_field.record_size);
+ −
+ − if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, ptr) < DB_OK)
+ − {
+ − ACI_MFREE(data);
+ − //TISH, patch for OMAPS00123396
+ − //start
+ − // return PHB_FAIL;
+ − return PHB_OK;
+ − //end
+ − }
+ − pb_sim_read_ext(ptr, entry);
+ −
+ − while(*(ptr + 12) NEQ 0xFF) /* check if a further EXT entry exists */
+ − {
+ − memset(ptr, 0xFF, info_field.record_size);
+ −
+ − db_read_record(pbs_data.db_handle, ext_file_id, (USHORT)*(ptr+12), 0, info_field.record_size,ptr);
+ −
+ − pb_sim_read_ext(ptr, entry);
+ − }
+ − }
+ −
+ − ACI_MFREE(data);
+ −
+ − return PHB_OK;
+ − }
+ −
+ − /* Implements Measure #30 */
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_search_name |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Finds the first entry matching the search tag.
+ − */
+ −
+ − 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)
+ − {
+ − T_ACI_PB_TEXT key;
+ − int res;
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_search_name()");
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ −
+ −
+ − key.len = search_tag->len;
+ − key.cs = search_tag->cs;
+ − pb_sim_cvt_alpha_for_cmp ((UBYTE*) search_tag->data, (UBYTE*) key.data, search_tag->len);
+ −
+ − res = db_search(pbs_data.db_handle, field_id, NAME_IDX, order_num, pb_sim_search_alpha_func, match, (const UBYTE*)&key);
+ −
+ − if(res > DB_OK)
+ − {
+ − return PHB_OK;
+ − }
+ −
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_search_number |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Finds the first entry matching the number.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_search_number (T_PHB_TYPE type, const UBYTE *number, SHORT *order_num)
+ − {
+ − int res, i;
+ − CHAR cur_number[MAX_PHB_NUM_LEN];
+ − CHAR rev_number[MAX_PHB_NUM_LEN];
+ − int cmpLen, cmp_res;
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_search_number()");
+ −
+ − /* Handling for ECC Phonebook. */
+ − if(type EQ ECC)
+ − {
+ − for(i = 0; i < pbs_data.max_record[ECC]; i++)
+ − {
+ −
+ − cmhPHB_getAdrStr(cur_number, MAX_PHB_NUM_LEN - 1,phb_ecc_element[i].number,pbs_data.record_size[ECC]);
+ −
+ − pb_sim_revString(cur_number);
+ −
+ − strcpy( rev_number,(const char*)number);
+ −
+ − pb_sim_revString(rev_number);
+ −
+ − /*cmpLen = MINIMUM(strlen((const char*) cur_number), strlen((const char*)number));*/
+ − cmpLen = strlen((const char*)number);
+ − if(cmpLen > 7)
+ − {
+ − cmpLen = 7;
+ − cmp_res = pb_sim_cmpString((UBYTE*)cur_number, (UBYTE*)rev_number, cmpLen);
+ − }
+ − else
+ − {
+ − cmp_res = strcmp(cur_number,rev_number);
+ − }
+ −
+ − /*patch for ASTec29800 EFECC by dongfeng*/
+ − if(cmp_res EQ 0)
+ − return PHB_OK;
+ − }
+ −
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ −
+ −
+ −
+ − res = db_search(pbs_data.db_handle, field_id, NUMBER_IDX, order_num, pb_sim_search_num_func, PHB_MATCH_PARTIAL, number);
+ −
+ − if(res > DB_OK)
+ − {
+ − return PHB_OK;
+ − }
+ −
+ − return PHB_FAIL;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_sizes |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reads the sizes of a given phonebook.
+ − */
+ −
+ − T_PHB_RETURN pb_sim_read_sizes (T_PHB_TYPE type,
+ − SHORT *max_rcd,
+ − SHORT *used_rcd,
+ − UBYTE *tag_len,
+ − SHORT *max_ext,
+ − SHORT *used_ext)
+ − {
+ − T_DB_INFO_FIELD info_field;
+ − USHORT field_id;
+ − T_DB_CODE db_result;
+ −
+ − TRACE_FUNCTION("pb_sim_read_sizes()");
+ −
+ − /* Set every output parameter to zero for (not there) */
+ − *max_rcd = 0;
+ − *used_rcd = 0;
+ − *tag_len = 0;
+ − *max_ext = 0;
+ − *used_ext = 0;
+ −
+ − /* Handling for ECC Phonebook */
+ − if(type EQ ECC)
+ − {
+ − *max_rcd = pbs_data.max_record[ECC];
+ − *used_rcd = pbs_data.used_record[ECC];
+ − *tag_len = 0; /* To Do:Alpha tag will not be there for ECC. So assigning zero here */
+ − return PHB_OK;
+ − }
+ −
+ − /* Get elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id (type);
+ −
+ − /* Query the database about the field */
+ − db_result = db_info_field (pbs_data.db_handle, field_id, &info_field);
+ −
+ − if (db_result EQ DB_OK)
+ − {
+ − /* We got results for the main phonebook entries. */
+ − *max_rcd = info_field.num_records;
+ − *used_rcd = info_field.used_records;
+ − *tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+ −
+ − /* Get elementary file ID for the respective extension. */
+ − field_id = pb_sim_get_ext_file (type);
+ − if (field_id NEQ 0)
+ − {
+ − /*
+ − * Extension records may exist for this kind of phonebook.
+ − * Query the database about the ext records.
+ − */
+ − db_result = db_info_field (pbs_data.db_handle, field_id, &info_field);
+ − if (db_result EQ DB_OK)
+ − {
+ − /* There are also extension records present in the database. */
+ − *max_ext = info_field.num_records;
+ − *used_ext = info_field.used_records;
+ − }
+ − /* There is no else as it is not a problem if there are no extension
+ − * records for the phonebook on the SIM as those are optional only. */
+ − }
+ − return PHB_OK;
+ − }
+ − return PHB_FAIL; /* The phonebook does not exist */
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_get_entry_len |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Used to get the length in bytes of a given entry which is coded as given in 11.11 Annex B.
+ − */
+ −
+ − int pb_sim_get_entry_len (const UBYTE *pb_tag, UBYTE max_pb_len)
+ − {
+ −
+ − int pb_len = 0;
+ − UBYTE inc_count = 1;
+ − BOOL ucs2 = FALSE;
+ − UBYTE chars = 0;
+ −
+ − TRACE_FUNCTION("pb_sim_get_entry_len()");
+ −
+ − if (*pb_tag EQ 0x80)
+ − {
+ − ucs2 = TRUE;
+ − inc_count = 2; /* check two bytes */
+ − pb_len = 1; /* skip the 0x80 */
+ − }
+ − else if (*pb_tag EQ 0x81 OR *pb_tag EQ 0x82)
+ − {
+ − if (*pb_tag EQ 0x81)
+ − pb_len = 3; /* 0x80 + len + pointer */
+ − else
+ − pb_len = 4; /* 0x80 + len + 2xpointer */
+ −
+ − chars = pb_tag[1];
+ − pb_tag += pb_len; /* go to data */
+ − while (chars)
+ − {
+ − if (*pb_tag++ & 0x80)
+ − pb_len+=2;
+ − else
+ − pb_len+=1;
+ −
+ − pb_tag++;
+ − chars--;
+ − }
+ − return MINIMUM(pb_len,max_pb_len);
+ − }
+ −
+ − while (pb_len < max_pb_len)
+ − {
+ − if (ucs2 EQ TRUE)
+ − {
+ − if (!(pb_len+1 < max_pb_len)) /* Check also if we traverse the upper bound */
+ − break; /* so only a "half" UCS2 element is remaining */
+ − }
+ − if (pb_tag[pb_len] EQ 0xFF)
+ − {
+ − /* one 0xFF indicates the end of a non UCS2 string */
+ − if (ucs2 EQ FALSE)
+ − {
+ − break;
+ − }
+ − /* two 0xFF indicates the end of a UCS2 string */
+ − if (pb_tag[pb_len + 1] EQ 0xFF)
+ − {
+ − break;
+ − }
+ − }
+ − pb_len += inc_count;
+ − }
+ −
+ − return (pb_len);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_alpha_cmp |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Compares alpha identifier of two records.
+ − */
+ − int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags)
+ − {
+ − T_PHB_RECORD entry_1,entry_2;
+ − UBYTE cmpLen = 0;
+ − UBYTE *buffer;
+ − UBYTE max_tag_len;
+ − UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN];
+ − int cmp_res;
+ − T_DB_INFO_FIELD info_field;
+ −
+ − TRACE_FUNCTION("pb_sim_alpha_cmp()");
+ −
+ −
+ − db_info_field(db_handle, field_id, &info_field);
+ −
+ − MALLOC(buffer, info_field.record_size);
+ −
+ − /* Read the first record. */
+ − db_read_record(db_handle, field_id, recno_1, 0, info_field.record_size, buffer);
+ −
+ − /* Unpack record 1 to do a string comparison on the alpha identifier field */
+ − max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+ − if (max_tag_len > PHB_MAX_TAG_LEN)
+ − max_tag_len = PHB_MAX_TAG_LEN;
+ −
+ − entry_1.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
+ −
+ − memset(entry_1.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+ − memcpy ( (char*)entry_1.tag, (char*)buffer, entry_1.tag_len );
+ −
+ − pb_sim_cvt_alpha_for_cmp ( entry_1.tag, cur_tag, entry_1.tag_len );
+ −
+ − memset(buffer, 0, info_field.record_size);
+ −
+ − /* Read the second record. */
+ − db_read_record(db_handle, field_id, recno_2, 0, info_field.record_size, buffer);
+ −
+ − /* Unpack record 2 to do a string comparison on the alpha identifier field */
+ − max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+ − if (max_tag_len > PHB_MAX_TAG_LEN)
+ − max_tag_len = PHB_MAX_TAG_LEN;
+ −
+ − entry_2.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
+ −
+ − memset(entry_2.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+ − memcpy ( (char*)entry_2.tag, (char*)buffer, entry_2.tag_len );
+ −
+ − pb_sim_cvt_alpha_for_cmp ( entry_2.tag, check_tag, entry_2.tag_len );
+ −
+ − cmpLen = MINIMUM ( entry_1.tag_len,
+ − entry_2.tag_len );
+ −
+ − TRACE_EVENT_P1("%d", cmpLen);
+ −
+ − cmp_res = pb_sim_cmpString ( cur_tag, check_tag, cmpLen );
+ −
+ − if (cmp_res EQ 0)
+ − {
+ − /* Correct result when length was different, ACIPHB201 */
+ − if (entry_1.tag_len < entry_2.tag_len)
+ − cmp_res = -1;
+ − else if (entry_1.tag_len > entry_2.tag_len)
+ − cmp_res = 1;
+ − }
+ −
+ − MFREE(buffer);
+ −
+ − return cmp_res;
+ − }
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_number |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reads a phine number from a given record
+ − */
+ − LOCAL void pb_sim_read_number (int db_handle,
+ − USHORT field_id,
+ − USHORT recno,
+ − CHAR *number)
+ − {
+ − T_PHB_RECORD entry;
+ − T_DB_INFO_FIELD info_field;
+ − UBYTE *sim_buffer, *buffer;
+ − UBYTE ext_rcd_num;
+ − unsigned ext_rec_cnt;
+ − USHORT ext_id;
+ −
+ − TRACE_FUNCTION("pb_sim_read_number()");
+ −
+ − ACI_MALLOC(sim_buffer, SIM_MAX_RECORD_SIZE);
+ − buffer = sim_buffer;
+ −
+ − db_info_field(db_handle, field_id, &info_field);
+ −
+ − /* Read record recno_1 from the database using db_read_record() */
+ − db_read_record (db_handle, field_id, recno, 0, info_field.record_size, buffer);
+ −
+ − /* Read only number from the buffer. */
+ − buffer += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+ − entry.len = *(buffer++) - 1;
+ − entry.ton_npi = *buffer++;
+ −
+ − /*
+ − * This error handling is done to avoid the accidental incorrect
+ − * record length stored in the test SIMs
+ − */
+ − if (entry.len > PHB_PHY_NUM_LENGTH)
+ − {
+ − entry.len = PHB_PHY_NUM_LENGTH;
+ − }
+ −
+ − memset (entry.number, 0xFF, PHB_PACKED_NUM_LEN);
+ − memcpy (entry.number, buffer, entry.len);
+ − buffer += 10;
+ − entry.cc_id = *buffer++;
+ − ext_rcd_num = (UBYTE)*buffer;
+ − ext_id = pb_sim_get_ext_file_id (field_id);
+ − if ((ext_id NEQ 0) AND
+ − (db_info_field (db_handle, ext_id, &info_field) EQ DB_OK))
+ − {
+ − /* Extension records exist and we can obtain information about it */
+ − ext_rec_cnt = 0;
+ − while ((ext_rcd_num NEQ 0xFF) AND
+ − (ext_rcd_num NEQ 0) AND
+ − (ext_rcd_num <= info_field.num_records) AND
+ − (ext_rec_cnt < info_field.num_records))
+ − {
+ − /*
+ − * Record not empty, in range 1..max num of ext records
+ − * Impossible to have read all records (avoid infinite loop)
+ − */
+ − ext_rec_cnt++;
+ − (void)db_read_record (db_handle, ext_id, ext_rcd_num,
+ − 0, info_field.record_size,
+ − buffer);
+ − pb_sim_read_ext (buffer, &entry);
+ − ext_rcd_num = sim_buffer[12];
+ − }
+ − }
+ −
+ − cmhPHB_getAdrStr(number,
+ − MAX_PHB_NUM_LEN - 1,
+ − entry.number,
+ − entry.len);
+ −
+ − ACI_MFREE (sim_buffer);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_number_cmp |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Compares two numbers of two records.
+ − */
+ − int pb_sim_number_cmp (int db_handle,
+ − USHORT field_id,
+ − USHORT recno_1,
+ − USHORT recno_2,
+ − ULONG flags)
+ − {
+ − CHAR cur_number[MAX_PHB_NUM_LEN];
+ − CHAR ref_number[MAX_PHB_NUM_LEN];
+ −
+ − TRACE_FUNCTION("pb_sim_number_cmp()");
+ −
+ − /* Read the numbers */
+ − pb_sim_read_number (db_handle, field_id, recno_1, cur_number);
+ − pb_sim_read_number (db_handle, field_id, recno_2, ref_number);
+ −
+ − /* Reverse the numbers to compare number from right. */
+ − pb_sim_revString(cur_number);
+ − pb_sim_revString(ref_number);
+ −
+ − return pb_sim_cmpWild ((char *)cur_number, (char *)ref_number, MAX_PHB_NUM_LEN);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_ext |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reads extension records from the database and copies them to number.
+ − */
+ − /* Extesion records will be stored as per 11.11.
+ − Bytes Description M/O Length
+ − --------------------------------------
+ − 1 Record type M 1 byte
+ − 2 to 12 Extension data M 11 bytes
+ − 13 Identifier M 1 byte
+ − --------------------------------------*/
+ −
+ − void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry)
+ − {
+ − UBYTE data_len;
+ − UBYTE data_type;
+ − UBYTE *data;
+ −
+ − TRACE_FUNCTION("pb_sim_read_ext()");
+ −
+ − /* If this extension record is not empty, it is written in phonebook. */
+ − data = buffer;
+ −
+ − data_type = *data;
+ − data_len = *(data+1);
+ −
+ − switch (data_type)
+ − {
+ −
+ − case 1: /* Called Party Subaddress */
+ − {
+ − int sa_len = 0;
+ − while (sa_len<PHB_PACKED_NUM_LEN) /* get length of possible already stored subaddr if more than one EXT is used */
+ − {
+ − if (entry->subaddr[sa_len] EQ 0xFF)
+ − break;
+ − else if ((entry->subaddr[sa_len] & 0xF0) EQ 0xF0)
+ − {
+ − sa_len++;
+ − break;
+ − }
+ − else
+ − sa_len++;
+ − }
+ −
+ − pb_sim_nibblecopy (entry->subaddr,
+ − sa_len,
+ − data + 2,
+ − data_len);
+ − }
+ − break;
+ −
+ − case 2: /* Additional data */
+ − entry->len =
+ − pb_sim_nibblecopy (entry->number,
+ − entry->len,
+ − data + 2,
+ − data_len);
+ − break;
+ −
+ − default: /* unknown type */
+ − break;
+ − }
+ −
+ − return;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_revString |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reverses a string within the same variable.
+ − */
+ −
+ − void pb_sim_revString(char *str)
+ − {
+ − UBYTE i, j,str_len;
+ − char ch;
+ −
+ − TRACE_FUNCTION("pb_sim_revString()");
+ −
+ − str_len = strlen(str);
+ −
+ − for(i = 0, j = str_len - 1;i < (str_len / 2); i++, j--)
+ − {
+ − ch = *(str + i);
+ − *(str + i) = *(str + j);
+ − *(str + j) = ch;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_search_alpha_func |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Searches for a given alpha key in the database.
+ − */
+ −
+ − int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num)
+ − {
+ − T_ACI_PB_TEXT *search_key;
+ − T_PHB_RECORD entry;
+ − UBYTE cmpLen = 0;
+ − T_PHB_TYPE phb_type;
+ − UBYTE cur_tag[PHB_MAX_TAG_LEN];
+ − int cmp_res;
+ −
+ − TRACE_FUNCTION("pb_sim_search_alpha_func()");
+ −
+ − /* Cast search key to appropriate data structure */
+ − search_key = (T_ACI_PB_TEXT *)key;
+ −
+ − /* Get PHB type from field ID using PHB_ACI function. */
+ − phb_type = pb_get_phb_type_from_ef(field_id);
+ −
+ − /* Read record from the database. */
+ − pb_sim_read_record(phb_type, rec_num, &entry);
+ −
+ − pb_sim_cvt_alpha_for_cmp ( entry.tag, cur_tag, entry.tag_len );
+ −
+ − cmpLen = search_key->len;
+ −
+ − if(flags EQ PHB_MATCH_PARTIAL)
+ − cmpLen = MINIMUM ( entry.tag_len, cmpLen);
+ −
+ − TRACE_EVENT_P1( "cmpLen=%d", cmpLen );
+ −
+ − cmp_res = pb_sim_cmpString ( cur_tag, search_key->data, cmpLen );
+ −
+ − return cmp_res;
+ − }
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_search_num_func |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Searches for a given number key in the database.
+ − */
+ − int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle,
+ − USHORT field_id, USHORT rec_num)
+ − {
+ − T_PHB_RECORD entry;
+ − UBYTE cmpLen = 0;
+ − T_PHB_TYPE phb_type;
+ − CHAR cur_number[MAX_PHB_NUM_LEN];
+ − CHAR rev_key[MAX_PHB_NUM_LEN];
+ − int cmp_res;
+ − size_t strg_len;
+ −
+ − TRACE_FUNCTION("pb_sim_search_num_func()");
+ −
+ − /* Get PHB type from field ID using PHB_ACI function. */
+ − phb_type = pb_get_phb_type_from_ef(field_id);
+ −
+ − /* Read record from the database. */
+ − if(pb_sim_read_record(phb_type, rec_num, &entry) NEQ PHB_OK)
+ − return -1;
+ −
+ − cmhPHB_getAdrStr(cur_number,
+ − MAX_PHB_NUM_LEN - 1,
+ − entry.number,
+ − entry.len);
+ −
+ − /* Reverse the first number to compare number from right. */
+ − pb_sim_revString(cur_number);
+ −
+ − /* Reverse the second number to compare number from right. */
+ −
+ − strcpy (rev_key, (const char*) key);
+ −
+ − pb_sim_revString(rev_key);
+ −
+ − cmpLen = strlen(rev_key);
+ −
+ − if(flags EQ PHB_MATCH_PARTIAL)
+ − {
+ − strg_len = strlen(cur_number);
+ − cmpLen = MINIMUM(strg_len, cmpLen);
+ − }
+ −
+ − TRACE_EVENT_P1("Number to be compared: %s", cur_number);
+ − TRACE_EVENT_P1("Number to be searched: %s", rev_key);
+ − if(cmpLen > 7)
+ − {
+ − cmpLen = 7;
+ − }
+ −
+ − cmp_res = pb_sim_cmpWild((char*)cur_number, (char*)rev_key, cmpLen);
+ −
+ −
+ − TRACE_EVENT_P1("Result of the comparison: %d", cmp_res);
+ −
+ − return cmp_res;
+ −
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_nibblecopy |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Used to convert BCD nibbles to string.
+ − */
+ −
+ − LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count)
+ − {
+ −
+ − int i;
+ − int nibble;
+ −
+ − int destnibble=destlen*2;
+ −
+ − TRACE_FUNCTION("pb_sim_nibblecopy()");
+ −
+ − if (destnibble)
+ − {
+ − if ((dest[destlen-1] & 0xF0) == 0xF0) /* check if there is space in last nibble */
+ − destnibble--;
+ − }
+ −
+ − for ( i=0; i<count*2; i++ )
+ − {
+ − /* check if we access out of bounds */
+ − if (destnibble/2 >= PHB_PACKED_NUM_LEN)
+ − return PHB_PACKED_NUM_LEN;
+ −
+ − /* get nibble */
+ − if (i%2 == 0)
+ − nibble = src[i/2] & 0x0F;
+ − else
+ − nibble = (src[i/2] & 0xF0) >> 4;
+ −
+ − if (nibble == 0xF) /* end of number detected */
+ − break;
+ −
+ − /* put nibble */
+ − if (destnibble%2 == 0)
+ − {
+ − dest[destnibble/2] &= 0xF0;
+ − dest[destnibble/2] |= nibble;
+ − }
+ − else
+ − {
+ − dest[destnibble/2] &= 0x0F;
+ − dest[destnibble/2] |= nibble << 4;
+ − }
+ −
+ − destnibble++;
+ − }
+ − return destnibble/2 + destnibble%2; /* round up */
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE : pb_sim_read_eeprom_ecc |
+ − +------------------------------------------------------------------------+
+ −
+ − PURPOSE : Read EC number from EEPROM.
+ −
+ − */
+ − LOCAL void pb_sim_read_eeprom_ecc (void)
+ − {
+ − EF_ECC efecc;
+ − UBYTE *data_ptr;
+ − UBYTE version;
+ − int rec_ctr;
+ −
+ − TRACE_FUNCTION("pb_sim_read_eeprom_ecc()");
+ −
+ − /* Initialise ECC Phonebook Info. */
+ − pbs_data.max_record[ECC] = MAX_ECC_RCD;
+ − pbs_data.used_record[ECC] = 0;
+ −
+ − if (pcm_ReadFile((UBYTE *)EF_ECC_ID,
+ − SIZE_EF_ECC,
+ − (UBYTE *)&efecc,
+ − &version) EQ DRV_OK)
+ − {
+ − { /* workaround when invalid data stored on PCM */
+ − CHAR ecc_number[MAX_PHB_NUM_LEN];
+ − int num_len;
+ −
+ − data_ptr = efecc.ecc1;
+ −
+ − for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
+ − {
+ − if (*data_ptr NEQ 0xFF)
+ − {
+ − cmhPHB_getAdrStr (ecc_number,
+ − MAX_PHB_NUM_LEN - 1,
+ − data_ptr,
+ − ECC_NUM_LEN);
+ − for (num_len = 0; num_len < ECC_NUM_LEN; num_len++)
+ − {
+ − if (!isdigit (ecc_number[num_len]))
+ − {
+ − TRACE_EVENT_P2 ("[ERR] pb_read_eeprom_ecc(): invalid character found %c (%d)",
+ − ecc_number[num_len], rec_ctr);
+ − return;
+ − }
+ − }
+ − }
+ − data_ptr += ECC_NUM_LEN;
+ − }
+ − } /* workaround end */
+ −
+ − data_ptr = &efecc.ecc1[0];
+ −
+ − memset( phb_ecc_element,0xFF, (pbs_data.max_record[ECC] * sizeof(T_PHB_ECC_RECORD)) );
+ −
+ − for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
+ − {
+ − if(*data_ptr NEQ 0xff)
+ − {
+ − phb_ecc_element[rec_ctr].phy_idx = rec_ctr + 1;
+ − memcpy(phb_ecc_element[rec_ctr].number, data_ptr, ECC_NUM_LEN);
+ − data_ptr += ECC_NUM_LEN;
+ − (pbs_data.used_record[ECC])++;
+ − }
+ − }
+ − }
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_prepare_ext_data |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Prepare the data for the extention record.
+ − If NULL pointer is given for number and subaddress
+ − then the extention record will marked as unused
+ −
+ − */
+ − /* Extesion records will be stored as per 11.11.
+ − Bytes Description M/O Length
+ − --------------------------------------
+ − 1 Record type M 1 byte
+ − 2 to 12 Extension data M 11 bytes
+ − 13 Identifier M 1 byte
+ − --------------------------------------*/
+ −
+ − LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr)
+ − {
+ − UBYTE *data_num = NULL;
+ − UBYTE *data_subadd = NULL;
+ −
+ − TRACE_FUNCTION("pb_sim_prepare_ext_data()");
+ −
+ − if(number[10] NEQ 0xFF)
+ − data_num = number + ((ext_count + 1) * 10);
+ −
+ − data_subadd = subaddr + (ext_count * 11);
+ −
+ − memset(ext_data, 0xFF, sizeof(ext_data));
+ −
+ − if ((data_num NEQ NULL) AND (*data_num NEQ 0xFF))
+ − {
+ − /* Set record type to 2 which corresponds to Additional data. Record type as per 11.11 */
+ − ext_data[0] = 2;
+ − ext_data[1] = no_len - ((ext_count + 1) * 10);
+ − memcpy (ext_data + 2, data_num, 10);
+ − }
+ − else if ((data_subadd NEQ NULL) AND (*data_subadd NEQ 0xFF))
+ − {
+ − TRACE_EVENT ("SUBADDRESS EXTENTION");
+ − /* Set record type to 1 which corresponds to Called Party Subaddress. Record type as per 11.11 */
+ − ext_data[0] = 1;
+ − memcpy (ext_data + 1, data_subadd, 11);
+ − }
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_get_field_id |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Returns field ID for the corresponding Phonebook type.
+ −
+ − */
+ − LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type)
+ − {
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_get_field_id()");
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − switch(type)
+ − {
+ − case ADN:
+ − field_id = SIM_ADN;
+ − break;
+ −
+ − case LDN:
+ − field_id = SIM_OCI;
+ − break;
+ −
+ − case LRN:
+ − field_id = FFS_LRN;
+ − break;
+ −
+ − case LMN:
+ − field_id = FFS_LMN;
+ − break;
+ −
+ − case UPN:
+ − field_id = SIM_MSISDN;
+ − break;
+ −
+ − case FDN:
+ − field_id = SIM_FDN;
+ − break;
+ −
+ − case SDN:
+ − field_id = SIM_SDN;
+ − break;
+ −
+ − case BDN:
+ − field_id = SIM_BDN;
+ − break;
+ −
+ − default:
+ − TRACE_ERROR ("No such field");
+ − TRACE_EVENT_P1 ("No such field for type = %04X", type);
+ − field_id = 0;
+ − break;
+ − }
+ −
+ − return field_id;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_get_ext_file |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Returns field ID for the corresponding Phonebook type.
+ −
+ − */
+ − LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type)
+ − {
+ − USHORT ext_file_id;
+ −
+ − TRACE_FUNCTION("pb_sim_get_ext_file()");
+ −
+ − /* Get Extension Elementary file ID for the Phonebook type. */
+ − switch(type)
+ − {
+ − case ADN:
+ − case UPN:
+ − ext_file_id = SIM_EXT1;
+ − break;
+ −
+ − case FDN:
+ − ext_file_id = SIM_EXT2;
+ − break;
+ −
+ − case SDN:
+ − ext_file_id = SIM_EXT3;
+ − break;
+ −
+ − case BDN:
+ − ext_file_id = SIM_EXT4;
+ − break;
+ −
+ − case LDN:
+ − ext_file_id = SIM_EXT5;
+ − break;
+ −
+ − case LRN:
+ − ext_file_id = FFS_EXT_LRN;
+ − break;
+ −
+ − case LMN:
+ − ext_file_id = FFS_EXT_LMN;
+ − break;
+ −
+ − default:
+ − ext_file_id = 0; /* No extension records available */
+ − break;
+ − }
+ −
+ − return ext_file_id;
+ − }
+ −
+ − /*
+ − +---------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_cvt_alpha_for_cmp |
+ − +---------------------------------------------------------------------+
+ −
+ − PURPOSE : convert alpha to lower case when not unicode
+ −
+ − */
+ − LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE *src,
+ − UBYTE *dst,
+ − UBYTE len )
+ − {
+ − int i;
+ −
+ − TRACE_FUNCTION("pb_sim_cvt_alpha_for_cmp()");
+ −
+ − if (*src NEQ 0x80) /* 11.11 Annex B 0x80 is the UCS2 indicator */
+ − {
+ − for ( i = 0; i < len; i++ )
+ − dst[i] = (UBYTE)tolower((int)src[i]);
+ − }
+ − else
+ − {
+ − memcpy (dst, src, len);
+ − }
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_get_ext_file_id |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Returns Extension field ID for the corresponding field ID of a Phonebook.
+ −
+ − */
+ − LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id)
+ − {
+ − USHORT ext_file_id;
+ −
+ − TRACE_FUNCTION("pb_sim_get_ext_file_id()");
+ −
+ − /* Get Extension Elementary file ID for the Phonebook type. */
+ − switch(field_id)
+ − {
+ − case SIM_ADN:
+ − case SIM_LND:
+ − case SIM_MSISDN:
+ − ext_file_id = SIM_EXT1;
+ − break;
+ −
+ − case SIM_FDN:
+ − ext_file_id = SIM_EXT2;
+ − break;
+ −
+ − case SIM_SDN:
+ − ext_file_id = SIM_EXT3;
+ − break;
+ −
+ − case SIM_BDN:
+ − ext_file_id = SIM_EXT4;
+ − break;
+ −
+ − case SIM_OCI:
+ − ext_file_id = SIM_EXT5;
+ − break;
+ −
+ − case FFS_LRN:
+ − ext_file_id = FFS_EXT_LRN;
+ − break;
+ −
+ − case FFS_LMN:
+ − ext_file_id = FFS_EXT_LMN;
+ − break;
+ −
+ − default:
+ − ext_file_id = 0;
+ − break;
+ − }
+ −
+ − return ext_file_id;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_get_ext_type |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Returns Extension Type ID for the corresponding
+ − field ID of a Phonebook.
+ −
+ − */
+ − LOCAL T_EXT_TYPE pb_sim_get_ext_type (USHORT field_id)
+ − {
+ − T_EXT_TYPE ext_type;
+ −
+ − /* Get Extension Type for the Phonebook field ID. */
+ − switch(field_id)
+ − {
+ − case SIM_ADN:
+ − case SIM_LND:
+ − case SIM_MSISDN:
+ − ext_type = EXT1;
+ − break;
+ −
+ − case SIM_FDN:
+ − ext_type = EXT2;
+ − break;
+ −
+ − case SIM_SDN:
+ − ext_type = EXT3;
+ − break;
+ −
+ − case SIM_BDN:
+ − ext_type = EXT4;
+ − break;
+ −
+ − case SIM_OCI:
+ − ext_type = EXT5;
+ − break;
+ −
+ − case FFS_LRN:
+ − ext_type = EXT_LRN;
+ − break;
+ −
+ − case FFS_LMN:
+ − ext_type = EXT_LMN;
+ − break;
+ −
+ − default:
+ − ext_type = INVALID_EXT;
+ − break;
+ − }
+ −
+ − return ext_type;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------+
+ − | PROJECT : MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_find_free_record |
+ − +----------------------------------------------------------------------+
+ −
+ −
+ − PURPOSE : Returns free record number for the Phonebook type.
+ −
+ − */
+ − GLOBAL int pb_sim_find_free_record (T_PHB_TYPE type)
+ − {
+ − int db_result;
+ − unsigned i;
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_find_free_record()");
+ −
+ − switch (type)
+ − {
+ − case ECC: /* ECC not stored in DB, special handling */
+ − for (i = 0; i < pbs_data.max_record[ECC]; i++)
+ − {
+ − if (phb_ecc_element[i].phy_idx EQ 0)
+ − return i + 1;
+ − }
+ − return 0; /* No free record found */
+ −
+ − case LDN:
+ − case LRN:
+ − case LMN:
+ − return 1; /* For cyclic entries always the first */
+ −
+ − default:
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ − db_result = db_find_free_record(pbs_data.db_handle, field_id);
+ −
+ − if (db_result <= 0)
+ − return 0; /* No free record */
+ −
+ − return db_result;
+ − }
+ − }
+ −
+ − GLOBAL int pb_sim_find_free_ext_record ()
+ − {
+ − int db_result;
+ − unsigned i;
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_find_ext_free_record()");
+ −
+ − field_id =SIM_EXT1;
+ −
+ − db_result = db_find_free_record(pbs_data.db_handle, field_id);
+ −
+ − if (db_result <= 0)
+ − return 0; /* No free record */
+ −
+ − return db_result;
+ − }
+ −
+ −
+ −
+ −
+ −
+ − /*
+ − +-------------------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_get_size_except_tag |
+ − +-------------------------------------------------------------------------------+
+ −
+ − PURPOSE : Returns size of data excluding length of tag (alpha identifier)
+ − */
+ − USHORT pb_sim_get_size_except_tag (USHORT field_id)
+ − {
+ −
+ − TRACE_FUNCTION("pb_sim_get_size_except_tag()");
+ − switch(field_id)
+ − {
+ − case SIM_ADN:
+ − case SIM_FDN:
+ − case SIM_BDN:
+ − case SIM_MSISDN:
+ − case SIM_SDN:
+ − return 14; /* 11.11 */
+ −
+ − case FFS_LRN:
+ − case FFS_LMN:
+ − case SIM_OCI:
+ − return 27; /* Using EF_OCI, 31.102 4.2.34 */
+ −
+ − //case SIM_ICI:
+ − // return 28; /* Using EF_ICI, 31.102 4.2.33 */
+ −
+ − default:
+ − TRACE_ERROR("Invalid field ID passed !");
+ − return 0;
+ − }
+ − }
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_cmpString |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : compare two strings.
+ − if s1 < s2 return value < 0
+ − if s1 = s2 return value = 0
+ − if s1 > s2 return value > 0
+ − */
+ −
+ − static int pb_sim_cmpString ( UBYTE *s1, UBYTE *s2, UBYTE len )
+ − {
+ − int n = 0;
+ −
+ − /* TRACE_FUNCTION("pb_sim_cmpString()"); */ /* Called too often to trace */
+ −
+ − if ((*s1 EQ 0x80) AND
+ − (*s2 NEQ 0x80) )
+ − {
+ − s1++;
+ − len--;
+ − return pb_sim_cmp2Bytes(s1, s2, len, 1);
+ − }
+ − else if ((*s1 NEQ 0x80) AND
+ − (*s2 EQ 0x80) )
+ − {
+ − s2++;
+ − len--;
+ − return pb_sim_cmp2Bytes(s1, s2, len, 2);
+ − }
+ − else
+ − {
+ − while (*s1 EQ *s2)
+ − {
+ − if (*s1 EQ 0xff)
+ − return 0;
+ − s1++;
+ − s2++;
+ − n++;
+ − if (n EQ len)
+ − return 0;
+ − }
+ −
+ − if ((*s1 > *s2) AND (*s1 NEQ 0xff))
+ − return 1;
+ −
+ − return -1;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_cmp2Bytes |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : compare two strings.
+ − if s1 < s2 return value < 0
+ − if s1 = s2 return value = 0
+ − if s1 > s2 return value > 0
+ −
+ − flag = 1, s1 is unicode
+ − flag = 2, s2 is unicode
+ − */
+ −
+ − LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag)
+ − {
+ − int n = 0;
+ −
+ − /* TRACE_FUNCTION("pb_sim_cmp2Bytes()"); */
+ −
+ − if (flag EQ 1)
+ − {
+ − while ( (*s1 EQ 0x00 OR *s1 EQ 0xFF ) AND ( *(s1+1) EQ *s2) )
+ − {
+ − if (*s1 EQ 0xff AND *(s1+1) EQ 0xFF)
+ − return 0;
+ −
+ − s1 += 2;
+ − s2++;
+ − n += 2;
+ −
+ − if (n >= len)
+ − return 0;
+ − }
+ −
+ − if ( ( *s1 > 0 AND *s1 NEQ 0xff ) OR
+ − ( !*s1 AND ( *(s1+1) > *s2 ) ) )
+ − return 1;
+ −
+ − return -1;
+ − }
+ −
+ − if (flag EQ 2)
+ − {
+ − while ((*s2 EQ 0x00 OR *s2 EQ 0xFF) AND (*s1 EQ *(s2+1)))
+ − {
+ − if (*s2 EQ 0xff AND *(s2+1) EQ 0xFF)
+ − return 0;
+ −
+ − s1++;
+ − s2 += 2;
+ − n += 2;
+ −
+ − if (n >= len)
+ − return 0;
+ − }
+ −
+ − if ((*s2 > 0 AND *s2 NEQ 0xff) OR
+ − (!*s2 AND (*(s2+1) > *s1)) )
+ − return -1;
+ −
+ − return 1;
+ − }
+ − return -1;
+ − }
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_update_extn_records |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Update reference count for extension record and delete if record
+ − is not referenced at all.
+ − ETSI 11.11 clause 11.5.1 states that reference counts not only
+ − have to be maintained for EXT1 but also for other EXT records.
+ − */
+ − LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id,
+ − USHORT rec_num,
+ − SHORT ref_type)
+ − {
+ − T_EXT_TYPE ext_type;
+ − UBYTE *refptr;
+ − int db_result;
+ − UBYTE dummy_ref;
+ −
+ − switch (ext_field_id)
+ − {
+ − case SIM_EXT1: ext_type = EXT1; break;
+ − case SIM_EXT2: ext_type = EXT2; break;
+ − case SIM_EXT3: ext_type = EXT3; break;
+ − case SIM_EXT4: ext_type = EXT4; break;
+ − case SIM_EXT5: ext_type = EXT5; break;
+ − case FFS_EXT_LRN: ext_type = EXT_LRN; break;
+ − case FFS_EXT_LMN: ext_type = EXT_LMN; break;
+ − default:
+ − return PHB_FAIL;
+ − }
+ −
+ − if (rec_num <= MAX_EXT_RECORDS)
+ − {
+ − refptr = &ext_ref_count[ext_type][rec_num - 1];
+ − }
+ − else
+ − {
+ − /* Could become improved by using dynamic memory but better as using an
+ − * illegal array index. Only ref counters will have a problem here. */
+ − TRACE_ERROR ("SIM exceeds MAX_EXT_RECORDS");
+ − dummy_ref = 1;
+ − refptr = &dummy_ref;
+ − }
+ −
+ − if (ref_type EQ -1)
+ − {
+ − /* Decrement usage counter */
+ − if (*refptr > 0)
+ − {
+ − *refptr += ref_type;
+ − }
+ − else
+ − {
+ − TRACE_ERROR ("EXT usage counter below zero");
+ − }
+ −
+ − if (*refptr EQ 0)
+ − {
+ − db_result = db_delete_record(pbs_data.db_handle, ext_field_id, rec_num);
+ − if(db_result < DB_OK)
+ − return PHB_FAIL;
+ − }
+ − }
+ − else if (ref_type EQ 1)
+ − {
+ − *refptr += ref_type;
+ − }
+ − else
+ − return PHB_FAIL; /* add_val not in -1, +1 */
+ −
+ − TRACE_EVENT_P3 ("Usage count of EXT %04X, record %d = %d",
+ − ext_field_id, rec_num, *refptr);
+ −
+ − return PHB_OK;
+ − }
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_del_ext_records |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Read extension records and update the records.
+ −
+ − */
+ − #define RETURN(x) { retVal = x; goto cleanup_exit; }
+ − /*lint -e{801} Use of goto*/
+ − LOCAL T_PHB_RETURN pb_sim_del_ext_records (T_PHB_TYPE type,
+ − USHORT field_id,
+ − USHORT db_recno)
+ − {
+ − int db_result;
+ − T_PHB_RETURN retVal;
+ − USHORT ext_file_id;
+ − T_DB_INFO_FIELD info_field;
+ − UBYTE *data;
+ − UBYTE ext_rcd_num;
+ −
+ − TRACE_FUNCTION("pb_sim_del_ext_records()");
+ −
+ − ACI_MALLOC (data, SIM_MAX_RECORD_SIZE);
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = pb_sim_get_ext_file(type);
+ −
+ − /* Read record from the database. */
+ − if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+ − RETURN (PHB_FAIL)
+ −
+ − db_result = db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data);
+ − if (db_result EQ DB_EMPTY_RECORD)
+ − RETURN (PHB_OK) /* Nothing to do */
+ −
+ − if (db_result < DB_OK)
+ − RETURN (PHB_FAIL) /* Some other problem */
+ −
+ − /* Get extension record identifier */
+ − ext_rcd_num = data[info_field.record_size - 1];
+ −
+ − while (ext_rcd_num NEQ 0xFF) /* check for extension records */
+ − {
+ − if(db_info_field (pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
+ − RETURN (PHB_FAIL)
+ −
+ − if ((ext_rcd_num EQ 0) OR (ext_rcd_num > info_field.num_records))
+ − {
+ − TRACE_EVENT_P1 ("illegal ext record number %d ignored", ext_rcd_num);
+ − RETURN (PHB_OK)
+ − }
+ −
+ − if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, data) < DB_OK)
+ − RETURN (PHB_FAIL)
+ −
+ − if (pb_sim_update_extn_records(ext_file_id, ext_rcd_num, -1) EQ PHB_FAIL)
+ − RETURN (PHB_FAIL)
+ −
+ − ext_rcd_num = data[12];
+ − }
+ − RETURN (PHB_OK)
+ −
+ − cleanup_exit:
+ − ACI_MFREE (data);
+ − return retVal;
+ − }
+ − #undef RETURN
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_ext_records_used |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : check if extension records is used by one phone book record (ADN & FDN).
+ −
+ − */
+ − #define RETURN(x) { retVal = x; goto cleanup_exit; }
+ − /*lint -e{801} Use of goto*/
+ − LOCAL BOOL pb_sim_ext_records_used (T_PHB_TYPE type,
+ − USHORT field_id,
+ − USHORT db_recno)
+ − {
+ − int db_result;
+ − BOOL retVal;
+ − USHORT ext_file_id;
+ − T_DB_INFO_FIELD info_field;
+ − UBYTE *data;
+ − UBYTE ext_rcd_num;
+ −
+ − TRACE_FUNCTION("pb_sim_ext_records_used()");
+ −
+ − ACI_MALLOC (data, SIM_MAX_RECORD_SIZE);
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = pb_sim_get_ext_file(type);
+ −
+ − /* Read record from the database. */
+ − if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+ − RETURN (FALSE)
+ −
+ − db_result = db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data);
+ − if (db_result < DB_OK)
+ − RETURN (FALSE) /* record can not be read - so no EXTn used */
+ −
+ − /* Get extension record identifier */
+ − ext_rcd_num = data[info_field.record_size - 1];
+ −
+ − TRACE_EVENT_P1("pb_sim_ext_records_used() --1-- ext_rcd_num = %d", ext_rcd_num);
+ −
+ − if (ext_rcd_num NEQ 0xFF) /* check for extension records */
+ − {
+ − if(db_info_field (pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
+ − RETURN (FALSE)
+ −
+ − if ((ext_rcd_num EQ 0) OR (ext_rcd_num > info_field.num_records))
+ − {
+ − TRACE_EVENT_P1 ("illegal ext record number %d ignored", ext_rcd_num);
+ − RETURN (FALSE)
+ − }
+ −
+ − if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, data) < DB_OK)
+ − RETURN (FALSE)
+ −
+ − ext_rcd_num = data[12];
+ − TRACE_EVENT_P1("pb_sim_ext_records_used() --2-- ext_rcd_num = %d", ext_rcd_num);
+ −
+ − RETURN (TRUE) //return TRUE here since ext_rcd_num is valid
+ − }
+ − else
+ − {
+ − RETURN (FALSE)
+ − }
+ − cleanup_exit:
+ − ACI_MFREE (data);
+ − return retVal;
+ − }
+ − #undef RETURN
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_retrieve_rdm_recno |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Retrieving record number for LDN, LMN and LRN Phonebook.
+ −
+ − */
+ −
+ − LOCAL USHORT pb_sim_retrieve_rdm_recno (T_PHB_TYPE type)
+ − {
+ − USHORT rec_no;
+ −
+ − TRACE_FUNCTION("pb_sim_retrieve_rdm_recno()");
+ −
+ − switch(type)
+ − {
+ − case LDN:
+ − rec_no = LDN_DATA_RECNO;
+ − break;
+ −
+ − case LMN:
+ − rec_no = LMN_DATA_RECNO;
+ − break;
+ −
+ − case LRN:
+ − rec_no = LRN_DATA_RECNO;
+ − break;
+ −
+ − default:
+ − rec_no = 0;
+ − break;
+ − }
+ −
+ − return rec_no;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : MMI-Framework (8417) MODULE : PHB |
+ − | STATE : code ROUTINE : pb_sim_cmpWild |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : compare two strings considering wildcard.
+ − if s1 < s2 return value < 0
+ − if s1 = s2 return value = 0
+ − if s1 > s2 return value > 0
+ − */
+ −
+ − GLOBAL int pb_sim_cmpWild ( const char *s1, const char *s2, size_t cmp_len )
+ − {
+ − TRACE_FUNCTION("pb_sim_cmpWild()");
+ −
+ − if (cmp_len EQ 0)
+ − return 0; /* Nothing to compare */
+ −
+ − while ((*s1 EQ *s2) OR (*s1 EQ PHB_WILD_CRD) OR (*s2 EQ PHB_WILD_CRD))
+ − {
+ − /* Character matches */
+ − cmp_len--;
+ −
+ − if (cmp_len EQ 0)
+ − return 0;
+ −
+ − if ((*s1 EQ '\0') AND (*s2 EQ '\0'))
+ − return 0;
+ −
+ − if (*s2 EQ '\0') /* Means *s1 > '\0' */
+ − return 1;
+ −
+ − if (*s1 EQ '\0') /* Means *s2 > '\0' */
+ − return -1;
+ −
+ − s1++;
+ − s2++;
+ − }
+ − /* Character does not match */
+ − if (*s1 > *s2)
+ − return 1;
+ − else
+ − return -1;
+ −
+ − }
+ −
+ −
+ − /* Implements Measure #30 */
+ − /*
+ − +------------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_alpha_num_record |
+ − +------------------------------------------------------------------------+
+ −
+ − PURPOSE : Read a given physical record from the flash based phonebook
+ − in alphabetical order Or in number sorted order
+ − */
+ −
+ − GLOBAL T_PHB_RETURN pb_sim_read_alpha_num_record (T_PHB_TYPE type,
+ − USHORT order_num,
+ − T_PHB_RECORD *entry,
+ − UBYTE sort_index)
+ − {
+ − int db_result;
+ − USHORT field_id;
+ −
+ − TRACE_FUNCTION("pb_sim_read_alpha_num_record()");
+ −
+ − /* Get Elementary file ID for the Phonebook type. */
+ − field_id = pb_sim_get_field_id(type);
+ −
+ − /* Read record from the FFS. */
+ − db_result = db_get_phy_from_idx(pbs_data.db_handle, field_id,
+ − sort_index, order_num);
+ −
+ − if(db_result > DB_OK)
+ − {
+ − return pb_sim_read_record(type, (USHORT)db_result, entry) ;
+ − }
+ −
+ − /* Check whether index is vaild. */
+ − if(db_result EQ DB_INVALID_INDEX)
+ − {
+ − return PHB_INVALID_IDX;
+ − }
+ −
+ − /*
+ − * Unable to get record from the database.
+ − * Hence returning PHB_FAIL.
+ − */
+ − return PHB_FAIL;
+ − }
+ −
+ − /* Implements Measure #167 */
+ − /*
+ − +------------------------------------------------------------------------+
+ − | PROJECT: MMI-Framework (8417) MODULE: PHB |
+ − | STATE : code ROUTINE: pb_sim_read_alpha_num_record |
+ − +------------------------------------------------------------------------+
+ −
+ − PURPOSE : Function check for extention records
+ − */
+ − LOCAL T_PHB_RETURN pb_sim_update_index (T_PHB_TYPE type,
+ − T_DB_CHANGED *rec_affected,
+ − USHORT field_id,
+ − UBYTE ext_rec_cnt)
+ − {
+ − TRACE_FUNCTION("pb_sim_update_index()");
+ −
+ − if((type NEQ LDN) AND (type NEQ LMN) AND (type NEQ LRN))
+ − {
+ − /* Update the sorted indexes. */
+ − if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX,
+ − pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+ − {
+ − return PHB_FAIL;
+ − }
+ −
+ − if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX,
+ − pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+ − {
+ − return PHB_FAIL;
+ − }
+ − }
+ − return PHB_OK;
+ − }
+ −
+ − void pb_update_cphs_mb_ext_record(void)
+ − {
+ − UBYTE i;
+ − USHORT ext_file_id;
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = SIM_EXT1;
+ −
+ − for(i =0; i< 4; i++)
+ − {
+ − if(cphs_mb_ext_record_num[i] NEQ 0xff)
+ − {
+ − db_update_ext_bitmap(pbs_data.db_handle,ext_file_id,cphs_mb_ext_record_num[i],TRUE);
+ − pb_sim_update_extn_records(ext_file_id, cphs_mb_ext_record_num[i], 1);
+ − }
+ − }
+ − }
+ − GLOBAL void pb_sim_update_ext_bitmap(UBYTE rec_num, BOOL flag)
+ − {
+ − USHORT ext_file_id;
+ −
+ − /* Get Extension file for the Phonebook type. */
+ − ext_file_id = SIM_EXT1;
+ −
+ − db_update_ext_bitmap(pbs_data.db_handle,ext_file_id,rec_num, flag);
+ − if(flag EQ TRUE)
+ − {
+ − pb_sim_update_extn_records(ext_file_id, rec_num, 1);
+ − }
+ − else
+ − {
+ − pb_sim_update_extn_records(ext_file_id, rec_num, -1);
+ − }
+ − }
+ −
+ −
+ − #endif /* #ifdef TI_PS_FFS_PHB */
+ −
+ −