FreeCalypso > hg > tcs211-l1-reconst
diff g23m/condat/ms/src/aci/phb.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/condat/ms/src/aci/phb.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,6129 @@ +/* ++----------------------------------------------------------------------------- +| 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 books. ++----------------------------------------------------------------------------- +*/ + +#ifndef TI_PS_FFS_PHB + +#include "aci_all.h" + +#include "aci_cmh.h" +#include "ati_cmd.h" +#include "aci_cmd.h" +#include "aci.h" +#include "p_sim.h" +#include "pcm.h" +#include "gdi.h" + +#include "phb.h" +#include "psa.h" +#include "psa_sim.h" +#include "psa_cc.h" +#ifdef SIM_TOOLKIT +#include "psa_sat.h" +#endif + +#ifdef FAX_AND_DATA +#include "aci_fd.h" +#endif /* of #ifdef FAX_AND_DATA */ + +#include "cmh.h" +#include "cmh_phb.h" + +#include "dti_conn_mng.h" + + +#include "cmh_sim.h" +#include "psa_mm.h" +#include "psa_ss.h" + +#ifndef _SIMULATION_ +#include "ffs\ffs.h" +#endif +/********* current define *******************************************/ +static T_PHB_EXT_CMP_FCT ext_compare_fct = NULL; /* external compare function */ +static T_PHB_CTB phb_ctb[MAX_PHONEBOOK]; +static T_PHB_AFB_ELEMENT phb_element[MAX_AFB_RECORDS]; +static T_PHB_RDM_ELEMENT phb_l_element[MAX_RDM_RECORDS]; +static UBYTE adn_bitmap[MAX_ADN_BITMAP]; +static UBYTE fdn_bitmap[MAX_FDN_BITMAP]; +static UBYTE bdn_bitmap[MAX_BDN_BITMAP]; +static UBYTE sdn_bitmap[MAX_SDN_BITMAP]; +static UBYTE ecc_bitmap[MAX_ECC_BITMAP]; +static UBYTE upn_bitmap[MAX_UPN_BITMAP]; +#ifdef PHONEBOOK_EXTENSION +static T_PHB_EXT_RECORDS phb_ext_records[MAX_PHB_EXT]; +static UBYTE ext1_bitmap[MAX_EXT1_BITMAP]; +static UBYTE ext2_bitmap[MAX_EXT2_BITMAP]; +#endif +static UBYTE sim_service_table[MAX_SRV_TBL]; /* SIM service table */ +static UBYTE data [256]; + +static SHORT ext_index; +static UBYTE max_ext_chain_reads=0; +static UBYTE phb_stat; +static UBYTE fdn_mode; +static T_ACI_CLASS fdn_classtype; +static T_ACI_CLASS fdn_input_classtype; +static UBYTE read_flag = 0; +static SHORT db_index; /* memory index for delete whole phonebook */ +static BOOL sstUpdateId = FALSE; /* SIM service table update indication (SAT) */ + +static UBYTE max_sim_LDN_records = 0; /* to ensure that every physical record is written */ + +static int cmpString (UBYTE *s1, UBYTE *s2, UBYTE len); +static int pb_cmp_phb_entry ( UBYTE *pb_tag, UBYTE pb_len, + T_ACI_PB_TEXT *search_tag ); +static int pb_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag); +static void pb_cvt_alpha_for_cmp ( UBYTE *src, + UBYTE *dst, + UBYTE len ); +static BOOL imsiFlag; + +static BOOL pause_pb_reading_while_EXT_reading = FALSE; /* pauses the loop while reading EXT-Records */ +static SHORT paused_table_id = 0; /* the paused record */ +EXTERN T_PCEER causeMod; +EXTERN SHORT causeCeer; + +#ifdef SIM_TOOLKIT +BOOL pb_update (int ref, T_SIM_FILE_UPDATE_IND *fu); +BOOL pb_update_ecc_fu (int ref, T_SIM_FILE_UPDATE_IND *fu); +#endif +void pb_copy_ecc_entry (UBYTE *ecc, UBYTE num); +void pb_read_sim_ecc ( void ); +void pb_read_eeprom_ecc (void); +T_PHB_RETURN pb_read_eeprom_req(void); +BOOL pb_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length); +void pb_read_sim_dat_cb(SHORT table_id); +void pb_read_sim_req(void); +void pb_sat_update_reset (USHORT data_id); +void pb_init_afb(void); +void pb_init_ctb (T_PHB_TYPE book); +void pb_init_element (UBYTE book); +void pb_init_l_element (UBYTE book); /*CQ16301: Added support for LND Refresh*/ + +BOOL pb_init_sync_sim(UBYTE type); +BOOL pb_prepare_sync_sim(UBYTE type, UBYTE rcd_num); +BOOL pb_sync_sim(UBYTE type, UBYTE rcd_num); +void pb_sync_sim_cb(SHORT table_id); +void pb_finish_sync_sim(void); + +void copy_phb_element ( T_PHB_RECORD *entry, T_PHB_AFB_ELEMENT phb_element ); +void copy_phb_l_element ( T_PHB_RECORD *entry, T_PHB_RDM_ELEMENT phb_l_element ); + + +LOCAL USHORT pb_get_ext_file_id (UBYTE pb_type); +LOCAL void pb_prepare_ext_data(UBYTE *number, UBYTE no_len, + UBYTE *subaddr, UBYTE sub_len, + USHORT file_id); +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_sat_update_reset | ++--------------------------------------------------------------------+ + + PURPOSE : Initialisation of phonebook field for SAT REFRESH +*/ + +void pb_sat_update_reset (USHORT data_id) +{ + TRACE_FUNCTION("pb_sat_update_reset()"); + +#ifdef SIM_TOOLKIT + switch (data_id) + { + /* ACI-ENH-17240: Subissue of CQ 16303, ADN and FDN are updated + if one of them has changed */ + case SIM_ADN: + /* + * pb_init_element (ADN); + * pb_init_ctb (ADN); + * phb_ctb[ADN].rcd_bitmap = adn_bitmap; + * memset(phb_ctb[ADN].rcd_bitmap, 0, MAX_ADN_BITMAP); + * break; + */ + case SIM_FDN: + /* + * pb_init_element (FDN); + * pb_init_ctb (FDN); + * phb_ctb[FDN].rcd_bitmap = fdn_bitmap; + * memset(phb_ctb[FDN].rcd_bitmap, 0, MAX_FDN_BITMAP); + */ + pb_init_afb(); + break; + + case SIM_BDN: + pb_init_element (BDN); + pb_init_ctb (BDN); + phb_ctb[BDN].rcd_bitmap = bdn_bitmap; + memset(phb_ctb[BDN].rcd_bitmap, 0, MAX_BDN_BITMAP); + break; + + case SIM_SDN: + pb_init_element (SDN); + pb_init_ctb (SDN); + phb_ctb[SDN].rcd_bitmap = sdn_bitmap; + memset(phb_ctb[SDN].rcd_bitmap, 0, MAX_SDN_BITMAP); + break; + + case SIM_MSISDN: + pb_init_element (UPN); + pb_init_ctb (UPN); + phb_ctb[UPN].rcd_bitmap = upn_bitmap; + memset(phb_ctb[UPN].rcd_bitmap, 0, MAX_UPN_BITMAP); + break; + + /* CQ16301: Added support for LND refresh triggered by SAT */ + case SIM_LND: + pb_init_l_element (LDN); + pb_init_ctb (LDN); + break; + + default: + break; + } +#endif +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init_ctb | ++--------------------------------------------------------------------+ + + PURPOSE : Initialisation of the phonebook control block, + but not for bitmap field +*/ + +void pb_init_ctb (T_PHB_TYPE book) +{ + TRACE_FUNCTION("pb_init_ctb()"); + + phb_ctb[book].mem = NO_PHB_ENTRY; + phb_ctb[book].alpha_len = 0; + phb_ctb[book].max_rcd = 0; + phb_ctb[book].used_rcd = 0; + phb_ctb[book].first_rcd = UNUSED_INDEX; + phb_ctb[book].first_trcd = UNUSED_INDEX; + phb_ctb[book].first_nrcd = UNUSED_INDEX; + phb_ctb[book].first_mtrcd = UNUSED_INDEX; + phb_ctb[book].first_mnrcd = UNUSED_INDEX; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init_element | ++--------------------------------------------------------------------+ + + PURPOSE : Initialisation of the saved phonebook element +*/ + +void pb_init_element (UBYTE book) +{ + SHORT index; + + TRACE_FUNCTION("pb_init_element()"); + + index = phb_ctb[book].first_rcd; + while (index NEQ UNUSED_INDEX) + { + phb_element[index].free = PHB_ELEMENT_FREE; + index = phb_element[index].next_rcd; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init_l_element | ++--------------------------------------------------------------------+ + + PURPOSE : Initialisation of the saved phonebook element (ME) +*/ + +void pb_init_l_element (UBYTE book) +{ + SHORT index; + + TRACE_FUNCTION("pb_init_l_element()"); + + index = phb_ctb[book].first_rcd; + while (index NEQ UNUSED_INDEX) + { + phb_l_element[index].free = PHB_ELEMENT_FREE; + index = phb_element[index].next_rcd; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: phb_Init | ++--------------------------------------------------------------------+ + + PURPOSE : Power-on initialisation of the phonebook module +*/ + +void phb_Init (void) +{ + fdn_mode = NO_OPERATION; + /* set fdn_classtype to default value */ + fdn_classtype = CLASS_VceDatFaxSms; + fdn_input_classtype = fdn_classtype; +#ifdef SIM_TOOLKIT + simShrdPrm.fuRef=-1; + if (!psaSAT_FURegister (pb_update)) + { + TRACE_EVENT ("FAILED to register the handler pb_update() for FU"); + } + if (!psaSAT_FURegister (pb_update_ecc_fu)) + { + TRACE_EVENT ("FAILED to register the handler pb_update_ecc_fu() for FU"); + } + +#endif +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init | ++--------------------------------------------------------------------+ + + PURPOSE : +*/ + +void pb_init (void) +{ + TRACE_FUNCTION ("pb_init()"); + + if (fdn_mode EQ NO_OPERATION) + { + { + T_PHB_TYPE i; + + /* Initiate the bitmap in control block */ + for (i=0; i<MAX_PHONEBOOK; i++) + { + pb_init_ctb(i); + + switch(i) + { + case ECC: + phb_ctb[i].rcd_bitmap = ecc_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_ECC_BITMAP); + break; + case ADN: + phb_ctb[i].rcd_bitmap = adn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_ADN_BITMAP); + break; + case FDN: + phb_ctb[i].rcd_bitmap = fdn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_FDN_BITMAP); + break; + case BDN: + phb_ctb[i].rcd_bitmap = bdn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_BDN_BITMAP); + break; + case SDN: + phb_ctb[i].rcd_bitmap = sdn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_SDN_BITMAP); + break; + case UPN: + phb_ctb[i].rcd_bitmap = upn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_UPN_BITMAP); + break; + } + } + } +#ifdef PHONEBOOK_EXTENSION + { + T_PHB_EXT_TYPE i; + /* Initiate the bitmap for the phonebook extention records */ + for (i = 0; i < MAX_PHB_EXT; i++) + { + phb_ext_records[i].mem = NO_PHB_ENTRY; + phb_ext_records[i].max_rcd = 0; + switch (i) + { + case EXT1: + phb_ext_records[i].rcd_bitmap = ext1_bitmap; + memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT1_BITMAP); /* ADN; LDN */ + break; + + case EXT2: + phb_ext_records[i].rcd_bitmap = ext2_bitmap; + memset(phb_ext_records[i].rcd_bitmap, 0, MAX_EXT2_BITMAP); /* FDN */ + break; + } + } + } +#endif + { + int i; + /* Initiate the free element */ + for (i=0; i<MAX_AFB_RECORDS; i++) + phb_element[i].free = PHB_ELEMENT_FREE; + for (i=0; i<MAX_RDM_RECORDS; i++) + phb_l_element[i].free = PHB_ELEMENT_FREE; + } + + phb_stat = PHB_UNKNOWN; + cmhPHB_StatIndication ( PHB_UNKNOWN, CME_ERR_NotPresent, TRUE ); + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init_afb | ++--------------------------------------------------------------------+ + + + PURPOSE : + +*/ + +void pb_init_afb(void) +{ + T_PHB_TYPE i; + SHORT index; + SHORT cur_index; + + TRACE_FUNCTION ("pb_init_afb()"); + + /* Initiate the bitmap in control block */ + for (i=0; i<MAX_PHONEBOOK; i++) + { + switch (i) + { + case ADN: + case FDN: + index = phb_ctb[i].first_rcd; + while (index != UNUSED_INDEX) + { + cur_index = index; + index = phb_element[cur_index].next_rcd; + phb_element[cur_index].free = PHB_ELEMENT_FREE; + phb_element[cur_index].prev_rcd = UNUSED_INDEX; + phb_element[cur_index].next_rcd = UNUSED_INDEX; + } + pb_init_ctb(i); + switch(i) + { + case ADN: + phb_ctb[i].rcd_bitmap = adn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_ADN_BITMAP); + break; + case FDN: + phb_ctb[i].rcd_bitmap = fdn_bitmap; + memset(phb_ctb[i].rcd_bitmap, 0, MAX_FDN_BITMAP); + break; + } + break; + case ADN_FDN: + pb_init_ctb(i); + break; + default: + break; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_reset | ++--------------------------------------------------------------------+ + + PURPOSE : Invalidate phonebook buffered in RAM + +*/ + +void pb_reset (void) +{ + TRACE_FUNCTION("pb_reset()"); + + pb_write_eeprom(); + + fdn_mode = NO_OPERATION; /* some more stuff may be needed */ + /* set fdn_classtype to default value */ + fdn_classtype = CLASS_VceDatFaxSms; + fdn_input_classtype = fdn_classtype; + cmhPHB_StatIndication ( PHB_UNKNOWN, CME_ERR_NotPresent, TRUE ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_create_memory | ++--------------------------------------------------------------------+ + + + PURPOSE : Find the next free entry + +*/ + +T_PHB_RETURN pb_create_memory(SHORT *index) +{ + int i; + + /* TRACE_FUNCTION("pb_create_memory()"); */ + + for (i=0; i<MAX_AFB_RECORDS; i++) + { + if (phb_element[i].free EQ PHB_ELEMENT_FREE) + { + memset ((char *)&phb_element[i].entry, 0xff, sizeof (T_AFB_RECORD)); + phb_element[i].free = PHB_ELEMENT_USED; + *index = i; + return PHB_OK; + } + } + + return PHB_FULL; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_create_l_memory | ++--------------------------------------------------------------------+ + + + PURPOSE : Find the next free entry + +*/ + +T_PHB_RETURN pb_create_l_memory(SHORT *index) +{ + SHORT i; + + /* TRACE_FUNCTION("pb_create_l_memory()"); */ + + for (i=0; i<MAX_RDM_RECORDS; i++) + { + if (phb_l_element[i].free EQ PHB_ELEMENT_FREE) + { + memset ((char *)&phb_l_element[i].entry, 0xff, sizeof (T_RDM_RECORD)); + phb_l_element[i].free = PHB_ELEMENT_USED; + *index = i; + return PHB_OK; + } + } + + return PHB_FULL; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_ecc | ++--------------------------------------------------------------------+ + + + PURPOSE : Build emergency call phonebook. + +*/ +T_PHB_RETURN pb_read_ecc (USHORT error, UBYTE ecc_len, UBYTE *sim_ecc) +{ + UBYTE *data_ptr; + int i; + + TRACE_FUNCTION ("pb_read_ecc()"); + + if (fdn_mode != NO_OPERATION) + return PHB_OK; + + /* If SIM card is not active, the emergency call numbers are read from EEPROM */ + if ( ( error EQ SIM_CAUSE_OTHER_ERROR ) + OR ( error EQ SIM_CAUSE_CARD_REMOVED) + OR ( error >= SIM_CAUSE_PARAM_WRONG AND error <= SIM_CAUSE_DRV_TEMPFAIL) ) + { + pb_read_eeprom_ecc(); + } + + /* SIM card is active, the emergency call numbers are read from SIM card */ + else + { + /* if SIM ECC data is not empty, copy SIM ECC data to phonebook */ + if ( strcmp((CHAR*)sim_ecc,"") ) + { + phb_ctb[ECC].mem = SIM_MEMORY; + data_ptr = sim_ecc; + phb_ctb[ECC].max_rcd = (SHORT)((ecc_len/3) > MAX_ECC_RCD)? MAX_ECC_RCD: ecc_len/3; + + phb_ctb[ECC].type = ECC; + phb_ctb[ECC].first_trcd = UNUSED_INDEX; + + /* Read emergency call number */ + for (i=0; i<MAX_ECC_RCD; i++) + { + pb_copy_ecc_entry (data_ptr, (UBYTE)i); + data_ptr += 3; + } + } + } + + return PHB_OK; +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim | ++----------------------------------------------------------------------+ + + + PURPOSE : SIM card informs the numbers of phonebook record. + +*/ + +BOOL pb_read_sim(USHORT data_id, UBYTE rcd_num, UBYTE len) +{ + SHORT table_id; + + TRACE_FUNCTION ("pb_read_sim()"); + + table_id = psaSIM_atbNewEntry(); + + if(table_id NEQ NO_ENTRY) + { + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_RD_REC; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].recNr = rcd_num; + if (rcd_num EQ 1) + simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; + else + simShrdPrm.atb[table_id].dataLen = len; + simShrdPrm.atb[table_id].exchData = data; + simShrdPrm.atb[table_id].rplyCB = pb_read_cb; + + simShrdPrm.aId = table_id; + + if (pause_pb_reading_while_EXT_reading EQ TRUE) /* Read request must be paused while EXT is read */ + { + paused_table_id = simShrdPrm.aId; /* save the aId for later SIM Access */ + } + else + { + if(psaSIM_AccessSIMData() < 0) + { + TRACE_EVENT("FATAL ERROR"); + return FALSE; + } + } + } + else + return FALSE; + + return TRUE; +} + + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim_ext | ++----------------------------------------------------------------------+ + + + PURPOSE : SIM card informs the numbers of phonebook record. + +*/ + +#ifdef PHONEBOOK_EXTENSION +void pb_read_sim_ext(USHORT data_id, UBYTE rcd_num) +{ + SHORT table_id; + + TRACE_FUNCTION ("pb_read_sim_ext()"); + + table_id = psaSIM_atbNewEntry(); + + if(table_id NEQ NO_ENTRY) + { + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_RD_REC; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].recNr = rcd_num; + simShrdPrm.atb[table_id].dataLen = 13; + simShrdPrm.atb[table_id].exchData = data; + simShrdPrm.atb[table_id].rplyCB = pb_read_ext_cb; + + simShrdPrm.aId = table_id; + + pause_pb_reading_while_EXT_reading = TRUE; /* Suspend further ADN reading while EXT is read */ + + if(psaSIM_AccessSIMData() < 0) + { + TRACE_EVENT("pb_read_sim_ext (): FATAL ERROR"); + } + } +} +#endif + + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_init_sync_sim | ++----------------------------------------------------------------------+ + + + PURPOSE : Sync the local LDN entries to SIM +*/ + + +BOOL pb_init_sync_sim(UBYTE type) +{ + TRACE_FUNCTION ("pb_init_sync_sim()"); + + switch (type) + { + case LDN: + break; + default: /* Only supported for LDN */ + return FALSE; + } + + if (phb_ctb[type].service == ALLOCATED_AND_ACTIVATED + AND phb_ctb[type].mem != NO_PHB_ENTRY) + { + if (max_sim_LDN_records) /* start with oldest record */ + return (pb_prepare_sync_sim(type, max_sim_LDN_records)); + } + return FALSE; +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_prepare_sync_sim | ++----------------------------------------------------------------------+ + + + PURPOSE : Sync the local LDN entries to SIM +*/ + +BOOL pb_prepare_sync_sim(UBYTE type, UBYTE rcd_num) +{ + T_PHB_RECORD entry; + T_PHB_RETURN sim_result; + UBYTE tag_len; + + TRACE_FUNCTION ("pb_prepare_sync_sim()"); + + switch (type) + { + case LDN: + break; + default: + return FALSE; + } + + memset(data, 0xFF, sizeof(data)); + + if (pb_read_phys_record( type, rcd_num, &entry) NEQ PHB_OK) + { + sim_result = pb_sync_sim(type, rcd_num); /* Write an empty record */ + } + else + { + tag_len = MINIMUM ( phb_ctb[type].alpha_len, entry.tag_len ); + memcpy(data, entry.tag, tag_len); + data[phb_ctb[type].alpha_len] = entry.len+1; +/*#if PHONEBOOK_EXTENSION*/ +#if 0 + if (entry.number[10] NEQ 0xFF) + { + data[phb_ctb[type].alpha_len] = 11; /* max. length */ + } + else + { + data[phb_ctb[type].alpha_len] = entry.len+1; + } +#else + data[phb_ctb[type].alpha_len] = entry.len+1; +#endif + data[phb_ctb[type].alpha_len+1] = entry.ton_npi; + memcpy((char *)&data[phb_ctb[type].alpha_len+2], + (char *)entry.number, 10); + data[phb_ctb[type].alpha_len+12] = entry.cc_id; + +/*#ifdef PHONEBOOK_EXTENSION*/ +#if 0 + if (entry->number[10] NEQ 0xFF) + { + file_id = pb_get_ext_file_id (type); + if (old_ext_rcd_num NEQ 0xFF) + { + /* use the old extention record */ + phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num; + } + else + { + phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (type); + } + data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num; + } + /* only number extention or subaddress could be store */ + else if (entry->subaddr[0] NEQ 0xFF) + { + file_id = pb_get_ext_file_id (type); + if (old_ext_rcd_num NEQ 0xFF) + { + /* use the old extention record */ + phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num; + } + else + { + phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (0xFF); + } + data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num; + } +#endif + sim_result = pb_sync_sim(type, rcd_num); /* Record is always 1 for cyclic files */ + +/*#ifdef PHONEBOOK_EXTENSION*/ +#if 0 + if (sim_result NEQ PHB_FAIL) + { + if (phb_element[new_index].entry.ext_rcd_num NEQ 0xFF) + { + pb_prepare_ext_data (phb_element[new_index].entry.number, + phb_element[new_index].entry.len, + phb_element[new_index].entry.subaddr, + 10, + file_id); + sim_result = pb_write_sim_ext(file_id, phb_element[new_index].entry.ext_rcd_num); + } + else if (old_ext_rcd_num NEQ 0xFF) + { + /* delete the old extention record */ + pb_rem_ext_record_flag (type, old_ext_rcd_num); + pb_prepare_ext_data (NULL, 0, NULL, 0, file_id); + sim_result = pb_write_sim_ext(SIM_EXT1, old_ext_rcd_num); + } + } +#endif /* PHONEBOOK_EXTENSION */ + } + if (sim_result NEQ PHB_FAIL) + return (TRUE); + return TRUE; +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_sync_sim | ++----------------------------------------------------------------------+ + + + PURPOSE : Sync the local LDN entries to SIM +*/ + +BOOL pb_sync_sim (UBYTE type, UBYTE rcd_num) +{ + SHORT table_id; + USHORT data_id; + + TRACE_FUNCTION ("pb_sync_sim()"); + + switch (type) + { + case LDN: + data_id = SIM_LND; + break; + default: + return FALSE; + } + + table_id = psaSIM_atbNewEntry(); + if (table_id EQ NO_ENTRY) + { + TRACE_ERROR ("pb_sync_sim(): no more table entries"); + return (FALSE); + } + + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_WR_REC; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].recNr = rcd_num; + simShrdPrm.atb[table_id].dataLen = phb_ctb[type].alpha_len + 14; + simShrdPrm.atb[table_id].exchData = data; + simShrdPrm.atb[table_id].rplyCB = pb_sync_sim_cb; + + simShrdPrm.aId = table_id; + + + if(psaSIM_AccessSIMData() < 0) + { + return (FALSE); + } + + phb_stat = PHB_BUSY; + cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, TRUE ); + + /* return (PHB_EXCT);*/ + return (TRUE); +} + + + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_sync_sim_cb | ++------------------------------------------------------------------+ + + + PURPOSE : Call back for sync phonebook in SIM card. + +*/ + +void pb_sync_sim_cb(SHORT table_id) +{ + UBYTE type; + USHORT type_id; + UBYTE rcd_num; + + TRACE_FUNCTION("pb_sync_sim_cb()"); + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR) + { + TRACE_ERROR("pb_sync_sim_cb(): error for writing"); + /* return; */ /* dont stop writing here if one record fails since must reach¬ + pb_finish_sync_sim to deactivate the sim */ + } + + /* Inform the data of record */ + switch (simShrdPrm.atb[table_id].reqDataFld) + { + case SIM_LND: /* Up to now only LDN supported */ + type = LDN; + type_id = SIM_LND; + break; + default: + TRACE_FUNCTION("pb_sync_sim_cb() invalid callback"); + return; + } + + rcd_num = simShrdPrm.atb[table_id].recNr; + if (--rcd_num) + { + pb_prepare_sync_sim(type, rcd_num); /* sync next record */ + return; + } + else /* Last record copied to SIM */ + { + pb_finish_sync_sim(); + } + return; +} + + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_finish_sync_sim | ++---------------------------------------------------------------------+ + + + PURPOSE : Call back for sync phonebook in SIM card. + +*/ + +void pb_finish_sync_sim() +{ + phb_stat = PHB_READY; + + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE ); + + pb_reset(); + pb_init(); + + simShrdPrm.synCs = SYNC_DEACTIVATE; /* This was moved from pb_sync_sim_ldn */ + psaSIM_SyncSIM(); + + return; +} + + + + + +/* ++-------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_copy_sim_entry| ++-------------------------------------------------------------------+ + + + PURPOSE : SIM card informs the numbers of phonebook record. + +*/ + +void pb_copy_sim_entry(SHORT cur_index) +{ + UBYTE *ptr; + UBYTE max_tag_len; +#ifdef PHONEBOOK_EXTENSION + USHORT file_id; +#endif + + TRACE_FUNCTION ("pb_copy_sim_entry()"); + + ptr = data; + max_tag_len = MINIMUM (phb_ctb[phb_element[cur_index].type].alpha_len, + PHB_MAX_TAG_LEN); + phb_element[cur_index].entry.tag_len = (UBYTE)pb_get_entry_len(ptr, max_tag_len); + memset(phb_element[cur_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */ + memcpy ( (char*)phb_element[cur_index].entry.tag, + (char*)ptr, + phb_element[cur_index].entry.tag_len ); + + ptr += phb_ctb[phb_element[cur_index].type].alpha_len; + phb_element[cur_index].entry.len = *(ptr++) - 1; + phb_element[cur_index].entry.ton_npi = *ptr++; + memset(phb_element[cur_index].entry.number, 0xFF, PHB_PACKED_NUM_LEN); + memcpy( (char*)phb_element[cur_index].entry.number, (char*)ptr, phb_element[cur_index].entry.len ); + ptr += 10; + phb_element[cur_index].entry.cc_id = *ptr++; + +#ifdef PHONEBOOK_EXTENSION + if (*ptr != 0xFF) /* check for extention records */ + { + file_id = pb_get_ext_file_id(phb_element[cur_index].type); + if (file_id != 0xFFFF) + { + phb_element[cur_index].entry.ext_rcd_num = (UBYTE)*ptr; + ext_index = cur_index; + max_ext_chain_reads=5; /* Limit the number of additional EXT reads per ADN record to avoid a possible endless loop */ + pb_read_sim_ext(file_id, phb_element[cur_index].entry.ext_rcd_num); + } + } + else + { + phb_element[cur_index].entry.ext_rcd_num = 0xFF; + } +#endif +} + + +/* ++-------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_copy_sim_entry| ++-------------------------------------------------------------------+ + + + PURPOSE : SIM card informs the numbers of phonebook record. + +*/ + +void pb_copy_sim_ldn_entry(SHORT cur_index) +{ + UBYTE *ptr; + UBYTE max_tag_len; +#ifdef PHONEBOOK_EXTENSION +/* USHORT file_id;*/ +#endif + + TRACE_FUNCTION ("pb_copy_sim_ldn_entry()"); + + ptr = data; + max_tag_len = MINIMUM (phb_ctb[phb_l_element[cur_index].type].alpha_len, + PHB_MAX_TAG_LEN); + phb_l_element[cur_index].entry.tag_len = (UBYTE)pb_get_entry_len(ptr, max_tag_len); + memset(phb_l_element[cur_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */ + memcpy ( (char*)phb_l_element[cur_index].entry.tag, + (char*)ptr, + phb_l_element[cur_index].entry.tag_len ); + + ptr += phb_ctb[phb_l_element[cur_index].type].alpha_len; + phb_l_element[cur_index].entry.len = *(ptr++) - 1; + phb_l_element[cur_index].entry.ton_npi = *ptr++; + memset(phb_l_element[cur_index].entry.number, 0xFF, PHB_PACKED_NUM_LEN); + memcpy( (char*)phb_l_element[cur_index].entry.number, (char*)ptr, 10 ); + ptr += 10; + phb_l_element[cur_index].entry.cc_id = *ptr++; + + phb_l_element[cur_index].entry.year = 0xff; /* This is not on SIM */ + phb_l_element[cur_index].entry.month = 0xff; + phb_l_element[cur_index].entry.day = 0xff; + phb_l_element[cur_index].entry.hour = 0xff; + phb_l_element[cur_index].entry.minute = 0xff; + phb_l_element[cur_index].entry.second = 0xff; + +/*#ifdef PHONEBOOK_EXTENSION */ +#if 0 + if (*ptr != 0xFF) /* check for extention records */ + { + file_id = pb_get_ext_file_id(phb_l_element[cur_index].type); + if (file_id != 0xFFFF) + { + phb_l_element[cur_index].entry.ext_rcd_num = (UBYTE)*ptr; + ext_index = cur_index; + pb_read_sim_ext(file_id, phb_l_element[cur_index].entry.ext_rcd_num); + } + } + else + { + phb_l_element[cur_index].entry.ext_rcd_num = 0xFF; + } +#endif +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim_record | ++---------------------------------------------------------------------+ + + + PURPOSE : Build emergency call phonebook. + +*/ + +T_PHB_RETURN pb_read_sim_record(UBYTE type, USHORT type_id, UBYTE rcd_num) +{ + SHORT index; + UBYTE n,m; + + /* TRACE_FUNCTION ("pb_read_sim_record()");*/ + + if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd) + { + TRACE_FUNCTION("Used rcd full!"); + return PHB_FULL; + } + + if (type NEQ LDN) + { + /* search a free element in phonebook element table */ + if (pb_create_memory(&index) NEQ PHB_OK) + { + TRACE_FUNCTION("Memory full"); + pb_read_eeprom_req(); + return PHB_FULL; + } + + phb_ctb[type].used_rcd++; + n = (UBYTE)(rcd_num-1)/8; + m = (rcd_num-1)%8; + phb_ctb[type].rcd_bitmap[n] |= 0x01 << m; + phb_element[index].type = type; + phb_element[index].entry.index = rcd_num; + + pb_copy_sim_entry(index); + + pb_record_sort(index); + pb_alpha_sort(index); + pb_num_sort(index); + + if ((type EQ ADN) OR (type EQ FDN)) + { + pb_malpha_sort(index); + pb_mnum_sort(index); + } + } + else /* special handling for LDN entries from SIM */ + { + if (pb_create_l_memory(&index) NEQ PHB_OK) + { + TRACE_FUNCTION("Memory full"); + pb_read_eeprom_req(); + return PHB_OK; + } + phb_ctb[type].used_rcd++; + phb_l_element[index].type = type; + phb_l_element[index].entry.index = rcd_num; + + pb_copy_sim_ldn_entry(index); + + pb_l_record_sort(index); + /* pb_l_alpha_sort(index);*//* not possible with RDM Structure */ + /* pb_l_num_sort(index);*/ + } + + return PHB_OK; +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT: MODULE: PHB | +| STATE : code ROUTINE: pb_get_ext_file_id | ++---------------------------------------------------------------------+ + + + PURPOSE : Find and gives the extention SIM file ID for the + phonebook entry. + +*/ +#ifdef PHONEBOOK_EXTENSION +LOCAL USHORT pb_get_ext_file_id (UBYTE pb_type) +{ + switch (pb_type) + { + case 0xFF: + case ADN: + case LDN: + return (SIM_EXT1); + + case FDN: + return (SIM_EXT2); + + case SDN: + return (SIM_EXT3); + + case BDN: + return (SIM_EXT4); + + default: + TRACE_ERROR ("pb_get_free_ext_record(): invalid type"); + return (0xFFFF); + } +} + + +/* ++-----------------------------------------------------------------------+ +| PROJECT: MODULE: PHB | +| STATE : code ROUTINE: pb_rem_ext_record_flag | ++-----------------------------------------------------------------------+ + + + PURPOSE : Removes the flag for the extention record. + +*/ + +LOCAL void pb_rem_ext_record_flag (UBYTE pb_type, UBYTE rcd_num) +{ + UBYTE *rcd_bitmap; + UBYTE pos, bit, len; + + switch (pb_type) + { + case 0xFF: + case ADN: + rcd_bitmap = phb_ext_records[EXT1].rcd_bitmap; + len = MAX_EXT1_BITMAP; + break; + + case FDN: + rcd_bitmap = phb_ext_records[EXT2].rcd_bitmap; + len = MAX_EXT2_BITMAP; + break; + + case BDN: + case SDN: + default: + TRACE_ERROR ("pb_rem_free_ext_record(): invalid type"); + return; + } + + pos = (UBYTE)(rcd_num - 1) / 8; + bit = (rcd_num - 1) % 8; + + rcd_bitmap[pos] &= (UBYTE)(~(1u << bit)); + +} + + +/* ++-------------------------------------------------------------------------+ +| PROJECT: MODULE: PHB | +| STATE : code ROUTINE: pb_rem_ext_record_number | ++-------------------------------------------------------------------------+ + + + PURPOSE : Gives the extention record number for the phonebook entry. + +*/ + +LOCAL UBYTE pb_get_ext_record_number (UBYTE pb_type) +{ + UBYTE *rcd_bitmap; + UBYTE len, pos, bit, rcd_num; + + switch (pb_type) + { + case 0xFF: + case ADN: + rcd_bitmap = phb_ext_records[EXT1].rcd_bitmap; + len = MAX_EXT1_BITMAP; + break; + + case FDN: + rcd_bitmap = phb_ext_records[EXT2].rcd_bitmap; + len = MAX_EXT2_BITMAP; + break; + + case BDN: + case SDN: + default: + TRACE_ERROR ("pb_get_free_ext_number(): invalid type"); + return (0xFF); + } + + for (pos = 0; pos < len; pos++) + { + if (~(rcd_bitmap[pos])) + { + bit = 0; + while (rcd_bitmap[pos] & (1 << bit)) + { + bit++; + if (bit EQ 7) + { + TRACE_ERROR ("pb_get_free_ext_number (): NOT POSSIBLE"); + return (0); + } + } + rcd_bitmap[pos] |= (1 << bit); + rcd_num = (pos * 8) + bit + 1; + return (rcd_num); + } + } + TRACE_ERROR ("pb_get_free_ext_record(): no more extention records free"); + + return (0xFF); +} + + +/* ++-----------------------------------------------------------------------+ +| PROJECT: MODULE: PHB | +| STATE : code ROUTINE: pb_read_ext_records | ++-----------------------------------------------------------------------+ + + + PURPOSE : Store the extention record flag and read the next record. + +*/ + +LOCAL void pb_read_ext_records (T_PHB_EXT_TYPE type, + USHORT sim_id, + SHORT table_id) +{ + UBYTE rcd_num; + UBYTE n, m; + + rcd_num = simShrdPrm.atb[table_id].recNr; + + if (rcd_num EQ 1) + { + phb_ext_records[type].max_rcd = simShrdPrm.atb[table_id].recMax; + } + + /* If this record is not empty ==> set used flag */ + if (data[0] NEQ 0xFF) + { + n = (UBYTE)(rcd_num - 1) / 8; + m = (rcd_num - 1) % 8; + phb_ext_records[type].rcd_bitmap[n] |= (0x01 << m); + } + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + if (rcd_num < phb_ext_records[type].max_rcd) + { + pb_read_sim(sim_id, ++rcd_num, simShrdPrm.atb[table_id].dataLen); + } + else + { + pb_read_sim_req(); + } +} +#endif + +/* ++---------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_cb | ++---------------------------------------------------------------------+ + + + PURPOSE : read sim callback function + +*/ +void pb_read_cb(SHORT table_id) +{ + UBYTE type = NOT_PRESENT_8BIT; + USHORT type_id; + UBYTE rcd_num; /* record number */ + + TRACE_FUNCTION ("pb_read_cb()"); + + /* Inform the data of record */ + switch (simShrdPrm.atb[table_id].reqDataFld) + { +#ifdef PHONEBOOK_EXTENSION + case SIM_EXT1: + pb_read_ext_records (EXT1, SIM_EXT1, table_id); + return; + + case SIM_EXT2: + pb_read_ext_records (EXT2, SIM_EXT2, table_id); + return; +#endif + case SIM_ADN: + type = ADN; + type_id = SIM_ADN; + break; + + case SIM_FDN: + type = FDN; + type_id = SIM_FDN; + break; + + case SIM_LND: /* Support for SIM_LDN */ + type = LDN; /* Caution: different identifiers LDN and LND */ + type_id = SIM_LND; + break; + + case SIM_SDN: + type = SDN; + type_id = SIM_SDN; + break; + + case SIM_BDN: + type = BDN; + type_id = SIM_BDN; + break; + + case SIM_MSISDN: + type = UPN; + type_id = SIM_MSISDN; + break; + + default: + TRACE_ERROR ("Invalid reqDataFld!"); + return; + + } + TRACE_EVENT_P1("Callback of SIM reading Phonebook: %d", type); + + rcd_num = simShrdPrm.atb[table_id].recNr; + + + if (rcd_num EQ 1) + { + if (type EQ LDN) + { + /* remember physical count for writing of correct number of LND on CFUN=0 */ + max_sim_LDN_records = simShrdPrm.atb[table_id].recMax; + } + phb_ctb[type].alpha_len = simShrdPrm.atb[table_id].dataLen - 14; + phb_ctb[type].max_rcd = simShrdPrm.atb[table_id].recMax; + } + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + /* + * workaround for invalid phonebook entries (the entire entry is filled with 0x00) + * this entries have been received which a very slow SIM + * check if the Length of BCD number/SSC contents is 0x00 then discard + */ + + /* If this record is not empty, this record is written in phonebook. */ + if((phb_ctb[type].max_rcd NEQ 0) + AND ((*data NEQ 0xff) OR (*(data + phb_ctb[type].alpha_len + 2) NEQ 0xff)) + AND (*(data + phb_ctb[type].alpha_len) NEQ 0x00)) + { + if (pb_read_sim_record(type, type_id, rcd_num) EQ PHB_FULL) + { +#ifdef SIM_TOOLKIT + if (simShrdPrm.fuRef >= 0) + { + psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCC_ADD); + } +#endif + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE ); + return; + } + } + + if (rcd_num < phb_ctb[type].max_rcd) + { + pb_read_sim(type_id, ++rcd_num, simShrdPrm.atb[table_id].dataLen); + } + else + pb_read_sim_req(); +} + + + + +/* ++---------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_nibblecopy | ++---------------------------------------------------------------------+ + + + PURPOSE : appends a packed BCD number to an existing entry. +*/ + +#ifdef PHONEBOOK_EXTENSION +int pb_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count) +{ + + int i; + int nibble; + + int destnibble=destlen*2; + 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 */ +} +#endif + + +/* ++---------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_ext_cb | ++---------------------------------------------------------------------+ + + + PURPOSE : read sim callback function + +*/ + +#ifdef PHONEBOOK_EXTENSION +void pb_read_ext_cb(SHORT table_id) +{ + USHORT type_id; + /* UBYTE buf[11];*/ + UBYTE data_len; + UBYTE data_type; + + TRACE_FUNCTION ("pb_read_ext_cb()"); + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR) + { + TRACE_EVENT_P1 ("SIM returned error 0x%04X", simShrdPrm.atb[table_id].errCode); + } + else + { + type_id = simShrdPrm.atb[table_id].reqDataFld; + + /* If this extension record is not empty, it is written in phonebook. */ + data_type = data[0]; + 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 (phb_element[ext_index].entry.subaddr[sa_len] EQ 0xFF) + break; + else if ((phb_element[ext_index].entry.subaddr[sa_len] & 0xF0) EQ 0xF0) + { + sa_len++; + break; + } + else + sa_len++; + } + + pb_nibblecopy (phb_element[ext_index].entry.subaddr, + sa_len, + data + 2, + data_len); + } + break; + + case 2: /* Additional data */ + phb_element[ext_index].entry.len = + pb_nibblecopy (phb_element[ext_index].entry.number, + phb_element[ext_index].entry.len, + data + 2, + data_len); + break; + + default: /* unknown type */ + break; + } + + if (data[12] != 0xFF) /* check if a further EXT entry exists */ + { + if (max_ext_chain_reads) /* limit reached? */ + { + max_ext_chain_reads--; + pb_read_sim_ext(type_id, data[12]); + return; + } + } + } + + /* Continue reading the last by EXT interrupted phonebook */ + pause_pb_reading_while_EXT_reading = FALSE; + + if (paused_table_id) + { + simShrdPrm.aId = paused_table_id; + paused_table_id = 0; + if(psaSIM_AccessSIMData() < 0) + { + TRACE_EVENT("FATAL ERROR"); + return; + } + } +} +#endif + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_eeprom_req | ++--------------------------------------------------------------------+ + + + PURPOSE : Request to build phonebook. + +*/ +T_PHB_RETURN pb_read_eeprom_req(void) +{ + UBYTE version; + UBYTE i, n, m; + SHORT index; + USHORT max_rcd; + EF_UPN *efupn; + + TRACE_FUNCTION ("pb_read_eeprom_req()"); + + phb_ctb[ADN_FDN].mem = SIM_MEMORY; + phb_ctb[ADN_FDN].type = ADN_FDN; + if (phb_ctb[ADN].alpha_len) + phb_ctb[ADN_FDN].alpha_len = phb_ctb[ADN].alpha_len; + else + phb_ctb[ADN_FDN].alpha_len = phb_ctb[FDN].alpha_len; + + phb_ctb[ADN_FDN].max_rcd = phb_ctb[ADN].max_rcd + phb_ctb[FDN].max_rcd; + phb_ctb[ADN_FDN].used_rcd = phb_ctb[ADN].used_rcd + phb_ctb[FDN].used_rcd; + + if (read_flag) + { + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE ); + return PHB_OK; + } + + /* Read Last Dialing Numbers */ + + if (phb_ctb[LDN].mem EQ NO_PHB_ENTRY) /* No phonebook loaded from SIM? */ + { + phb_ctb[LDN].mem = TE_MEMORY; + phb_ctb[LDN].type = LDN; + phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3; + phb_ctb[LDN].used_rcd = 0; + phb_ctb[LDN].first_rcd = UNUSED_INDEX; + phb_ctb[LDN].first_trcd = UNUSED_INDEX; + phb_ctb[LDN].first_nrcd = UNUSED_INDEX; + phb_ctb[LDN].first_mtrcd = UNUSED_INDEX; + phb_ctb[LDN].first_mnrcd = UNUSED_INDEX; + } + else + { + /* either: */ + /* phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3;*//* adjust in case SIM_max_record was smaller than PCM_max_rcd */ + /* or: */ + ; /* use max_rcd as read from SIM. */ + + } + if (imsiFlag EQ FALSE ) /* SIM has changed? */ + { + memset (data, 0xFF, SIZE_EF_LDN); + i=0; + while (i < NR_EF_LDN) + { + if (pcm_WriteRecord((UBYTE *)EF_LDN_ID, /* Wipe entire LDN-PCM */ + (USHORT)(i+1), + SIZE_EF_LDN, + data) NEQ DRV_OK) + break; + i++; + } + } + else + { /* Merge timestamp with existing SIM-entries */ + BOOL all_records_match = TRUE; + SHORT records_from_sim = phb_ctb[LDN].used_rcd; /* =0 in case of no records from SIM read */ + EF_LDN *p = (EF_LDN *)data; + + index = phb_ctb[LDN].first_rcd; + for (i=0; i<(UBYTE)phb_ctb[LDN].max_rcd; i++) + { + if ((i+1) > NR_EF_LDN) + break; /* end of phonebook */ + if (pcm_ReadRecord((UBYTE *)EF_LDN_ID, + (USHORT)(i+1), + SIZE_EF_LDN, + (UBYTE *)&data[0], + &version, + &max_rcd) NEQ DRV_OK) + break; /* read error */ + else + { + if (p->len NEQ 0 AND p->len NEQ 0xFF) + { + if ((i+1) <= records_from_sim) + { + if (index EQ UNUSED_INDEX) + { + all_records_match = FALSE; + break; + } + if ( !memcmp((char *)phb_l_element[index].entry.number, (char *)&p->dldNum, 10) + AND phb_l_element[index].entry.ton_npi EQ p->numTp + AND phb_l_element[index].entry.len EQ p->len + AND phb_l_element[index].entry.cc_id EQ p->ccp) /* Number matches? */ + { + pb_copy_ldn_record(index, 0); /* then update the record with Timestamps and cc_id from PCM */ + } + else + { + all_records_match = FALSE; /* one (or more) record failed */ + break; /* stop processing of further records */ + } + index = phb_l_element[index].next_rcd; + } + else /* PCM has more entries than on SIM */ + { + /* search a free element in phonebook element table */ + if (pb_create_l_memory(&index) NEQ PHB_OK) + return PHB_FULL; + + phb_ctb[LDN].used_rcd++; + phb_l_element[index].type = LDN; + phb_l_element[index].entry.index = i+1; + + pb_copy_ldn_record((SHORT)index, 0); + pb_l_record_sort(index); + } + } + } + } + if (all_records_match NEQ TRUE) /* some elements did not match */ + { + index = phb_ctb[LDN].first_rcd; + for (i=0; i<phb_ctb[LDN].used_rcd; i++) + { + if (index EQ UNUSED_INDEX) + { + break; + } + phb_l_element[index].entry.year = + phb_l_element[index].entry.month = + phb_l_element[index].entry.day = + phb_l_element[index].entry.hour = + phb_l_element[index].entry.minute = + phb_l_element[index].entry.second = 0xFF; /* remove previous merged data from PCM */ + index = phb_l_element[index].next_rcd; + } + } + } + + + /* Read Last received Numbers from EEPROM */ + phb_ctb[LRN].mem = TE_MEMORY; + phb_ctb[LRN].type = LRN; + phb_ctb[LRN].max_rcd = MAX_RDM_RECORDS/3; + phb_ctb[LRN].used_rcd = 0; + phb_ctb[LRN].first_rcd = UNUSED_INDEX; + phb_ctb[LRN].first_trcd = UNUSED_INDEX; + phb_ctb[LRN].first_nrcd = UNUSED_INDEX; + phb_ctb[LRN].first_mtrcd = UNUSED_INDEX; + phb_ctb[LRN].first_mnrcd = UNUSED_INDEX; + + if (imsiFlag EQ FALSE ) + { + memset (data, 0xFF, SIZE_EF_LRN); + i=0; + while (i < NR_EF_LRN) + { + if (pcm_WriteRecord((UBYTE *)EF_LRN_ID, /* Wipe entire LRN-PCM */ + (USHORT)(i+1), + SIZE_EF_LRN, + data) NEQ DRV_OK) + break; + i++; + } + } + else + { + EF_LRN *p = (EF_LRN *)data; + for (i=0; i<(UBYTE)phb_ctb[LRN].max_rcd; i++) + { + if ((i+1) > NR_EF_LRN) + break; + if (pcm_ReadRecord((UBYTE *)EF_LRN_ID, + (USHORT)(i+1), + SIZE_EF_LRN, + (UBYTE *)&data[0], + &version, + &max_rcd) NEQ DRV_OK) + break; + else + { + if (p->len NEQ 0 AND p->len NEQ 0xFF) + { + /* search a free element in phonebook element table */ + if (pb_create_l_memory(&index) NEQ PHB_OK) + return PHB_FULL; + + phb_ctb[LRN].used_rcd++; + phb_l_element[index].type = LRN; + phb_l_element[index].entry.index = i+1; + + pb_copy_lrn_record(index, 0); + pb_l_record_sort(index); + } + } + } + } + + /* Read Last missed Numbers from EEPROM */ + phb_ctb[LMN].mem = TE_MEMORY; + phb_ctb[LMN].type = LMN; + phb_ctb[LMN].max_rcd = MAX_RDM_RECORDS/3; + phb_ctb[LMN].used_rcd = 0; + phb_ctb[LMN].first_rcd = UNUSED_INDEX; + phb_ctb[LMN].first_trcd = UNUSED_INDEX; + phb_ctb[LMN].first_nrcd = UNUSED_INDEX; + phb_ctb[LMN].first_mtrcd = UNUSED_INDEX; + phb_ctb[LMN].first_mnrcd = UNUSED_INDEX; + + if (imsiFlag EQ FALSE ) + { + memset (data, 0xFF, SIZE_EF_LMN); + i=0; + while (i < NR_EF_LMN) + { + if (pcm_WriteRecord((UBYTE *)EF_LMN_ID, /* Wipe entire LMN-PCM */ + (USHORT)(i+1), + SIZE_EF_LMN, + data) NEQ DRV_OK) + break; + i++; + } + } + else + { + EF_LMN *p = (EF_LMN *)data; + for (i=0; i<(UBYTE)phb_ctb[LMN].max_rcd; i++) + { + if ((i+1) > NR_EF_LMN) + break; + if (pcm_ReadRecord((UBYTE *)EF_LMN_ID, + (USHORT)(i+1), + SIZE_EF_LMN, + (UBYTE *)&data[0], + &version, + &max_rcd) NEQ DRV_OK) + break; + else + { + if (p->len NEQ 0 AND p->len NEQ 0xFF) + { + /* search a free element in phonebook element table */ + if (pb_create_l_memory(&index) NEQ PHB_OK) + return PHB_FULL; + + phb_ctb[LMN].used_rcd++; + phb_l_element[index].type = LMN; + phb_l_element[index].entry.index = i+1; + + pb_copy_lmn_record(index, 0); + pb_l_record_sort(index); + } + } + } + } + + if (phb_ctb[UPN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[UPN].mem = TE_MEMORY; + phb_ctb[UPN].type = UPN; + phb_ctb[UPN].max_rcd = NR_EF_UPN; + phb_ctb[UPN].used_rcd = 0; + phb_ctb[UPN].first_rcd = UNUSED_INDEX; + phb_ctb[UPN].first_trcd = UNUSED_INDEX; + phb_ctb[UPN].first_nrcd = UNUSED_INDEX; + phb_ctb[UPN].first_mtrcd = UNUSED_INDEX; + phb_ctb[UPN].first_mnrcd = UNUSED_INDEX; + + for (i=0; i<NR_EF_UPN; i++) + { + if (pcm_ReadRecord((UBYTE *)EF_UPN_ID, + (USHORT)(i+1), + SIZE_EF_UPN, + (UBYTE *)&data[0], + &version, + &max_rcd) NEQ DRV_OK) + { + phb_ctb[UPN].mem = NO_PHB_ENTRY; + phb_ctb[UPN].max_rcd = 0; + } + else + { + efupn = (EF_UPN *)&data[0]; + if (efupn->usrNum[0] NEQ 0xff) + { + /* search a free element in phonebook element table */ + if (pb_create_memory(&index) NEQ PHB_OK) + return PHB_FULL; + + phb_ctb[UPN].used_rcd++; + n = (UBYTE)i/8; + m = i%8; + phb_ctb[UPN].rcd_bitmap[n] |= 0x01 << m; + + phb_element[index].type = UPN; + phb_element[index].entry.index = i+1; + + /* copy record */ + memset(phb_element[index].entry.tag, 0xFF, sizeof(phb_element[index].entry.tag)); + memset(phb_element[index].entry.number, 0xFF, sizeof(phb_element[index].entry.number)); + memcpy(phb_element[index].entry.tag, + efupn->alphId, + 10*sizeof(UBYTE)); + phb_element[index].entry.tag_len = pb_get_entry_len(efupn->alphId, 10); + phb_element[index].entry.len = efupn->len; + phb_element[index].entry.ton_npi = efupn->numTp; + memcpy(phb_element[index].entry.number, + efupn->usrNum, + 10*sizeof(UBYTE)); + phb_element[index].entry.cc_id = efupn->ccp; + + pb_record_sort(index); + pb_alpha_sort(index); + pb_num_sort(index); + } + } + } + } + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, TRUE ); + read_flag = 1; + return PHB_OK; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim_req | ++--------------------------------------------------------------------+ + + +PURPOSE : Request to build phonebook. + +*/ + +void pb_read_sim_req(void) +{ + UBYTE serv_stat; + + TRACE_FUNCTION("pb_read_sim_req()"); + + /* Read Fixed Dialing Numbers from SIM card */ + if ((serv_stat = pb_ssc(SRV_FDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ctb[FDN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[FDN].mem = SIM_MEMORY; + phb_ctb[FDN].type = FDN; + phb_ctb[FDN].service = serv_stat; + pb_read_sim(SIM_FDN, 1, NOT_PRESENT_8BIT); + return; + } + + if (read_flag) + { + pb_read_eeprom_req(); + return; + } + + /* Read MSISDN from SIM card */ + if ((serv_stat = pb_ssc(SRV_MSISDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ctb[UPN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[UPN].mem = SIM_MEMORY; + phb_ctb[UPN].type = UPN; + phb_ctb[UPN].service = serv_stat; + pb_read_sim(SIM_MSISDN, 1, NOT_PRESENT_8BIT); + return; + } + + /* Read Barred Dialing Numbers from SIM card */ + if ((serv_stat = pb_ssc(SRV_BDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ctb[BDN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[BDN].mem = SIM_MEMORY; + phb_ctb[BDN].type = BDN; + phb_ctb[BDN].service = serv_stat; + pb_read_sim(SIM_BDN, 1, NOT_PRESENT_8BIT); + return; + } + + /* Read Service Dialing Numbers from SIM card */ + if ((serv_stat = pb_ssc(SRV_SDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ctb[SDN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[SDN].mem = SIM_MEMORY; + phb_ctb[SDN].type = SDN; + phb_ctb[SDN].service = serv_stat; + pb_read_sim(SIM_SDN, 1, NOT_PRESENT_8BIT); + return; + } + + + /* Read Last Numbers Dialed from SIM card */ + if ((serv_stat = pb_ssc(SRV_LDN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ctb[LDN].mem EQ NO_PHB_ENTRY) + { + phb_ctb[LDN].mem = TE_MEMORY; + phb_ctb[LDN].type = LDN; + phb_ctb[LDN].service = serv_stat; + phb_ctb[LDN].max_rcd = MAX_RDM_RECORDS/3; + phb_ctb[LDN].used_rcd = 0; + phb_ctb[LDN].first_rcd = UNUSED_INDEX; + phb_ctb[LDN].first_trcd = UNUSED_INDEX; + phb_ctb[LDN].first_nrcd = UNUSED_INDEX; + phb_ctb[LDN].first_mtrcd = UNUSED_INDEX; + phb_ctb[LDN].first_mnrcd = UNUSED_INDEX; + pb_read_sim(SIM_LND, 1, NOT_PRESENT_8BIT); + return; + } + + +#ifdef PHONEBOOK_EXTENSION + /* Read Ext1 Records from SIM card */ + if ((serv_stat = pb_ssc(SRV_EXT1,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ext_records[EXT1].mem EQ NO_PHB_ENTRY) + { + TRACE_EVENT ("Start reading EXT1"); + phb_ext_records[EXT1].mem = SIM_MEMORY; + pb_read_sim(SIM_EXT1, 1, NOT_PRESENT_8BIT); + return; + } + + /* Read Ext2 Records from SIM card */ + if ((serv_stat = pb_ssc(SRV_EXT2,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED + AND phb_ext_records[EXT2].mem EQ NO_PHB_ENTRY) + { + TRACE_EVENT ("Start reading EXT2"); + phb_ext_records[EXT2].mem = SIM_MEMORY; + pb_read_sim(SIM_EXT2, 1, NOT_PRESENT_8BIT); + return; + } +#endif + + /* Read phonebook from EEPROM */ + pb_read_eeprom_req(); + +#ifdef SIM_TOOLKIT + if (simShrdPrm.fuRef >= 0) + { + psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCC_ADD); + } +#endif + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_build_req | ++--------------------------------------------------------------------+ + + PURPOSE : Request to build phonebook. + +*/ + +void pb_build_req(T_SIM_MMI_INSERT_IND *sim_mmi_insert_ind) +{ + UBYTE simIMSI[MAX_IMSI_LEN+1]; + UBYTE pcmIMSI[MAX_IMSI_LEN+1]; + EF_IMSI imsi; + UBYTE version; + + #ifndef _SIMULATION_ + UBYTE classFDN = (UBYTE) CLASS_None; + T_FFS_RET ret_ffs; /* FFS handle */ + #endif + + TRACE_FUNCTION ("pb_build_req()"); + + if (fdn_mode EQ NO_OPERATION) + { + /* Read SIM service table from SIM card */ + memcpy(sim_service_table, sim_mmi_insert_ind -> sim_serv, MAX_SRV_TBL); + + /* Compare IMSI field between SIM and PCM */ + imsiFlag = FALSE; + psaSIM_decodeIMSI (sim_mmi_insert_ind->imsi_field.field, + sim_mmi_insert_ind->imsi_field.c_field, + (char *)simIMSI); + + if (pcm_ReadFile((UBYTE *) EF_IMSI_ID,SIZE_EF_IMSI, + (UBYTE *) &imsi, &version) EQ PCM_OK) + { + psaSIM_decodeIMSI (imsi.IMSI, imsi.len, (char *)pcmIMSI); + if (!strcmp((char *)simIMSI, (char *)pcmIMSI)) + imsiFlag = TRUE; + else + { + /* write the IMSI in PCM */ + imsi.len = sim_mmi_insert_ind->imsi_field.c_field; + memcpy(imsi.IMSI, sim_mmi_insert_ind->imsi_field.field, MAX_IMSI-1); + pcm_WriteFile((UBYTE *) EF_IMSI_ID,SIZE_EF_IMSI, + (UBYTE *) &imsi); + } + } + + switch (sim_mmi_insert_ind -> func) + { + case SIM_ADN_ENABLED: + case SIM_ADN_BDN_ENABLED: + fdn_mode = FDN_DISABLE; + break; + case SIM_FDN_ENABLED: + case SIM_FDN_BDN_ENABLED: + fdn_mode = FDN_ENABLE; + #ifndef _SIMULATION_ + /* read last fdn_classtype from FFS */ + ret_ffs = ffs_fread("/mmi/fdnClassType", + &classFDN, + sizeof(classFDN)); + + if(!(ret_ffs < 1)) /* successful read */ + { + /* only these two classes are currently supported */ + if ( classFDN EQ (UBYTE) CLASS_VceDatFax OR + classFDN EQ (UBYTE) CLASS_VceDatFaxSms ) + { + fdn_classtype = classFDN; + fdn_input_classtype = fdn_classtype; + } + } + #endif + break; + default: + fdn_mode = NO_OPERATION; + break; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_start_build | ++--------------------------------------------------------------------+ + + PURPOSE : Start reading the phonebook. + +*/ + +T_PHB_RETURN pb_start_build (BOOL unchanged) +{ + UBYTE serv_stat; + + TRACE_FUNCTION ("pb_start_build()"); + + read_flag = 0; + phb_stat = PHB_BUSY; + cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, TRUE ); + + /* Read Abbreviated Dialing Numbers */ + if ((serv_stat = pb_ssc(SRV_ADN,sim_service_table)) EQ ALLOCATED_AND_ACTIVATED) + { + if (fdn_mode EQ FDN_ENABLE) + { + pb_read_sim_req(); + return PHB_OK; + } + + if ( phb_ctb[ADN].mem EQ NO_PHB_ENTRY ) + { + phb_ctb[ADN].mem = SIM_MEMORY; + phb_ctb[ADN].type = ADN; + phb_ctb[ADN].service = serv_stat; + + pb_read_sim(SIM_ADN, 1, NOT_PRESENT_8BIT); + } + else + pb_read_sim_req(); + } + + else + { + pb_read_sim_req(); + } + return PHB_OK; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_update | ++--------------------------------------------------------------------+ + + PURPOSE : Phonebook update on File Change Notification. + +*/ + +#ifdef SIM_TOOLKIT +BOOL pb_update (int ref, T_SIM_FILE_UPDATE_IND *fu) +{ + BOOL found = FALSE; + int i; + + TRACE_FUNCTION ("pb_update ()"); + + for (i = 0; i < (int)fu->val_nr; i++) + { + if (fu->file_id[i] EQ SIM_ADN OR /* the extension datafields */ + fu->file_id[i] EQ SIM_FDN OR /* have to be added, when*/ + fu->file_id[i] EQ SIM_BDN OR /* they are really used */ + fu->file_id[i] EQ SIM_SDN OR + fu->file_id[i] EQ SIM_MSISDN OR + fu->file_id[i] EQ SIM_SST OR + fu->file_id[i] EQ SIM_LND) /*CQ16301: Added support for LND refresh */ + { + found = TRUE; + + /* when SIM service table is changed, the all SIM-phonebooks + will be updated. */ + if (fu->file_id[i] EQ SIM_SST) + { + sstUpdateId = TRUE; + break; + } + + pb_sat_update_reset(fu->file_id[i]); + } + } + + if (found) + { + simShrdPrm.fuRef = ref; + if (sstUpdateId) + { + sstUpdateId = FALSE; + + /* Update SIM service table */ + if (pb_read_sim_dat(SIM_SST, NOT_PRESENT_8BIT, (UBYTE)256) EQ FALSE ) + pb_start_build (FALSE); + } + else + pb_start_build (FALSE); + return FALSE; + } + else + { + simShrdPrm.fuRef = -1; /* no update needed */ + return TRUE; + } +} +#endif + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_ssc | ++--------------------------------------------------------------------+ + + PURPOSE : Check SIM service status. + +*/ + +UBYTE pb_ssc (UBYTE nr, UBYTE * serv_table) +{ + TRACE_FUNCTION ("pb_ssc()"); + + if (nr > MAX_SRV_TBL*4) + { + TRACE_ERROR ("serv_table overflow in pb_ssc()"); + return NO_ALLOCATED; + } + + /* SDN and BDN are not used */ + /* if ((nr EQ 18) || (nr EQ31)) */ + /* return(NO_ALLOCATED);*/ + + return ( *(serv_table+(nr-1)/4) >> (((nr-1)&3)*2) & 0x03); +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_record_sort | ++---------------------------------------------------------------------+ + + PURPOSE : + +*/ + +void pb_record_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag; + + /* TRACE_FUNCTION ("pb_record_sort()"); */ + + if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1) + { + phb_element[cur_index].prev_rcd = UNUSED_INDEX; + phb_element[cur_index].next_rcd = UNUSED_INDEX; + phb_ctb[phb_element[cur_index].type].first_rcd = cur_index; + } + else + { + flag = 0; + + ref_index = phb_ctb[phb_element[cur_index].type].first_rcd; + phb_ctb[phb_element[cur_index].type].first_rcd = cur_index; + + phb_element[cur_index].prev_rcd = UNUSED_INDEX; + phb_element[cur_index].next_rcd = ref_index; + phb_element[ref_index].prev_rcd = cur_index; + + while (ref_index NEQ UNUSED_INDEX) + { + if (phb_element[cur_index].entry.index > phb_element[ref_index].entry.index) + { + ptr_index = phb_element[ref_index].next_rcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].prev_rcd = cur_index; + phb_element[cur_index].next_rcd = ptr_index; + + ptr_index = phb_element[cur_index].prev_rcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].next_rcd = ref_index; + + phb_element[ref_index].prev_rcd = phb_element[cur_index].prev_rcd; + phb_element[ref_index].next_rcd = cur_index; + phb_element[cur_index].prev_rcd = ref_index; + + /* set the first record in control block */ + if(!flag) + { + phb_ctb[phb_element[cur_index].type].first_rcd = ref_index; + flag = 1; + } + ref_index = phb_element[cur_index].next_rcd; + } + + else + ref_index = phb_element[ref_index].next_rcd; + } + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_l_record_sort | ++---------------------------------------------------------------------+ + + PURPOSE : + +*/ + +void pb_l_record_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag; + + TRACE_FUNCTION ("pb_l_record_sort()"); + + if (phb_ctb[phb_l_element[cur_index].type].used_rcd EQ 1) + { + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX; + phb_ctb[phb_l_element[cur_index].type].first_rcd = cur_index; + } + else + { + flag = 0; + + ref_index = phb_ctb[phb_l_element[cur_index].type].first_rcd; + phb_ctb[phb_l_element[cur_index].type].first_rcd = cur_index; + + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + phb_l_element[cur_index].next_rcd = (UBYTE)ref_index; + phb_l_element[ref_index].prev_rcd = (UBYTE)cur_index; + + while ((UBYTE)ref_index NEQ UNUSED_BYTE_INDEX) + { + if (phb_l_element[cur_index].entry.index > phb_l_element[ref_index].entry.index) + { + ptr_index = (SHORT)phb_l_element[ref_index].next_rcd; + if ((UBYTE)ptr_index != UNUSED_BYTE_INDEX) + phb_l_element[ptr_index].prev_rcd = (UBYTE)cur_index; + phb_l_element[cur_index].next_rcd = (UBYTE)ptr_index; + + ptr_index = (SHORT)phb_l_element[cur_index].prev_rcd; + if ((UBYTE)ptr_index != UNUSED_BYTE_INDEX) + phb_l_element[ptr_index].next_rcd = (UBYTE)ref_index; + + phb_l_element[ref_index].prev_rcd = phb_l_element[cur_index].prev_rcd; + phb_l_element[ref_index].next_rcd = (UBYTE)cur_index; + phb_l_element[cur_index].prev_rcd = (UBYTE)ref_index; + + /* set the first record in control block */ + if(!flag) + { + phb_ctb[phb_l_element[cur_index].type].first_rcd = ref_index; + flag = 1; + } + ref_index = (SHORT)phb_l_element[cur_index].next_rcd; + } + + else + ref_index = (SHORT)phb_l_element[ref_index].next_rcd; + } + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_cvt_alpha_for_cmp | ++---------------------------------------------------------------------+ + + PURPOSE : convert alpha to lower case when not unicode + +*/ +static void pb_cvt_alpha_for_cmp ( UBYTE *src, + UBYTE *dst, + UBYTE len ) +{ + int i; + + if ( *src NEQ 0x80 ) + { + for ( i = 0; i < len; i++ ) + dst[i] = (UBYTE)tolower((int)src[i]); + + return; + } + + for ( i = 0; i < len; i++ ) + dst[i] = src[i]; +} + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_alpha_sort | ++---------------------------------------------------------------------+ + + PURPOSE : Insert a new record to alpha sorted chain. + +*/ + +void pb_alpha_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag, cmpLen = 0; + UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN]; + int cmp_res; + + /* set the new record as first element */ + if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1) + { + phb_element[cur_index].prev_trcd = UNUSED_INDEX; + phb_element[cur_index].next_trcd = UNUSED_INDEX; + + phb_ctb[phb_element[cur_index].type].first_trcd = cur_index; + } + + if (phb_ctb[phb_element[cur_index].type].used_rcd > 1) + { + ref_index = phb_ctb[phb_element[cur_index].type].first_trcd; + phb_ctb[phb_element[cur_index].type].first_trcd = cur_index; + + phb_element[cur_index].prev_trcd = UNUSED_INDEX; + phb_element[cur_index].next_trcd = ref_index; + phb_element[ref_index].prev_trcd = cur_index; + + /* insert the new record in the alpha order */ + flag = 0; + while (ref_index NEQ UNUSED_INDEX) + { + memset(cur_tag, 0, sizeof ( cur_tag ) ); + memset(check_tag, 0, sizeof ( check_tag ) ); + + /* + this should not cause problems, because in both alphabets + (GSM and ASCII) the most important chars are at the same + positions (A-Z: 65-90 a-z:97-122) + */ + + if( ext_compare_fct != NULL ) + { + cmp_res = ext_compare_fct ( phb_element[cur_index].entry.tag, + phb_element[cur_index].entry.tag_len, + phb_element[ref_index].entry.tag, + phb_element[ref_index].entry.tag_len ); + } + else + { + pb_cvt_alpha_for_cmp ( phb_element[cur_index].entry.tag, + cur_tag, + phb_element[cur_index].entry.tag_len ); + pb_cvt_alpha_for_cmp ( phb_element[ref_index].entry.tag, + check_tag, + phb_element[ref_index].entry.tag_len ); + cmpLen = MINIMUM ( phb_element[cur_index].entry.tag_len, + phb_element[ref_index].entry.tag_len ); + + cmp_res = cmpString ( cur_tag, check_tag, cmpLen ); + } + + if (cmp_res EQ 0) /* MINIMUM character match, so check if one string is longer */ + { /* ABC should come after AB */ + if (phb_element[cur_index].entry.tag_len NEQ phb_element[ref_index].entry.tag_len) + { + if ((phb_element[cur_index].entry.tag_len - phb_element[ref_index].entry.tag_len) > 0) + cmp_res = cmpLen + 1; + else + cmp_res = -cmpLen - 1; + } + } + + if(cmp_res > 0) + { + ptr_index = phb_element[ref_index].next_trcd; + if (ptr_index != UNUSED_INDEX) + { + phb_element[ptr_index].prev_trcd = cur_index; + } + phb_element[cur_index].next_trcd = ptr_index; + + ptr_index = phb_element[cur_index].prev_trcd; + if (ptr_index != UNUSED_INDEX) + { + phb_element[ptr_index].next_trcd = ref_index; + } + + phb_element[ref_index].prev_trcd = phb_element[cur_index].prev_trcd; + phb_element[ref_index].next_trcd = cur_index; + phb_element[cur_index].prev_trcd = ref_index; + + /* set the first record in control block */ + if(!flag) + { + phb_ctb[phb_element[cur_index].type].first_trcd = ref_index; + flag = 1; + } + ref_index = phb_element[cur_index].next_trcd; + } + else + { + ref_index = phb_element[ref_index].next_trcd; + } + } + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_num_sort | ++---------------------------------------------------------------------+ + + PURPOSE : + +*/ + +void pb_num_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag; + CHAR cur_number[MAX_PHB_NUM_LEN]; + CHAR ref_number[MAX_PHB_NUM_LEN]; + + /* TRACE_FUNCTION ("pb_num_sort()");*/ + + /* set the new record as first element */ + if (phb_ctb[phb_element[cur_index].type].used_rcd EQ 1) + { + phb_element[cur_index].prev_nrcd = UNUSED_INDEX; + phb_element[cur_index].next_nrcd = UNUSED_INDEX; + + phb_ctb[phb_element[cur_index].type].first_nrcd = cur_index; + } + + if (phb_ctb[phb_element[cur_index].type].used_rcd > 1) + { + ref_index = phb_ctb[phb_element[cur_index].type].first_nrcd; + phb_ctb[phb_element[cur_index].type].first_nrcd = cur_index; + + phb_element[cur_index].prev_nrcd = UNUSED_INDEX; + phb_element[cur_index].next_nrcd = ref_index; + phb_element[ref_index].prev_nrcd = cur_index; + + /* insert the new record in the number order */ + flag = 0; + while (ref_index NEQ UNUSED_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_element[cur_index].entry.number, + phb_element[cur_index].entry.len); + cmhPHB_getAdrStr(ref_number, + MAX_PHB_NUM_LEN - 1, + phb_element[ref_index].entry.number, + phb_element[ref_index].entry.len); + + if (strcmp((char *)cur_number, (char *)ref_number) > 0) + { + ptr_index = phb_element[ref_index].next_nrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].prev_nrcd = cur_index; + phb_element[cur_index].next_nrcd = ptr_index; + + ptr_index = phb_element[cur_index].prev_nrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].next_nrcd = ref_index; + + phb_element[ref_index].prev_nrcd = phb_element[cur_index].prev_nrcd; + phb_element[ref_index].next_nrcd = cur_index; + phb_element[cur_index].prev_nrcd = ref_index; + + /* set the first logic number record in control block */ + if(!flag) + { + phb_ctb[phb_element[cur_index].type].first_nrcd = ref_index; + flag = 1; + } + ref_index = phb_element[cur_index].next_nrcd; + } + else + { + ref_index = phb_element[ref_index].next_nrcd; + } + } + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_malpha_sort | ++---------------------------------------------------------------------+ + + PURPOSE : Insert a new record to alpha sorted chain. + +*/ + +void pb_malpha_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag, cmpLen = 0; + UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN]; + int cmp_res; + + if (((phb_ctb[ADN].used_rcd EQ 1) AND (phb_ctb[FDN].used_rcd EQ 0)) + OR ((phb_ctb[ADN].used_rcd EQ 0) AND (phb_ctb[FDN].used_rcd EQ 1))) + { + phb_element[cur_index].prev_mtrcd = UNUSED_INDEX; + phb_element[cur_index].next_mtrcd = UNUSED_INDEX; + + phb_ctb[phb_element[cur_index].type].first_mtrcd = cur_index; + return; + } + else + { + if (phb_ctb[ADN].used_rcd NEQ 0) + { + /* Test whether ADN's first_mtrcd index is already in use or not. + If not and FDN entries exist, take FDN's first_mtrcd. */ + if ((phb_ctb[ADN].first_mtrcd EQ UNUSED_INDEX) AND (phb_ctb[FDN].used_rcd NEQ 0)) + ref_index = phb_ctb[FDN].first_mtrcd; + else + ref_index = phb_ctb[ADN].first_mtrcd; + + phb_ctb[ADN].first_mtrcd = cur_index; + } + else + { + ref_index = phb_ctb[FDN].first_mtrcd; + phb_ctb[FDN].first_mtrcd = cur_index; + } + } + + phb_element[cur_index].prev_mtrcd = UNUSED_INDEX; + phb_element[cur_index].next_mtrcd = ref_index; + phb_element[ref_index].prev_mtrcd = cur_index; + + /* insert the new record in the alpha order */ + flag = 0; + while (ref_index NEQ UNUSED_INDEX) + { + memset(cur_tag, 0, sizeof ( cur_tag ) ); + memset(check_tag, 0, sizeof ( check_tag ) ); + + /* + this should not cause problems, because in both alphabets + (GSM and ASCII) the most important chars are at the same + positions (A-Z: 65-90 a-z:97-122) + */ + if( ext_compare_fct != NULL ) + { + cmp_res = ext_compare_fct ( phb_element[cur_index].entry.tag, + phb_element[cur_index].entry.tag_len, + phb_element[ref_index].entry.tag, + phb_element[ref_index].entry.tag_len ); + } + else + { + pb_cvt_alpha_for_cmp ( phb_element[cur_index].entry.tag, + cur_tag, + phb_element[cur_index].entry.tag_len ); + pb_cvt_alpha_for_cmp ( phb_element[ref_index].entry.tag, + check_tag, + phb_element[ref_index].entry.tag_len ); + cmpLen = MINIMUM ( phb_element[cur_index].entry.tag_len, + phb_element[ref_index].entry.tag_len ); + + cmp_res = cmpString ( cur_tag, check_tag, cmpLen ); + } + + if (cmp_res EQ 0) /* MINIMUM character match, so check if one string is longer */ + { /* ABC should come after AB */ + if (phb_element[cur_index].entry.tag_len NEQ phb_element[ref_index].entry.tag_len) + { + if ((phb_element[cur_index].entry.tag_len - phb_element[ref_index].entry.tag_len) > 0) + cmp_res = cmpLen + 1; + else + cmp_res = -cmpLen - 1; + } + } + + if (cmp_res > 0) + { + ptr_index = phb_element[ref_index].next_mtrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].prev_mtrcd = cur_index; + phb_element[cur_index].next_mtrcd = ptr_index; + + ptr_index = phb_element[cur_index].prev_mtrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].next_mtrcd = ref_index; + + phb_element[ref_index].prev_mtrcd = phb_element[cur_index].prev_mtrcd; + phb_element[ref_index].next_mtrcd = cur_index; + phb_element[cur_index].prev_mtrcd = ref_index; + + /* set the first record in control block */ + if(!flag) + { + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mtrcd = ref_index; + else + phb_ctb[FDN].first_mtrcd = ref_index; + + flag = 1; + } + ref_index = phb_element[cur_index].next_mtrcd; + } + else + ref_index = phb_element[ref_index].next_mtrcd; + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_mnum_sort | ++---------------------------------------------------------------------+ + + PURPOSE : + +*/ + +void pb_mnum_sort(SHORT cur_index) +{ + SHORT ref_index; + SHORT ptr_index; + UBYTE flag; + CHAR cur_number[MAX_PHB_NUM_LEN]; + CHAR ref_number[MAX_PHB_NUM_LEN]; + + /* TRACE_FUNCTION ("pb_num_sort()");*/ + + if (((phb_ctb[ADN].used_rcd EQ 1) AND (phb_ctb[FDN].used_rcd EQ 0)) + OR ((phb_ctb[ADN].used_rcd EQ 0) AND (phb_ctb[FDN].used_rcd EQ 1))) + { + phb_element[cur_index].prev_mnrcd = UNUSED_INDEX; + phb_element[cur_index].next_mnrcd = UNUSED_INDEX; + + phb_ctb[phb_element[cur_index].type].first_mnrcd = cur_index; + return; + } + else + { + if (phb_ctb[ADN].used_rcd != 0) + { + /* Test whether ADN's first_mtrcd index is already in use or not. + If not and FDN entries exist, take FDN's first_mtrcd. */ + if ((phb_ctb[ADN].first_mnrcd EQ UNUSED_INDEX) AND (phb_ctb[FDN].used_rcd NEQ 0)) + ref_index = phb_ctb[FDN].first_mnrcd; + else + ref_index = phb_ctb[ADN].first_mnrcd; + + phb_ctb[ADN].first_mnrcd = cur_index; + } + else + { + ref_index = phb_ctb[FDN].first_mnrcd; + phb_ctb[FDN].first_mnrcd = cur_index; + } + } + + phb_element[cur_index].prev_mnrcd = UNUSED_INDEX; + phb_element[cur_index].next_mnrcd = ref_index; + phb_element[ref_index].prev_mnrcd = cur_index; + + /* insert the new record in the number order */ + flag = 0; + while (ref_index NEQ UNUSED_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_element[cur_index].entry.number, + phb_element[cur_index].entry.len); + cmhPHB_getAdrStr(ref_number, + MAX_PHB_NUM_LEN - 1, + phb_element[ref_index].entry.number, + phb_element[ref_index].entry.len); + + if (strcmp((char *)cur_number, (char *)ref_number) > 0) + { + ptr_index = phb_element[ref_index].next_mnrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].prev_mnrcd = cur_index; + phb_element[cur_index].next_mnrcd = ptr_index; + + ptr_index = phb_element[cur_index].prev_mnrcd; + if (ptr_index != UNUSED_INDEX) + phb_element[ptr_index].next_mnrcd = ref_index; + + phb_element[ref_index].prev_mnrcd = phb_element[cur_index].prev_mnrcd; + phb_element[ref_index].next_mnrcd = cur_index; + phb_element[cur_index].prev_mnrcd = ref_index; + + /* set the first logic number record in control block */ + if(!flag) + { + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mnrcd = ref_index; + else + phb_ctb[FDN].first_mnrcd = ref_index; + flag = 1; + } + ref_index = phb_element[cur_index].next_mnrcd; + } + else + ref_index = phb_element[ref_index].next_mnrcd; + } +} + + +/* ++---------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_add_record | ++---------------------------------------------------------------------+ + + PURPOSE : + +*/ + +T_PHB_RETURN pb_add_record(UBYTE type, UBYTE index, T_PHB_RECORD *entry) +{ + UBYTE bit = 0; + UBYTE tag_len; + SHORT new_index; + SHORT cur_index; + SHORT first_id; + SHORT result; + T_PHB_RECORD found_entry; + UBYTE n,m; + UBYTE pos; + UBYTE i; + UBYTE number[MAX_PHB_NUM_LEN]; + T_PHB_RETURN sim_result; + UBYTE old_ext_rcd_num = 0xFF; + int entrylen; +#ifdef PHONEBOOK_EXTENSION + USHORT file_id = 0; +#endif + + TRACE_FUNCTION ("pb_add_record()"); + + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + if (type EQ ECC + OR type EQ ADN + OR type EQ FDN + OR type EQ BDN + OR type EQ UPN) + { + /* Phonebook is full. */ + if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd AND !index) + { + return PHB_FULL; + } + + tag_len = pb_get_entry_len( entry->tag, PHB_MAX_TAG_LEN ); + /* tag_len = MINIMUM ( tag_len, phb_ctb[type].alpha_len); */ + /* Don't truncate a tag if it does not fit onto SIM but raise an error */ + if (tag_len > phb_ctb[type].alpha_len) + { + return PHB_TAG_EXCEEDED; + } + + /* Search the free record number for this record */ + if (!index) + { + T_PHB_RETURN ret; + SHORT first_free; + + switch (type) + { + case ADN: + case FDN: + case BDN: + case UPN: + /* + * Use the function pb_first_free() to determine + * the index of the first free record. + */ + ret=pb_first_free(type,&first_free); + + /* + * Get out if there was a problem, or the phonebook + * is full. + */ + if (ret NEQ PHB_OK) + return(ret); + + bit=(UBYTE)(first_free-1); + break; + + default: + bit=0; + } + } + + /* Delete the information in the record, in order to overwrite */ + if (index) + { + bit = index - 1; + pb_delete_record(type, index, &old_ext_rcd_num, FALSE); + } + + /* search a free element in phonebook element table */ + if (pb_create_memory(&new_index) NEQ PHB_OK) + return PHB_FULL; + phb_element[new_index].type = type; +#ifdef PHONEBOOK_EXTENSION + phb_element[new_index].entry.ext_rcd_num = 0xFF; +#endif + phb_ctb[type].used_rcd++; + + if (type EQ ADN OR type EQ FDN) + phb_ctb[ADN_FDN].used_rcd++; + n = (UBYTE)bit/8; + m = bit%8; + phb_ctb[type].rcd_bitmap[n] |= 0x01 << m; + phb_element[new_index].entry.index = bit + 1; + + /* Copy entry */ + phb_element[new_index].entry.tag_len = tag_len; + phb_element[new_index].entry.len = entry->len; + phb_element[new_index].entry.ton_npi = entry->ton_npi; + memset(phb_element[new_index].entry.tag, 0xFF, PHB_MAX_TAG_LEN); + memcpy((char *)phb_element[new_index].entry.tag, + (char *)entry->tag, + tag_len); + memcpy((char *)phb_element[new_index].entry.number, + (char *)entry->number, + PHB_PACKED_NUM_LEN); /* allow number (10 bytes) + a extension (11 bytes) */ +#ifdef PHONEBOOK_EXTENSION + memcpy((char *)phb_element[new_index].entry.subaddr, + (char *)entry->subaddr, PHB_PACKED_NUM_LEN); +#endif + phb_element[new_index].entry.cc_id = entry->cc_id; + + pb_record_sort(new_index); + pb_alpha_sort(new_index); + pb_num_sort(new_index); + + if ((type EQ ADN) OR (type EQ FDN)) + { + pb_malpha_sort(new_index); + pb_mnum_sort(new_index); + } + + if (phb_ctb[type].mem EQ SIM_MEMORY) + { + /* write this record in SIM card */ + memset(data, 0xFF, sizeof(data)); + memcpy(data, entry->tag, tag_len); + +#if PHONEBOOK_EXTENSION + if (entry->number[10] != 0xFF) + { + data[phb_ctb[type].alpha_len] = 11; /* max. length */ + } + else + { + data[phb_ctb[type].alpha_len] = entry->len+1; + } +#else + data[phb_ctb[type].alpha_len] = entry->len+1; +#endif + data[phb_ctb[type].alpha_len+1] = entry->ton_npi; + memcpy((char *)&data[phb_ctb[type].alpha_len+2], + (char *)entry->number, 10); + data[phb_ctb[type].alpha_len+12] = entry->cc_id; + +#ifdef PHONEBOOK_EXTENSION + if (entry->number[10] != 0xFF) + { + file_id = pb_get_ext_file_id (type); + if (old_ext_rcd_num NEQ 0xFF) + { + /* use the old extention record */ + phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num; + } + else + { + phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (type); + } + data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num; + } + /* only number extention or subaddress could be store */ + else if (entry->subaddr[0] NEQ 0xFF) + { + file_id = pb_get_ext_file_id (type); + if (old_ext_rcd_num NEQ 0xFF) + { + /* use the old extention record */ + phb_element[new_index].entry.ext_rcd_num = old_ext_rcd_num; + } + else + { + phb_element[new_index].entry.ext_rcd_num = pb_get_ext_record_number (0xFF); + } + data[phb_ctb[type].alpha_len+13] = phb_element[new_index].entry.ext_rcd_num; + } +#endif + sim_result = pb_write_sim(type, phb_element[new_index].entry.index); +#ifdef PHONEBOOK_EXTENSION + if (sim_result NEQ PHB_FAIL) + { + if (phb_element[new_index].entry.ext_rcd_num != 0xFF) + { + pb_prepare_ext_data (phb_element[new_index].entry.number, + phb_element[new_index].entry.len, + phb_element[new_index].entry.subaddr, + 10, + file_id); + sim_result = pb_write_sim_ext(file_id, phb_element[new_index].entry.ext_rcd_num); + } + else if (old_ext_rcd_num NEQ 0xFF) + { + /* delete the old extention record */ + pb_rem_ext_record_flag (type, old_ext_rcd_num); + pb_prepare_ext_data (NULL, 0, NULL, 0, file_id); + sim_result = pb_write_sim_ext(SIM_EXT1, old_ext_rcd_num); + } + } +#endif /* PHONEBOOK_EXTENSION */ + return(sim_result); + } + return PHB_OK; + } + + else if ((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN)) + { + cmhPHB_getAdrStr((char *)number, + MAX_PHB_NUM_LEN - 1, + entry->number, + entry->len); + if (pb_search_number(type, number, PHB_NEW_SEARCH, + &first_id, &result, &found_entry) EQ PHB_OK) + { + if (result) + pb_delete_record(type, (UBYTE)found_entry.index, &old_ext_rcd_num, FALSE); + } + + if (phb_ctb[type].used_rcd >= phb_ctb[type].max_rcd) + { + if ((cur_index = phb_ctb[type].first_rcd) EQ UNUSED_INDEX) + return PHB_FAIL; + + while (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX) + cur_index = phb_l_element[cur_index].next_rcd; + if (phb_l_element[cur_index].prev_rcd != UNUSED_BYTE_INDEX) + phb_l_element[phb_l_element[cur_index].prev_rcd].next_rcd = UNUSED_BYTE_INDEX; + } + + else + { + if (pb_create_l_memory(&new_index) NEQ PHB_OK) + return PHB_FAIL; + phb_ctb[type].used_rcd++; + cur_index = new_index; + } + + phb_l_element[cur_index].type = type; + + /* copy record */ + /* if ((type EQ LDN) OR (type EQ LRN)) */ + /* copy call duration - not jet done */ + /* if ((type EQ LRN) OR (type EQ LMN)) */ + /* copy call identifier - not jet done */ + + memcpy((char *)phb_l_element[cur_index].entry.tag, + (char *)entry->tag, + PHB_MAX_TAG_LEN); + phb_l_element[cur_index].entry.tag_len = entry->tag_len; + + phb_l_element[cur_index].entry.year = entry->year; + phb_l_element[cur_index].entry.month = entry->month; + phb_l_element[cur_index].entry.day = entry->day; + phb_l_element[cur_index].entry.hour = entry->hour; + phb_l_element[cur_index].entry.minute = entry->minute; + phb_l_element[cur_index].entry.second = entry->second; + phb_l_element[cur_index].entry.len = entry->len; + phb_l_element[cur_index].entry.ton_npi = entry->ton_npi; + phb_l_element[cur_index].entry.line = entry->line; + memcpy((char *)phb_l_element[cur_index].entry.number, + (char *)entry->number, + PHB_PACKED_NUM_LEN); + phb_l_element[cur_index].entry.cc_id = entry->cc_id; + + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + if (phb_ctb[type].first_rcd EQ cur_index) + { + phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX; + } + else + { + phb_l_element[cur_index].next_rcd = (UBYTE)phb_ctb[type].first_rcd; + } + + /* If it is -1, gardening ! This is possible for the 1rst time a entry is added ??? */ + if (phb_ctb[type].first_rcd != UNUSED_BYTE_INDEX) + { + phb_l_element[phb_ctb[type].first_rcd].prev_rcd = (UBYTE)cur_index; + } + + phb_ctb[type].first_rcd = cur_index; + + new_index = 1; + while (cur_index NEQ UNUSED_BYTE_INDEX) + { + phb_l_element[cur_index].entry.index = (UBYTE)new_index; + new_index++; + cur_index = phb_l_element[cur_index].next_rcd; + } + if ( type EQ LDN ) + { + /* ACI-SPR-16301: Write LND entry to 1 record of SIM, to keep it up + to date Actually, the SIM entries will be overwritten by the LND data + in RAM during switch off of the ME. This mechanism here is just to + ensure the we retrieve more current data in the case of a SAT REFRESH + or unexpected RESET. */ + + /* prepare entry */ + entrylen = pb_get_entry_len( entry->tag, PHB_MAX_TAG_LEN ); + tag_len = MINIMUM ( phb_ctb[type].alpha_len, + entrylen) ; + memset(data, 0xFF, sizeof(data)); + memcpy(data, entry->tag, tag_len); + data[phb_ctb[type].alpha_len] = entry->len+1; + data[phb_ctb[type].alpha_len+1] = entry->ton_npi; + memcpy((char *)&data[phb_ctb[type].alpha_len+2], + (char *)entry->number, 10); + data[phb_ctb[type].alpha_len+12] = entry->cc_id; + + /* always update the first entry */ + sim_result = pb_write_sim(type, 1); + + return sim_result; + } + else + { + return PHB_OK; + } + } + else /* unknown type */ + return PHB_FAIL; +} + + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_delete_record | ++------------------------------------------------------------------------+ + + PURPOSE : Delete a record from phonebook. + +*/ + +T_PHB_RETURN pb_delete_record(UBYTE type, UBYTE index, UBYTE *ext_rcd_num, BOOL permanent) +{ + SHORT cur_index; + UBYTE cur_byte_index, new_byte_index; + UBYTE m,n; + T_PHB_RETURN sim_result; + + TRACE_FUNCTION ("pb_delete_record()"); + + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + if ((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN)) + { + cur_byte_index = (UBYTE)phb_ctb[type].first_rcd; + while (cur_byte_index != UNUSED_BYTE_INDEX) + { + if (phb_l_element[cur_byte_index].entry.index EQ index) + { + phb_l_element[cur_byte_index].free = PHB_ELEMENT_FREE; + pb_l_rcd_chain(type, + (SHORT)phb_l_element[cur_byte_index].prev_rcd, + (SHORT)cur_byte_index, + (SHORT)phb_l_element[cur_byte_index].next_rcd); + phb_ctb[type].used_rcd--; + + /* + * Delete Record in PCM, else the + * record is back after restart + */ + if (phb_ctb[type].mem == TE_MEMORY) + { + UBYTE data[SIZE_EF_LDN]; + + memset (data, 0xFF, SIZE_EF_LDN); + + switch (type) + { + case LDN: + TRACE_EVENT ("Delete LDN entry"); + pcm_WriteRecord((UBYTE *)EF_LDN_ID, + (USHORT)(cur_byte_index+1), + SIZE_EF_LDN, + data); + break; + case LRN: + TRACE_EVENT ("Delete LRN entry"); + pcm_WriteRecord((UBYTE *)EF_LRN_ID, + (USHORT)(cur_byte_index+1), + SIZE_EF_LRN, + data); + break; + case LMN: + TRACE_EVENT ("Delete LMN entry"); + pcm_WriteRecord((UBYTE *)EF_LMN_ID, + (USHORT)(cur_byte_index+1), + SIZE_EF_LMN, + data); + break; + } + } + cur_byte_index = (UBYTE)phb_ctb[type].first_rcd; + new_byte_index = 1; + while (cur_byte_index != UNUSED_BYTE_INDEX) + { + phb_l_element[cur_byte_index].entry.index = new_byte_index; + new_byte_index++; + cur_byte_index = phb_l_element[cur_byte_index].next_rcd; + } + return PHB_OK; + } + cur_byte_index = phb_l_element[cur_byte_index].next_rcd; + } + } + else /* SIM related phonebooks */ + { + cur_index = phb_ctb[type].first_rcd; + + while (cur_index NEQ UNUSED_INDEX) + { + if (phb_element[cur_index].entry.index EQ index) + { + phb_element[cur_index].free = PHB_ELEMENT_FREE; + pb_rcd_chain(type, + phb_element[cur_index].prev_rcd, + cur_index, + phb_element[cur_index].next_rcd); + pb_name_chain(type, + phb_element[cur_index].prev_trcd, + cur_index, + phb_element[cur_index].next_trcd); + pb_num_chain(type, + phb_element[cur_index].prev_nrcd, + cur_index, + phb_element[cur_index].next_nrcd); + + if ((type EQ ADN) OR (type EQ FDN)) + { + pb_mname_chain(type, + phb_element[cur_index].prev_mtrcd, + cur_index, + phb_element[cur_index].next_mtrcd); + pb_mnum_chain(type, + phb_element[cur_index].prev_mnrcd, + cur_index, + phb_element[cur_index].next_mnrcd); + + phb_ctb[ADN_FDN].used_rcd--; + } + + phb_ctb[type].used_rcd--; + + n = (UBYTE)(phb_element[cur_index].entry.index - 1)/8; + m = (UBYTE)(phb_element[cur_index].entry.index - 1)%8; + phb_ctb[type].rcd_bitmap[n] ^= 0x01 << m; + + if (phb_ctb[type].mem EQ SIM_MEMORY) + { +#ifdef PHONEBOOK_EXTENSION + /* store the extention record */ + *ext_rcd_num = phb_element[cur_index].entry.ext_rcd_num; +#endif + /* write this record in SIM card */ + memset(data, 0xFF, sizeof(data)); + if (permanent) + { + sim_result = pb_write_sim(type, index); +#ifdef PHONEBOOK_EXTENSION + if ((sim_result NEQ PHB_FAIL) AND (*ext_rcd_num NEQ 0xFF)) + { + pb_rem_ext_record_flag (type, *ext_rcd_num); + pb_prepare_ext_data (NULL, 0, NULL, 0, pb_get_ext_file_id(type)); + sim_result = pb_write_sim_ext (pb_get_ext_file_id(type), *ext_rcd_num); + } +#endif + return (sim_result); + } + } + return PHB_OK; + } + cur_index = phb_element[cur_index].next_rcd; + } + } + + return PHB_FAIL; +} + + + +void copy_phb_element ( T_PHB_RECORD *entry, T_PHB_AFB_ELEMENT phb_element ) +{ + memset (entry, 0xff, sizeof(T_PHB_RECORD)); + + entry->book = phb_element.type; + entry->index = phb_element.entry.index; + entry->tag_len = phb_element.entry.tag_len; + memcpy((char *)entry->tag, + (char *)phb_element.entry.tag, + PHB_MAX_TAG_LEN); + entry->len = phb_element.entry.len; + entry->ton_npi = phb_element.entry.ton_npi; + memcpy((char *)entry->number, + (char *)phb_element.entry.number, + PHB_PACKED_NUM_LEN); +#ifdef PHONEBOOK_EXTENSION + memcpy((char *)entry->subaddr, + (char *)phb_element.entry.subaddr, + PHB_PACKED_NUM_LEN); +#endif + entry->cc_id = phb_element.entry.cc_id; +} + + +void copy_phb_l_element ( T_PHB_RECORD *entry, T_PHB_RDM_ELEMENT phb_l_element ) +{ + memset (entry, 0xff, sizeof(T_PHB_RECORD)); + + entry->book = phb_l_element.type; + entry->index = phb_l_element.entry.index; + entry->tag_len = phb_l_element.entry.tag_len; + memcpy((char *)entry->tag, + (char *)phb_l_element.entry.tag, + PHB_MAX_TAG_LEN); + entry->len = phb_l_element.entry.len; + entry->ton_npi = phb_l_element.entry.ton_npi; + memcpy((char *)entry->number, + (char *)phb_l_element.entry.number, + PHB_PACKED_NUM_LEN); +#ifdef PHONEBOOK_EXTENSION + memcpy((char *)entry->subaddr, + (char *)phb_l_element.entry.subaddr, + PHB_PACKED_NUM_LEN); +#endif + entry->cc_id = phb_l_element.entry.cc_id; + entry->line = phb_l_element.entry.line; + + entry->year = phb_l_element.entry.year; + entry->month = phb_l_element.entry.month; + entry->day = phb_l_element.entry.day; + entry->hour = phb_l_element.entry.hour; + entry->minute = phb_l_element.entry.minute; + entry->second = phb_l_element.entry.second; +} + + + + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_phys_record | ++------------------------------------------------------------------------+ + + PURPOSE : Read one record according to physical index from phonebook. + +*/ +T_PHB_RETURN pb_read_phys_record(UBYTE type, SHORT index, T_PHB_RECORD *entry) +{ + SHORT cur_index; + SHORT i; + + /* TRACE_FUNCTION ("pb_read_phys_record()");*/ + + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + if (index > phb_ctb[type].max_rcd) + return PHB_INVALID_IDX; + + cur_index = phb_ctb[type].first_rcd; + if (cur_index == UNUSED_INDEX) + return PHB_FAIL; + + if (type EQ ECC + OR type EQ ADN + OR type EQ FDN + OR type EQ BDN + OR type EQ UPN + OR type EQ SDN ) + { + for (i=0; i<phb_ctb[type].used_rcd; i++) + { + if (phb_element[cur_index].entry.index EQ index) + { + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + cur_index = phb_element[cur_index].next_rcd; + if (cur_index == UNUSED_INDEX) + break; + } + } + + else if (type EQ LDN + OR type EQ LRN + OR type EQ LMN) + { + for (i=0; i<phb_ctb[type].used_rcd; i++) + { + if (phb_l_element[cur_index].entry.index EQ index) + { + copy_phb_l_element (entry, phb_l_element[cur_index]); + return PHB_OK; + } + cur_index = phb_l_element[cur_index].next_rcd; + if (cur_index == UNUSED_INDEX) + break; + } + } + + return PHB_FAIL; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_index_record | ++------------------------------------------------------------------------+ + + PURPOSE : Read one record according to index from phonebook. + +*/ + +T_PHB_RETURN pb_read_index_record(UBYTE type, SHORT index, T_PHB_RECORD *entry) +{ + SHORT cur_index; + SHORT i; + + /* TRACE_FUNCTION ("pb_read_index_record()");*/ + + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + if (index > phb_ctb[type].max_rcd) + return PHB_INVALID_IDX; + + cur_index = phb_ctb[type].first_rcd; + if (cur_index == UNUSED_INDEX) + return PHB_FAIL; + + if (type EQ ECC + OR type EQ ADN + OR type EQ FDN + OR type EQ BDN + OR type EQ UPN + OR type EQ SDN) + { + for (i=1; i<index; i++) + { + cur_index = phb_element[cur_index].next_rcd; + if (cur_index == UNUSED_INDEX) + return PHB_FAIL; + } + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + + else if (type EQ LDN + OR type EQ LRN + OR type EQ LMN) + { + for (i=1; i<index; i++) + { + cur_index = phb_l_element[cur_index].next_rcd; + if (cur_index == UNUSED_BYTE_INDEX) + return PHB_FAIL; + } + copy_phb_l_element (entry, phb_l_element[cur_index]); + return PHB_OK; + } + + return PHB_FAIL; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_alpha_record | ++------------------------------------------------------------------------+ + + PURPOSE : Read one record according to alpha index from phonebook. + +*/ + +T_PHB_RETURN pb_read_alpha_record(UBYTE type, SHORT index, T_PHB_RECORD *entry) +{ + SHORT cur_index; + SHORT i; + + /* TRACE_FUNCTION ("pb_read_alpha_record()");*/ + + if (type EQ ADN_FDN) + { + /* check whether this phonebook exists */ + if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY) + AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY)) + return PHB_FAIL; + + cur_index = phb_ctb[ADN].first_mtrcd; + if (cur_index EQ UNUSED_INDEX) + cur_index = phb_ctb[FDN].first_mtrcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + + for (i=1; i<index; i++) + { + cur_index = phb_element[cur_index].next_mtrcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + } + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + else if (type EQ ECC + OR type EQ ADN + OR type EQ FDN + OR type EQ BDN + OR type EQ SDN + OR type EQ UPN) + { + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + cur_index = phb_ctb[type].first_trcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + + for (i=1; i<index; i++) + { + cur_index = phb_element[cur_index].next_trcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + } + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + else /* LDN, LRN, LMN */ + return PHB_FAIL; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_number_record | ++------------------------------------------------------------------------+ + + PURPOSE : Read one record according to number index from phonebook. + +*/ + +T_PHB_RETURN pb_read_number_record(UBYTE type, SHORT index, T_PHB_RECORD *entry) +{ + SHORT cur_index; + SHORT i; + + /* TRACE_FUNCTION ("pb_read_number_record()");*/ + + if (type EQ ADN_FDN) + { + /* check whether this phonebook exists */ + if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY) + AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY)) + return PHB_FAIL; + + + cur_index = phb_ctb[ADN].first_mnrcd; + if (cur_index EQ UNUSED_INDEX) + cur_index = phb_ctb[FDN].first_mnrcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + + for (i=1; i<index; i++) + { + cur_index = phb_element[cur_index].next_mnrcd; + if (cur_index EQ UNUSED_INDEX) + return PHB_FAIL; + } + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + else if (type EQ ECC + OR type EQ ADN + OR type EQ FDN + OR type EQ BDN + OR type EQ SDN + OR type EQ UPN) + { + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + cur_index = phb_ctb[type].first_nrcd; + if (cur_index == UNUSED_INDEX) + return PHB_FAIL; + + for (i=1; i<index; i++) + { + cur_index = phb_element[cur_index].next_nrcd; + if (cur_index == UNUSED_INDEX) + return PHB_FAIL; + } + copy_phb_element (entry, phb_element[cur_index]); + return PHB_OK; + } + else + /* LDN, LRN, LMN */ + return PHB_FAIL; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_search_name | ++------------------------------------------------------------------------+ + + PURPOSE : Search the string from phonebook + +*/ + +T_PHB_RETURN pb_search_name(T_ACI_CMD_SRC srcID, + UBYTE type, + T_ACI_PB_TEXT *search_tag, + UBYTE mode, + SHORT *first_ind, + SHORT *result, + T_PHB_RECORD *entry) +{ + static SHORT ptr_index = UNUSED_INDEX; + SHORT cur_index; + SHORT index; + int cmp_res; + int cmp_len; + int max_cmp_len; + + /* TRACE_FUNCTION ("pb_search_name()");*/ + + if (type EQ ADN_FDN) + { + /* check whether this phonebook exists */ + if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY) + AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY)) + return PHB_FAIL; + + if ((phb_ctb[ADN].first_mtrcd EQ UNUSED_INDEX) + AND (phb_ctb[FDN].first_mtrcd EQ UNUSED_INDEX)) + return PHB_FAIL; + } + else + { + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + } + + /* search string */ + if ( mode EQ PHB_NEW_SEARCH ) + { + TRACE_EVENT("pb_search_name() DEB: mode EQ PHB_NEW_SEARCH"); + ptr_index = UNUSED_INDEX; + max_cmp_len = 0; + index = 1; + *result = 0; + + if (type EQ ADN_FDN) + { + if (phb_ctb[ADN].first_mtrcd != UNUSED_INDEX) + cur_index = phb_ctb[ADN].first_mtrcd; + else + cur_index = phb_ctb[FDN].first_mtrcd; + } + else + cur_index = phb_ctb[type].first_trcd; + + while (cur_index != UNUSED_INDEX) + { + /* + this should not cause problems, because in both alphabets + (GSM and ASCII) the most important chars are at the same + positions (A-Z: 65-90 // a-z:97-122) + */ + if (ext_compare_fct != NULL) + { + cmp_res = ext_compare_fct (phb_element[cur_index].entry.tag, + phb_element[cur_index].entry.tag_len, + search_tag->data, + search_tag->len); + } + else + { + cmp_res = pb_cmp_phb_entry ( phb_element[cur_index].entry.tag, + phb_element[cur_index].entry.tag_len, + search_tag ); + } + +#if defined(MFW) OR defined (FF_MMI_RIV) + if (srcID EQ CMD_SRC_LCL) + { + /* if search string is before entry in alphabet */ + if (search_tag->len EQ 1 AND + (cmp_res >= 0) AND (phb_element[cur_index].entry.tag[0] NEQ '\0')) + { + cmp_res = 0; + } + } + else +#endif + { + if (cmp_res EQ 0) /* If Searchstring matches the first letters of Phonebook */ + { + if (search_tag->len <= phb_element[cur_index].entry.tag_len) + ; /* MATCH */ + else + cmp_res = search_tag->len + 1; + } + } + + if (cmp_res EQ 0) + { + cmp_len = MINIMUM(phb_element[cur_index].entry.tag_len, search_tag->len); + if ( cmp_len > max_cmp_len ) + { + max_cmp_len = cmp_len; + if ( ptr_index EQ UNUSED_INDEX ) + { + /* save the index of the first found record */ + TRACE_EVENT("pb_search_name() DEB: first index"); + } + ptr_index = cur_index; + *first_ind = index; + } + (*result)++; + + } + if (type == ADN_FDN) + cur_index = phb_element[cur_index].next_mtrcd; + else + cur_index = phb_element[cur_index].next_trcd; + index++; + } + } + else + { + TRACE_EVENT("pb_search_name() DEB: mode EQ PHB_NEXT_SEARCH"); + } + + if ( ptr_index EQ UNUSED_INDEX ) + { + TRACE_EVENT("pb_search_name() ERR: name not found"); + return PHB_FAIL; + } + + /* copy the found record */ + copy_phb_element( entry, phb_element[ptr_index] ); + + if (type == ADN_FDN) + ptr_index = phb_element[ptr_index].next_mtrcd; + else + ptr_index = phb_element[ptr_index].next_trcd; + + return PHB_OK; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_search_number | ++------------------------------------------------------------------------+ + + PURPOSE : + +*/ + +T_PHB_RETURN pb_search_number(UBYTE type, + UBYTE *number, + UBYTE mode, + SHORT *first_ind, + SHORT *result, + T_PHB_RECORD *entry) +{ + SHORT count = 0; + static SHORT ptr_index; + SHORT cur_index; + UBYTE cur_byte_index; + + UBYTE flag; + SHORT index; + CHAR cur_number[MAX_PHB_NUM_LEN]; + static CHAR search_number[MAX_PHB_NUM_LEN]; + + TRACE_FUNCTION ("pb_search_number()"); + + if (type EQ ADN_FDN) + { + /* check whether this phonebook exists */ + if ((phb_ctb[ADN].mem EQ NO_PHB_ENTRY) + AND (phb_ctb[FDN].mem EQ NO_PHB_ENTRY)) + return PHB_FAIL; + + if ((phb_ctb[ADN].first_mnrcd EQ UNUSED_INDEX) + AND (phb_ctb[FDN].first_mnrcd EQ UNUSED_INDEX)) + return PHB_FAIL; + } + else + { + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY AND type NEQ ECC) + return PHB_FAIL; + } + + if (type EQ LDN + OR type EQ LRN + OR type EQ LMN) + { + *result = 0; + if (!phb_ctb[type].used_rcd) + return PHB_OK; + + cur_byte_index = (UBYTE) phb_ctb[type].first_rcd; + + while (cur_byte_index != UNUSED_BYTE_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_l_element[cur_byte_index].entry.number, + phb_l_element[cur_byte_index].entry.len); + if (!strcmp((char *)cur_number, (char *)number)) + { + copy_phb_l_element(entry, phb_l_element[cur_byte_index]); + + *result = 1; + return PHB_OK; + } + cur_byte_index = phb_l_element[cur_byte_index].next_rcd; + } + } + + /* check emergency call */ + if (type EQ ECC) + { + *result = 0; + + /* if (!strcmp("112", (char *)number) || !strcmp("911", (char *)number) || !strcmp("999", (char *)number)) + { + entry->book = ECC; + entry->index = 1; + entry->tag_len = 0; + entry->tag[0] = 0; + cmhPHB_getAdrBcd ( entry->number, + &entry->len, + PHB_PACKED_NUM_LEN, (char *)number ); + entry->ton_npi = 0xFF; + entry->cc_id = 0xFF; + *result = 1; + return PHB_OK; + }*/ + + if (!phb_ctb[type].used_rcd) + return PHB_OK; + + cur_index = phb_ctb[type].first_nrcd; + + while (cur_index != UNUSED_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + PHB_PACKED_NUM_LEN - 1, + phb_element[cur_index].entry.number, + phb_element[cur_index].entry.len); + if (!strcmp((char *)cur_number, (char *)number)) + { + copy_phb_element (entry, phb_element[cur_index]); + *result = 1; + return PHB_OK; + } + cur_index = phb_element[cur_index].next_nrcd; + } + return PHB_OK; + } + + /* search phone number */ + if (mode EQ PHB_NEW_SEARCH) + { + count = 0; + flag = 0; + index = 1; + strncpy(search_number, (char *)number, MAX_PHB_NUM_LEN-1); + search_number[MAX_PHB_NUM_LEN-1] = '\0'; + + if (type EQ ADN_FDN) + { + if (phb_ctb[ADN].first_mnrcd != UNUSED_INDEX) + cur_index = phb_ctb[ADN].first_mnrcd; + else + cur_index = phb_ctb[FDN].first_mnrcd; + } + else + cur_index = phb_ctb[type].first_nrcd; + + while (cur_index != UNUSED_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_element[cur_index].entry.number, + phb_element[cur_index].entry.len); + + if (pb_check_number(cur_number, (char *)number)) + { + if (!flag) + { + ptr_index = cur_index; /* save the index of the first found record */ + *first_ind = index; + flag = 1; + } + count++; + } + if (type EQ ADN_FDN) + cur_index = phb_element[cur_index].next_mnrcd; + else + cur_index = phb_element[cur_index].next_nrcd; + index++; + } + + *result = count; + } + + if (mode EQ PHB_NEXT_SEARCH AND count) + { + while (ptr_index != UNUSED_INDEX) + { + /* convert the number in BCD to string */ + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_element[ptr_index].entry.number, + phb_element[ptr_index].entry.len); + + if (pb_check_number(cur_number, search_number)) + break; + + if (type EQ ADN_FDN) + ptr_index = phb_element[ptr_index].next_mnrcd; + else + ptr_index = phb_element[ptr_index].next_nrcd; + } + } + + /* copy the found record */ + if (count) + { + copy_phb_element( entry, phb_element[ptr_index] ); + if (type EQ ADN_FDN) + ptr_index = phb_element[ptr_index].next_mnrcd; + else + ptr_index = phb_element[ptr_index].next_nrcd; + count--; + } + else + return PHB_FAIL; + + return PHB_OK; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_rcd_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to record number. + +*/ + +void pb_rcd_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + /* TRACE_FUNCTION ("pb_rcd_chain()");*/ + + if ((phb_element[cur_index].prev_rcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_rcd EQ UNUSED_INDEX)) + { + phb_ctb[type].first_rcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_rcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_rcd EQ UNUSED_INDEX)) + { + phb_element[prev_index].next_rcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_rcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_rcd NEQ UNUSED_INDEX)) + { + phb_element[next_index].prev_rcd = UNUSED_INDEX; + phb_element[cur_index].next_rcd = UNUSED_INDEX; /* ??? */ + phb_ctb[type].first_rcd = next_index; + } + else if ((phb_element[cur_index].prev_rcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_rcd NEQ UNUSED_INDEX)) + { + phb_element[prev_index].next_rcd = phb_element[cur_index].next_rcd; + phb_element[next_index].prev_rcd = phb_element[cur_index].prev_rcd; + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_l_rcd_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to record number. + +*/ + +void pb_l_rcd_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + /* TRACE_FUNCTION ("pb_l_rcd_chain()"); */ + + if ((phb_l_element[cur_index].prev_rcd EQ UNUSED_BYTE_INDEX) + AND (phb_l_element[cur_index].next_rcd EQ UNUSED_BYTE_INDEX)) + { + phb_ctb[type].first_rcd = UNUSED_INDEX; + } + else if ((phb_l_element[cur_index].prev_rcd NEQ UNUSED_BYTE_INDEX) + AND (phb_l_element[cur_index].next_rcd EQ UNUSED_BYTE_INDEX)) + { + phb_l_element[prev_index].next_rcd = UNUSED_BYTE_INDEX; + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + } + else if ((phb_l_element[cur_index].prev_rcd EQ UNUSED_BYTE_INDEX) + AND (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX)) + { + phb_l_element[next_index].prev_rcd = UNUSED_BYTE_INDEX; + phb_l_element[cur_index].next_rcd = UNUSED_BYTE_INDEX; + phb_ctb[type].first_rcd = (UBYTE)next_index; + } + else if ((phb_l_element[cur_index].prev_rcd NEQ UNUSED_BYTE_INDEX) + AND (phb_l_element[cur_index].next_rcd NEQ UNUSED_BYTE_INDEX)) + { + phb_l_element[prev_index].next_rcd = phb_l_element[cur_index].next_rcd; + phb_l_element[next_index].prev_rcd = phb_l_element[cur_index].prev_rcd; + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + phb_l_element[cur_index].prev_rcd = UNUSED_BYTE_INDEX; + } +} + + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_name_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to alpha string. + +*/ + +void pb_name_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + SHORT ref_index; + UBYTE flag; + + /* TRACE_FUNCTION ("pb_name_chain()");*/ + + if ((phb_element[cur_index].prev_trcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_trcd EQ UNUSED_INDEX)) + { + phb_ctb[type].first_trcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_trcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_trcd EQ UNUSED_INDEX)) + { + phb_element[prev_index].next_trcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_trcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_trcd NEQ UNUSED_INDEX)) + { + phb_element[next_index].prev_trcd = UNUSED_INDEX; + phb_ctb[type].first_trcd = next_index; + phb_element[cur_index].next_trcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_trcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_trcd NEQ UNUSED_INDEX)) + { + phb_element[prev_index].next_trcd = phb_element[cur_index].next_trcd; + phb_element[next_index].prev_trcd = phb_element[cur_index].prev_trcd; + } + + if (phb_ctb[type].first_trcd EQ cur_index) + { + flag = 0; + + ref_index = phb_element[cur_index].next_trcd; + while (phb_element[ref_index].next_trcd) + { + if (!flag) + { + phb_ctb[type].first_trcd = ref_index; + flag = 1; + } + ref_index = phb_element[ref_index].next_trcd; + } + + if (!phb_element[ref_index].next_trcd AND !flag) + phb_ctb[type].first_trcd = UNUSED_INDEX; + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_num_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to phone number. + +*/ + +void pb_num_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + SHORT ref_index; + UBYTE flag; + + /* TRACE_FUNCTION ("pb_num_chain()");*/ + + if ((phb_element[cur_index].prev_nrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_nrcd EQ UNUSED_INDEX)) + { + phb_ctb[type].first_nrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_nrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_nrcd EQ UNUSED_INDEX)) + { + phb_element[prev_index].next_nrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_nrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_nrcd NEQ UNUSED_INDEX)) + { + phb_element[next_index].prev_nrcd = UNUSED_INDEX; + phb_ctb[type].first_nrcd = next_index; + } + else if ((phb_element[cur_index].prev_nrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_nrcd NEQ UNUSED_INDEX)) + { + phb_element[prev_index].next_nrcd = phb_element[cur_index].next_nrcd; + phb_element[next_index].prev_nrcd = phb_element[cur_index].prev_nrcd; + } + + if (phb_ctb[type].first_nrcd EQ cur_index) + { + flag = 0; + + ref_index = phb_element[cur_index].next_nrcd; + while (phb_element[ref_index].next_nrcd) + { + if (!flag) + { + phb_ctb[type].first_nrcd = ref_index; + flag = 1; + } + ref_index = phb_element[ref_index].next_nrcd; + } + + if (!phb_element[ref_index].next_nrcd AND !flag) + phb_ctb[type].first_nrcd = UNUSED_INDEX; + } +} + + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_mname_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to merged alpha string. + +*/ + +void pb_mname_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + SHORT ref_index; + UBYTE flag; + + /* TRACE_FUNCTION ("pb_mname_chain()");*/ + + if ((phb_element[cur_index].prev_mtrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mtrcd EQ UNUSED_INDEX)) + { + phb_ctb[type].first_mtrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_mtrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mtrcd EQ UNUSED_INDEX)) + { + phb_element[prev_index].next_mtrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_mtrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mtrcd NEQ UNUSED_INDEX)) + { + phb_element[next_index].prev_mtrcd = UNUSED_INDEX; + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mtrcd = next_index; + else + phb_ctb[FDN].first_mtrcd = next_index; + } + else if ((phb_element[cur_index].prev_mtrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mtrcd NEQ UNUSED_INDEX)) + { + phb_element[prev_index].next_mtrcd = phb_element[cur_index].next_mtrcd; + phb_element[next_index].prev_mtrcd = phb_element[cur_index].prev_mtrcd; + } + + if ((phb_ctb[ADN].first_mtrcd EQ cur_index) + OR (phb_ctb[FDN].first_mtrcd EQ cur_index)) + { + flag = 0; + + ref_index = phb_element[cur_index].next_mtrcd; + while (phb_element[ref_index].next_mtrcd) + { + if (!flag) + { + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mtrcd = ref_index; + else + phb_ctb[FDN].first_mtrcd = ref_index; + flag = 1; + } + ref_index = phb_element[ref_index].next_mtrcd; + } + + if (!phb_element[ref_index].next_mtrcd AND !flag) + { + phb_ctb[ADN].first_mtrcd = UNUSED_INDEX; + phb_ctb[FDN].first_mtrcd = UNUSED_INDEX; + } + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_mnum_chain | ++------------------------------------------------------------------------+ + + PURPOSE : Chain the element according to phone number. + +*/ + +void pb_mnum_chain(UBYTE type, + SHORT prev_index, + SHORT cur_index, + SHORT next_index) +{ + SHORT ref_index; + UBYTE flag; + + /* TRACE_FUNCTION ("pb_mnum_chain()");*/ + + if ((phb_element[cur_index].prev_mnrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mnrcd EQ UNUSED_INDEX)) + { + phb_ctb[ADN].first_mnrcd = UNUSED_INDEX; + phb_ctb[FDN].first_mnrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_mnrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mnrcd EQ UNUSED_INDEX)) + { + phb_element[prev_index].next_mnrcd = UNUSED_INDEX; + } + else if ((phb_element[cur_index].prev_mnrcd EQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mnrcd NEQ UNUSED_INDEX)) + { + phb_element[next_index].prev_mnrcd = UNUSED_INDEX; + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mnrcd = next_index; + else + phb_ctb[FDN].first_mnrcd = next_index; + } + else if ((phb_element[cur_index].prev_mnrcd NEQ UNUSED_INDEX) + AND (phb_element[cur_index].next_mnrcd NEQ UNUSED_INDEX)) + { + phb_element[prev_index].next_mnrcd = phb_element[cur_index].next_mnrcd; + phb_element[next_index].prev_mnrcd = phb_element[cur_index].prev_mnrcd; + } + + if ((phb_ctb[ADN].first_mnrcd EQ cur_index) + OR (phb_ctb[FDN].first_mnrcd EQ cur_index)) + { + flag = 0; + + ref_index = phb_element[cur_index].next_mnrcd; + while (phb_element[ref_index].next_mnrcd) + { + if (!flag) + { + if (phb_ctb[ADN].used_rcd != 0) + phb_ctb[ADN].first_mnrcd = ref_index; + else + phb_ctb[FDN].first_mnrcd = ref_index; + flag = 1; + } + ref_index = phb_element[ref_index].next_mnrcd; + } + + if (!phb_element[ref_index].next_mnrcd AND !flag) + { + phb_ctb[ADN].first_mnrcd = UNUSED_INDEX; + phb_ctb[FDN].first_mnrcd = UNUSED_INDEX; + } + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_status | ++------------------------------------------------------------------------+ + + PURPOSE : + +*/ + +T_PHB_RETURN pb_read_status(UBYTE type, UBYTE *service, + SHORT *max_rcd, SHORT *used_rcd, + UBYTE *tag_len, SHORT *avail_rcd) +{ + SHORT i; + SHORT count; + + TRACE_FUNCTION ("pb_read_status()"); + + TRACE_EVENT_P1("PHB get status of phonebook: %d", type); + + /* check whether this phonebook exists */ + if (phb_ctb[type].mem EQ NO_PHB_ENTRY) + { + TRACE_EVENT("Phonebook is empty: return PHB_FAIL"); + return PHB_FAIL; + } + *service = phb_ctb[type].service; + *used_rcd = phb_ctb[type].used_rcd; + /* ACI-SPR-9421 (mdf): reinstalled after storage increasement for phonebook */ + *max_rcd = phb_ctb[type].max_rcd; + *tag_len = MINIMUM ( phb_ctb[type].alpha_len, PHB_MAX_TAG_LEN ); + + count = 0; + switch (type) + { + case ECC: + case ADN: + case FDN: + case SDN: + case BDN: + case ADN_FDN: + case UPN: + for (i=0; i<MAX_AFB_RECORDS; i++) + { + if (phb_element[i].free EQ PHB_ELEMENT_FREE) + count++; + } + TRACE_EVENT_P1("free records from count=%d",count); + + if ((phb_ctb[type].max_rcd-phb_ctb[type].used_rcd) >=count) + { + /* avail_rcd should be equal to free records not used records!!! */ + *avail_rcd = count; + } + else + { + *avail_rcd = phb_ctb[type].max_rcd - phb_ctb[type].used_rcd; + } + break; + case LDN: + case LRN: + case LMN: + *max_rcd = phb_ctb[type].max_rcd; + *avail_rcd = phb_ctb[type].max_rcd - phb_ctb[type].used_rcd; + break; + } + return PHB_OK; +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_get_fdn_mode | ++------------------------------------------------------------------+ + + PURPOSE : + +*/ +void pb_status_req(UBYTE *mode) +{ + /* TRACE_FUNCTION ("pb_status_req()");*/ + + *mode = phb_stat; +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_first_free | ++------------------------------------------------------------------+ + + PURPOSE : On exit, "first_free" contains the index of the first free + location in the specified phonebook. + +*/ +T_PHB_RETURN pb_first_free( + UBYTE type, + SHORT *first_free) +{ + SHORT i,bit; + UBYTE max_bitmap; + UBYTE pos; + + TRACE_FUNCTION ("pb_first_free()"); + + if (first_free EQ NULL) + { + ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown); + return(PHB_FAIL); + } + + switch (type) + { + case SDN: + case ADN: + case FDN: + case BDN: + case UPN: + case ECC: + switch (type) + { + case ADN: max_bitmap=MAX_ADN_BITMAP; break; + case FDN: max_bitmap=MAX_FDN_BITMAP; break; + case BDN: max_bitmap=MAX_BDN_BITMAP; break; + case UPN: max_bitmap=MAX_UPN_BITMAP; break; + case SDN: max_bitmap=MAX_SDN_BITMAP; break; + case ECC: max_bitmap=MAX_ECC_BITMAP; break; + + default: + ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown); + return(PHB_FAIL); + } + + bit = 0; + for (i=0; i<max_bitmap; i++) + { + pos = 0; + while ((phb_ctb[type].rcd_bitmap[i] & (1<<pos))) + { + bit++; + pos++; + } + + if ((bit%8) OR !pos) + { + if (bit>=phb_ctb[type].max_rcd) + { + *first_free=0; + return(PHB_FULL); + } + + *first_free=bit+1; + return(PHB_OK); + } + } + + *first_free=0; + return(PHB_FULL); + + case LDN: + case LMN: + case LRN: + /* + * It is not possible to specify an index when writing to these + * phonebooks. Whenever a number is added, it automatically goes + * in the first entry of the list, hence it could be said that + * the first free entry is always 1. + */ + *first_free=1; + return(PHB_OK); + + default: + break; + } + + ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_Unknown); + return(PHB_FAIL); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_switch_adn_fdn | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +T_PHB_RETURN pb_switch_adn_fdn(UBYTE mode, T_ACI_CLASS aci_classFDN) +{ + UBYTE classFDN = (UBYTE) CLASS_None; + TRACE_FUNCTION("pb_switch_adn_fdn()"); + + pb_set_fdn_input_classtype (aci_classFDN); + + if ((mode != FDN_DISABLE) AND (mode != FDN_ENABLE)) + return PHB_FAIL; /* never used */ + + fdn_mode = mode; + + if ( fdn_classtype NEQ fdn_input_classtype) + { + fdn_classtype = fdn_input_classtype; + classFDN = fdn_input_classtype; + /* write to ffs */ +#ifndef _SIMULATION_ + if( ffs_fwrite("/mmi/fdnClassType", &classFDN, sizeof(classFDN)) < 1) + { + TRACE_FUNCTION("sAT_PlusCLCK: ME- failed to write ffs"); + } +#endif + } + + pb_init_afb(); + pb_start_build(FALSE); + return PHB_OK; /* never used */ +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : cmpWild | ++--------------------------------------------------------------------+ + + PURPOSE : compare two strings with wild character ('?') recognition + in string1. Returns 0 on mismatch, otherwise 1. An empty + string always match. + +*/ + +UBYTE cmpWild (char *s1, char *s2) +{ + int i1, i2; + + i1 = strlen(s1); + i2 = strlen(s2); + + if ( i1 != i2 ) + return 0; + + while (i1 && i2) + { + i1--; + i2--; + if (s1[i1] != s2[i2] && s1[i1] != '?') + return 0; + } + + return 1; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : PHB | +| STATE : code ROUTINE : cmpPHBString | ++--------------------------------------------------------------------+ + + PURPOSE : get the length for PHB entry +*/ +int pb_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; + + 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_cmp_phb_entry | ++--------------------------------------------------------------------+ + + PURPOSE : compare PHB entry (SIM) with T_ACI_PB_TEXT. + cannot compare pb_tag with search_tag return - 1 + if pb_tag < search_tag return value < 0 + if pb_tag = search_tag return value = 0 + if pb_tag > search_tag return value > 0 +*/ +static int pb_cmp_phb_entry ( UBYTE *pb_tag, + UBYTE pb_len, + T_ACI_PB_TEXT *search_tag ) +{ + UBYTE cmp_len; + UBYTE pb_tag_buf[PHB_MAX_TAG_LEN]; + UBYTE *cmp_pb_tag; + UBYTE search_tag_buf[PHB_MAX_TAG_LEN]; + UBYTE *cmp_search_tag; + int i; + + cmp_len = MINIMUM ( pb_len, search_tag->len ); + + /* convert to lower cases, when not Unicode */ + if ( ( search_tag->cs EQ CS_Sim ) AND + ( ( *search_tag->data NEQ 0x80 ) AND ( *pb_tag NEQ 0x80 ) ) ) + { + for (i = 0; i < cmp_len; i++) + pb_tag_buf[i] = (UBYTE)tolower((int)pb_tag[i]); + cmp_pb_tag = pb_tag_buf; + + for (i = 0; i < cmp_len; i++) + search_tag_buf[i] = (UBYTE)tolower((int)search_tag->data[i]); + cmp_search_tag = search_tag_buf; + } + else + { + cmp_pb_tag = pb_tag; + cmp_search_tag = search_tag->data; + } + /* check the types */ + if ( search_tag->cs EQ CS_Sim ) + return ( cmpString ( cmp_pb_tag, cmp_search_tag, cmp_len ) ); + + if ( ( search_tag->cs == CS_Ucs2 ) AND ( *pb_tag EQ 0x80 ) ) + return ( memcmp ( cmp_pb_tag + 1, cmp_search_tag, cmp_len ) ); + + if ( ( search_tag->cs EQ CS_Ucs2 ) AND ( *pb_tag NEQ 0x80 ) ) + return pb_cmp2Bytes ( cmp_search_tag, cmp_pb_tag, cmp_len, 1 ); + + if ( ( search_tag->cs EQ CS_GsmDef ) AND ( *pb_tag EQ 0x80 ) ) + return pb_cmp2Bytes ( cmp_search_tag, cmp_pb_tag + 1 , cmp_len, 2 ); + + if ( ( search_tag->cs EQ CS_GsmDef ) AND ( *pb_tag NEQ 0x80 ) ) + { + return ( memcmp ( cmp_pb_tag, cmp_search_tag, cmp_len ) ); + } + + return ( -1 ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : 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 cmpString ( UBYTE *s1, UBYTE *s2, UBYTE len ) +{ + int n = 0; + + /* TRACE_FUNCTION("cmpString()"); */ /* Called too often to trace */ + + if ((*s1 EQ 0x80) AND + (*s2 NEQ 0x80) ) + { + s1++; + len--; + return pb_cmp2Bytes(s1, s2, len, 1); + } + else if ((*s1 NEQ 0x80) AND + (*s2 EQ 0x80) ) + { + s2++; + len--; + return pb_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_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 +*/ + +static int pb_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag) +{ + int n = 0; + + /* TRACE_FUNCTION("pb_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_check_number | ++--------------------------------------------------------------------+ + + PURPOSE : compare two numbers. If they are same, return 1. + +*/ + +UBYTE pb_check_number(char *cur_number, char *number) +{ + UBYTE len1; + UBYTE len2; + + len1 = strlen(cur_number); + len2 = strlen((char *)number); + + if (!len2) + return 0; /* Bug Fix: the return value was "1" */ + + if ((len1>=6) && (len2>=6)) + { + if (cmpWild (&cur_number[len1-6], (char *)&number[len2-6]) EQ 1) + return 1; + } + else + { + if (cmpWild ((char *)cur_number, (char *)number) EQ 1) + return 1; + } + return 0; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_check_fdn | ++--------------------------------------------------------------------+ + + PURPOSE : check whether phone number is in FDN phonebook. + +*/ +GLOBAL T_PHB_RETURN pb_check_fdn (UBYTE toa, + const UBYTE *number) +{ + SHORT cur_index; + CHAR cur_number[MAX_PHB_NUM_LEN]; + CHAR new_number[MAX_PHB_NUM_LEN]; + UBYTE len1; + UBYTE len2; + + len1 = strlen((char *)number); + + cur_index = phb_ctb[FDN].first_nrcd; + while (cur_index != UNUSED_INDEX) + { + memset(new_number, 0, sizeof(new_number)); + cmhPHB_getAdrStr(cur_number, + MAX_PHB_NUM_LEN - 1, + phb_element[cur_index].entry.number, + phb_element[cur_index].entry.len); + + len2 = strlen((char *)cur_number); + if (len1 < len2 OR phb_element[cur_index].entry.len EQ 0) + { + cur_index = phb_element[cur_index].next_nrcd; + continue; + } + else + { + strncpy(new_number, (char *)number, len2); + if (cmpWild ((char *)&cur_number, new_number) EQ 1) + { + + if ( toa NEQ 0 ) /* ACI-SPR-11927:check whether to test toa or not */ + { + if ((toa NEQ phb_element[cur_index].entry.ton_npi) AND + (phb_element[cur_index].entry.ton_npi NEQ 0xFF) ) /* VO patch 02.03.01 */ + { + cur_index = phb_element[cur_index].next_nrcd; + continue; + } + } + + causeMod = P_CEER_mod; /* Clear module which was set for ceer */ + causeCeer = CEER_NotPresent; /* Reset cause - number to dial found in FDN list. */ + return PHB_OK; + } + } + + cur_index = phb_element[cur_index].next_nrcd; + } + causeMod = P_CEER_sim; /* Set ceer module to sim */ + causeCeer = P_CEER_InvalidFDN; /* Set cause - number to dial not found in FDN list.*/ + return PHB_FAIL; +} + +/* ++------------------------------------------------- -------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_exit | ++---------------------------------------------------------------+ + + PURPOSE : Save the phonebook in SIM card. + +*/ + +void pb_exit() +{ + TRACE_FUNCTION("pb_exit()"); + + pb_write_eeprom(); + if(pb_init_sync_sim(LDN) EQ FALSE) + pb_finish_sync_sim(); /* this will otherwise be called after the last record written*/ +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_write_sim_cb | ++------------------------------------------------------------------+ + + + PURPOSE : Call back for write phonebook in SIM card. + +*/ + +void pb_write_sim_cb(SHORT table_id) +{ + UBYTE type; + + TRACE_FUNCTION("pb_write_sim_cb()"); + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR) + { + TRACE_ERROR("pb_write_sim_cb(): error for writing"); + db_index = 0; + phb_stat = PHB_READY; + cmhPHB_StatIndication( PHB_WRITE_FAIL, + (SHORT)cmhSIM_GetCmeFromSim( simShrdPrm.atb[table_id].errCode ), + FALSE ); /* don't indicate for write */ + return; + } + if (db_index) + { + switch (simShrdPrm.atb[table_id].reqDataFld) + { + case SIM_ADN: + type = ADN; + break; + case SIM_FDN: + type = FDN; + break; + case SIM_BDN: + type = BDN; + break; + case SIM_SDN: + type = SDN; + break; + case SIM_MSISDN: + type = UPN; + break; + default: + return; + } + pb_delete_sim_book(type); + } + else + { + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE ); + } +} + +/* ++-----------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_write_sim | ++-----------------------------------------------------------------+ + + + PURPOSE : Write phonebook in SIM card. + +*/ + +T_PHB_RETURN pb_write_sim(UBYTE type, UBYTE rcd_num) +{ + SHORT table_id; + USHORT data_id; + + TRACE_FUNCTION("pb_write_sim()"); + + switch (type) + { + case ADN: + data_id = SIM_ADN; + break; + case FDN: + data_id = SIM_FDN; + break; + case BDN: + data_id = SIM_BDN; + break; + case SDN: + data_id = SIM_SDN; + break; + case UPN: + data_id = SIM_MSISDN; + break; + case LDN: + data_id = SIM_LND; + break; + default: + return PHB_FAIL; + } + + table_id = psaSIM_atbNewEntry(); + if(table_id EQ NO_ENTRY) + { + TRACE_ERROR ("pb_write_sim(): no more table entries"); + return (PHB_FAIL); + } + + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_WR_REC; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].recNr = rcd_num; + simShrdPrm.atb[table_id].dataLen = phb_ctb[type].alpha_len + 14; + simShrdPrm.atb[table_id].exchData = data; + simShrdPrm.atb[table_id].rplyCB = pb_write_sim_cb; + + simShrdPrm.aId = table_id; + + if(psaSIM_AccessSIMData() < 0) + { + TRACE_EVENT("pb_write_sim(): psaSIM_AccessSIMData() failed"); + return (PHB_FAIL); + } + + phb_stat = PHB_BUSY; + cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, FALSE ); + + return (PHB_EXCT); +} + + + +#ifdef PHONEBOOK_EXTENSION +/* ++----------------------------------------------------------------------+ +| PROJECT : MODULE : PHB | +| STATE : code ROUTINE : pb_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 + +*/ + + +LOCAL void pb_prepare_ext_data(UBYTE *number, UBYTE no_len, + UBYTE *subaddr, UBYTE sub_len, + USHORT file_id) +{ + memset(data, 0xFF, sizeof(data)); + + if ((subaddr != NULL) AND (*subaddr != 0xFF)) + { + TRACE_EVENT ("SUBADDRESS EXTENTION"); + data[0] = 1; + data[1] = sub_len; + memcpy (data + 2, subaddr, 11); + } + else if (number != NULL) + { + data[0] = 2; + data[1] = no_len - 10; + memcpy (data + 2, number + 10, no_len); + } +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_write_sim_ext_cb | ++----------------------------------------------------------------------+ + + + PURPOSE : Call back for write phonebook in SIM card. + +*/ + +void pb_write_sim_ext_cb(SHORT table_id) +{ + /* USHORT ext_type; + UBYTE rcd_num;*/ + + TRACE_FUNCTION("pb_write_sim_ext_cb"); + + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; + + if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR) + { + TRACE_ERROR("pb_write_sim_ext_cb (): FATAL ERROR"); + } +} + + +/* ++-------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_write_sim_ext | ++-------------------------------------------------------------------+ + + + PURPOSE : Write phonebook in SIM card. + +*/ + +T_PHB_RETURN pb_write_sim_ext(USHORT data_id, UBYTE rcd_num) +{ + SHORT table_id; + + table_id = psaSIM_atbNewEntry(); + + if(table_id EQ NO_ENTRY) + { + TRACE_ERROR ("pb_write_sim_ext(): no more table entries"); + return (PHB_FAIL); + } + + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_WR_REC; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].recNr = rcd_num; + simShrdPrm.atb[table_id].dataLen = 13; + simShrdPrm.atb[table_id].exchData = data; + simShrdPrm.atb[table_id].rplyCB = pb_write_sim_ext_cb; + + simShrdPrm.aId = table_id; + + if (psaSIM_AccessSIMData() < 0) + { + TRACE_ERROR("pb_write_sim_ext(): psaSIM_AccessSIMData() failed"); + return (PHB_FAIL); + } + + return (PHB_EXCT); +} +#endif /* PHONEBOOK_EXTENSION */ + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_write_eepron_req | ++------------------------------------------------------------------+ + + + PURPOSE : Write phonebook in EEPROM. + +*/ + +void pb_write_eeprom() +{ + SHORT ptr_index; + UBYTE ptr_byte_index; + int i; + UBYTE count; + EF_UPN *p = (EF_UPN *)data; + + /* TRACE_FUNCTION ("pb_write_eeprom_req()"); */ + + /* Write Last Dialing Numbers */ + ptr_byte_index = (UBYTE)phb_ctb[LDN].first_rcd; + + count = 0; + for (i=0; i<phb_ctb[LDN].max_rcd; i++) + { + if (count < phb_ctb[LDN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX) + { + TRACE_EVENT_P1("--- LDN: copy to eeprom for ptr_byte_index %d", ptr_byte_index); + pb_copy_ldn_record((SHORT)ptr_byte_index, 1); + } + else + memset(&data[0], 0xFF, SIZE_EF_LDN); + + if (pcm_WriteRecord((UBYTE *)EF_LDN_ID, + (USHORT)(i+1), + SIZE_EF_LDN, + &data[0]) NEQ DRV_OK) + break; + if (ptr_byte_index NEQ UNUSED_BYTE_INDEX) + ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd; + count++; + } + + /* Write Last received Numbers */ + ptr_byte_index = (UBYTE)phb_ctb[LRN].first_rcd; + + count = 0; + for (i=0; i<phb_ctb[LRN].max_rcd; i++) + { + if (count < phb_ctb[LRN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX) + pb_copy_lrn_record(ptr_byte_index, 1); + else + memset(&data[0], 0xFF, SIZE_EF_LRN); + + if (pcm_WriteRecord((UBYTE *)EF_LRN_ID, + (USHORT)(i+1), + SIZE_EF_LRN, + &data[0]) NEQ DRV_OK) + break; + if (ptr_byte_index NEQ UNUSED_BYTE_INDEX) + ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd; + count++; + } + + /* Write Last missed Numbers */ + ptr_byte_index = (UBYTE)phb_ctb[LMN].first_rcd; + + count = 0; + for (i=0; i<phb_ctb[LMN].max_rcd; i++) + { + if (count < phb_ctb[LMN].used_rcd AND ptr_byte_index NEQ UNUSED_BYTE_INDEX) + pb_copy_lmn_record(ptr_byte_index, 1); + else + memset(&data[0], 0xFF, SIZE_EF_LMN); + + if (pcm_WriteRecord((UBYTE *)EF_LMN_ID, + (USHORT)(i+1), + SIZE_EF_LMN, + &data[0]) NEQ DRV_OK) + break; + if (ptr_byte_index NEQ UNUSED_BYTE_INDEX) + ptr_byte_index = phb_l_element[ptr_byte_index].next_rcd; + count++; + } + + /* Write user person Numbers */ + if (phb_ctb[UPN].mem EQ TE_MEMORY) + { + ptr_index = phb_ctb[UPN].first_rcd; + + count = 0; + for (i=0; i<phb_ctb[UPN].max_rcd; i++) + { + if (count < phb_ctb[UPN].used_rcd AND ptr_index NEQ UNUSED_INDEX) + { + /* copy record */ + memcpy(p->alphId, + phb_element[ptr_index].entry.tag, + 10*sizeof(UBYTE)); + p->len = phb_element[ptr_index].entry.len; + p->numTp = phb_element[ptr_index].entry.ton_npi; + memcpy(p->usrNum, + phb_element[ptr_index].entry.number, + 10*sizeof(UBYTE)); + p->ccp = phb_element[ptr_index].entry.cc_id; + } + else + memset(&data[0], 0xFF, SIZE_EF_UPN); + + if (pcm_WriteRecord((UBYTE *)EF_UPN_ID, + (USHORT)(i+1), + SIZE_EF_UPN, + &data[0]) NEQ DRV_OK) + break; + if (ptr_index NEQ UNUSED_INDEX) + ptr_index = phb_element[ptr_index].next_rcd; + count++; + } + } +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_copy_ldn_record | ++------------------------------------------------------------------+ + + + PURPOSE : Copy a LDN record. + flag = 0: from EEPROM to local + flag = 1: from local to EEPROM + +*/ + +void pb_copy_ldn_record(SHORT index, UBYTE flag) +{ + EF_LDN *p = (EF_LDN *)data; + + /* TRACE_FUNCTION ("pb_copy_ldn_record()");*/ + if (!flag) + { + phb_l_element[index].entry.year = p->year; + phb_l_element[index].entry.month = p->month; + phb_l_element[index].entry.day = p->day; + phb_l_element[index].entry.hour = p->hour; + phb_l_element[index].entry.minute = p->minute; + phb_l_element[index].entry.second = p->second; + phb_l_element[index].entry.len = p->len; + phb_l_element[index].entry.ton_npi = p->numTp; + memcpy((char *)phb_l_element[index].entry.number, + (char *)&p->dldNum, 10); + phb_l_element[index].entry.cc_id = p->ccp; + } + if (flag EQ 1) + { + p->calDrMsb = 0xFF; + p->calDrLsb = 0xFF; + p->year = phb_l_element[index].entry.year; + p->month = phb_l_element[index].entry.month; + p->day = phb_l_element[index].entry.day; + p->hour = phb_l_element[index].entry.hour; + p->minute = phb_l_element[index].entry.minute; + p->second = phb_l_element[index].entry.second; + p->len = phb_l_element[index].entry.len; + p->numTp = phb_l_element[index].entry.ton_npi; + memcpy((char *)p->dldNum, + (char *)phb_l_element[index].entry.number, 10); + p->ccp = phb_l_element[index].entry.cc_id; + p->ext1 = 0xFF; + } +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_copy_lrn_record | ++------------------------------------------------------------------+ + + + PURPOSE : Copy a LRN record. + flag = 0: from EEPROM to local + flag = 1: from local to EEPROM + +*/ + +void pb_copy_lrn_record(SHORT index, UBYTE flag) +{ + EF_LRN *p = (EF_LRN *)data; + + /* TRACE_FUNCTION ("pb_copy_lrn_record()");*/ + + if (!flag) + { + phb_l_element[index].entry.year = p->year; + phb_l_element[index].entry.month = p->month; + phb_l_element[index].entry.day = p->day; + phb_l_element[index].entry.hour = p->hour; + phb_l_element[index].entry.minute = p->minute; + phb_l_element[index].entry.second = p->second; + phb_l_element[index].entry.len = p->len; + phb_l_element[index].entry.ton_npi = p->numTp; + memcpy((char *)phb_l_element[index].entry.number, + (char *)p->dldNum, 10); + phb_l_element[index].entry.cc_id = p->ccp; + } + if (flag EQ 1) + { + p->calDrMsb = 0xFF; + p->calDrLsb = 0xFF; + p->year = phb_l_element[index].entry.year; + p->month = phb_l_element[index].entry.month; + p->day = phb_l_element[index].entry.day; + p->hour = phb_l_element[index].entry.hour; + p->minute = phb_l_element[index].entry.minute; + p->second = phb_l_element[index].entry.second; + p->id = 0xFF; + p->len = phb_l_element[index].entry.len; + p->numTp = phb_l_element[index].entry.ton_npi; + memcpy((char *)p->dldNum, + (char *)phb_l_element[index].entry.number, 10); + p->ccp = phb_l_element[index].entry.cc_id; + p->ext1 = 0xFF; + } +} + + +/* ++------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE : PHB | +| STATE : code ROUTINE : pb_copy_lmn_record | ++------------------------------------------------------------------+ + + + PURPOSE : Copy a LMN record. + flag = 0: from EEPROM to local + flag = 1: from local to EEPROM + +*/ + +void pb_copy_lmn_record(SHORT index, UBYTE flag) +{ + EF_LMN *p = (EF_LMN *)data; + + /* TRACE_FUNCTION ("pb_copy_lmn_record()");*/ + + if (!flag) + { + phb_l_element[index].entry.year = p->year; + phb_l_element[index].entry.month = p->month; + phb_l_element[index].entry.day = p->day; + phb_l_element[index].entry.hour = p->hour; + phb_l_element[index].entry.minute = p->minute; + phb_l_element[index].entry.second = p->second; + phb_l_element[index].entry.len = p->len; + phb_l_element[index].entry.ton_npi = p->numTp; + memcpy((char *)phb_l_element[index].entry.number, + (char *)p->dldNum, 10); + phb_l_element[index].entry.cc_id = p->ccp; + } + if (flag EQ 1) + { + p->year = phb_l_element[index].entry.year; + p->month = phb_l_element[index].entry.month; + p->day = phb_l_element[index].entry.day; + p->hour = phb_l_element[index].entry.hour; + p->minute = phb_l_element[index].entry.minute; + p->second = phb_l_element[index].entry.second; + p->id = 0xFF; + p->len = phb_l_element[index].entry.len; + p->numTp = phb_l_element[index].entry.ton_npi; + memcpy((char *)p->dldNum, + (char *)phb_l_element[index].entry.number, 10); + p->ccp = phb_l_element[index].entry.cc_id; + p->ext1 = 0xFF; + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_delete_book | ++------------------------------------------------------------------------+ + + PURPOSE : Delete a phonebook in SIM card. + +*/ + +T_PHB_RETURN pb_delete_book(UBYTE book) +{ + SHORT cur_index; + + TRACE_FUNCTION("pb_delete_book()"); + + /* check whether this phonebook exists */ + if (phb_ctb[book].mem EQ NO_PHB_ENTRY) + return PHB_FAIL; + + phb_stat = PHB_BUSY; + cmhPHB_StatIndication ( PHB_BUSY, CME_ERR_NotPresent, FALSE ); + + cur_index = phb_ctb[book].first_rcd; + while (cur_index != UNUSED_INDEX) + { + phb_element[cur_index].free = PHB_ELEMENT_FREE; + if ((book EQ ADN) OR (book EQ FDN)) + { + pb_mname_chain(book, + phb_element[cur_index].prev_mtrcd, + cur_index, + phb_element[cur_index].next_mtrcd); + pb_mnum_chain(book, + phb_element[cur_index].prev_mnrcd, + cur_index, + phb_element[cur_index].next_mnrcd); + } + cur_index = phb_element[cur_index].next_rcd; + } + phb_ctb[book].used_rcd = 0; + /* phb_ctb[book].first_rcd = UNUSED_INDEX;*/ + phb_ctb[book].first_trcd = UNUSED_INDEX; + phb_ctb[book].first_nrcd = UNUSED_INDEX; + phb_ctb[book].first_mtrcd = UNUSED_INDEX; /* ??? */ + phb_ctb[book].first_mnrcd = UNUSED_INDEX; /* ??? */ + switch (book) + { + case ADN: + memset(phb_ctb[book].rcd_bitmap, 0, MAX_ADN_BITMAP); + break; + case FDN: + memset(phb_ctb[book].rcd_bitmap, 0, MAX_FDN_BITMAP); + break; + case BDN: + memset(phb_ctb[book].rcd_bitmap, 0, MAX_BDN_BITMAP); + break; + case SDN: + memset(phb_ctb[book].rcd_bitmap, 0, MAX_SDN_BITMAP); + break; + case UPN: + memset(phb_ctb[book].rcd_bitmap, 0, MAX_UPN_BITMAP); + break; + default: + break; + } + pb_delete_sim_book(book); + return PHB_OK; +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_delete_sim_book | ++------------------------------------------------------------------------+ + + PURPOSE : Delete a phonebook in SIM card. + +*/ + +void pb_delete_sim_book(UBYTE book) +{ + if (!db_index) + { + db_index = phb_ctb[book].first_rcd; + phb_ctb[book].first_rcd = UNUSED_INDEX; + } + else + db_index = phb_element[db_index].next_rcd; + if (db_index != UNUSED_INDEX) + { + memset(data, 0xFF, sizeof(data)); + if (pb_write_sim(book, phb_element[db_index].entry.index) EQ PHB_FAIL) + { + db_index = 0; + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE ); + } + } + else + { + db_index = 0; + phb_stat = PHB_READY; + cmhPHB_StatIndication ( PHB_READY, CME_ERR_NotPresent, FALSE ); + } +} + + + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_update_ecc_fu | ++------------------------------------------------------------------------+ + + PURPOSE : Read emergency call numbers from SIM card. + +*/ +#ifdef SIM_TOOLKIT +BOOL pb_update_ecc_fu(int ref, T_SIM_FILE_UPDATE_IND *fu) +{ + + BOOL found = FALSE; + UBYTE i; + TRACE_FUNCTION ("pb_update_ecc_fu()"); + + for (i = 0; i < (int)fu->val_nr; i++) + { + if (!found AND (fu->file_id[i] EQ SIM_ECC)) + { + found = TRUE; + } + } + + if (found) + { + simShrdPrm.fuRef = ref; + pb_update_ecc(); + return FALSE; /* reading files */ + } + else + { + return TRUE; /* nothing to do */ + } +} +#endif + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_update_ecc | ++------------------------------------------------------------------------+ + + PURPOSE : Read emergency call numbers from SIM card. + +*/ + +void pb_update_ecc(void) +{ + TRACE_FUNCTION("pb_update_ecc()"); + if ((fdn_mode != NO_OPERATION) AND (simShrdPrm.fuRef EQ -1)) + return; + + phb_ctb[ECC].mem = SIM_MEMORY; + + phb_ctb[ECC].type = ECC; + phb_ctb[ECC].first_trcd = UNUSED_INDEX; + pb_read_sim_ecc(); + +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_sim_ecc | ++------------------------------------------------------------------------+ + + PURPOSE : Read EC number from SIM card. + +*/ + +void pb_read_sim_ecc (void) +{ + TRACE_FUNCTION ("pb_read_sim_ecc()"); + + if (pb_read_sim_dat(SIM_ECC, NOT_PRESENT_8BIT, (UBYTE)256) EQ FALSE ) /* give the max length 256 */ + pb_read_eeprom_ecc(); +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_read_eeprom_ecc | ++------------------------------------------------------------------------+ + + PURPOSE : Read EC number from EEPROM. + +*/ + +void pb_read_eeprom_ecc (void) +{ + EF_ECC efecc; + UBYTE *data_ptr; + UBYTE version; + int i; + + phb_ctb[ECC].mem = TE_MEMORY; + phb_ctb[ECC].type = ECC; + phb_ctb[ECC].max_rcd = MAX_ECC_RCD; + phb_ctb[ECC].first_trcd = UNUSED_INDEX; + + 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 j; + + data_ptr = &efecc.ecc1[0]; + + for (i=0; i < phb_ctb[ECC].max_rcd; i++) + { + if (*data_ptr NEQ 0xFF) + { + cmhPHB_getAdrStr (ecc_number, + MAX_PHB_NUM_LEN - 1, + data_ptr, + 3); + for (j = 0; j < 3; j++) + { + if (!isdigit (ecc_number[j])) + { + TRACE_EVENT_P2 ("[ERR] pb_read_eeprom_ecc(): invalid character found %c (%d)", + ecc_number[j], i); + return; + } + } + } + data_ptr += 3; + } + } /* workaround end */ + + data_ptr = &efecc.ecc1[0]; + + for (i=0; i < phb_ctb[ECC].max_rcd; i++) + { + pb_copy_ecc_entry(data_ptr, (UBYTE)i); + data_ptr += 3; + } + } +} + +/* ++------------------------------------------------------------------------+ +| PROJECT : MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE : pb_copy_ecc_entry | ++------------------------------------------------------------------------+ + + PURPOSE : Read EC number from EEPROM. + +*/ + +void pb_copy_ecc_entry (UBYTE *ecc, UBYTE num) +{ + SHORT index; + /* TRACE_FUNCTION("pb_copy_ecc_entry()"); */ + if (*ecc NEQ 0xff) + { + /* search a free element in phonebook element table */ + if (pb_create_memory(&index) NEQ PHB_OK) + return; + + phb_ctb[ECC].used_rcd++; + phb_ctb[ECC].rcd_bitmap[0] |= (UBYTE)(0x01 << num); + + phb_element[index].type = ECC; + phb_element[index].entry.index = (UBYTE)(num+1); + phb_element[index].entry.len = 3; + memcpy(phb_element[index].entry.number, ecc, 3); + + pb_record_sort(index); + pb_num_sort(index); + + phb_element[index].prev_trcd = UNUSED_INDEX; + phb_element[index].next_trcd = UNUSED_INDEX; + } +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim_dat | ++----------------------------------------------------------------------+ + + + PURPOSE : Request to read SIM card. + +*/ + +BOOL pb_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length) +{ + SHORT table_id; + + TRACE_FUNCTION ("pb_read_sim_dat()"); + + table_id = psaSIM_atbNewEntry(); + + if(table_id NEQ NO_ENTRY) + { + simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; + simShrdPrm.atb[table_id].accType = ACT_RD_DAT; + simShrdPrm.atb[table_id].reqDataFld = data_id; + simShrdPrm.atb[table_id].dataOff = 0; + simShrdPrm.atb[table_id].dataLen = len; + simShrdPrm.atb[table_id].recMax = max_length; + simShrdPrm.atb[table_id].exchData = NULL; + simShrdPrm.atb[table_id].rplyCB = pb_read_sim_dat_cb; + + simShrdPrm.aId = table_id; + + if(psaSIM_AccessSIMData() < 0) + { + TRACE_EVENT("FATAL ERROR"); + return FALSE; + } + return TRUE; + } + return FALSE; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework (8417) MODULE: PHB | +| STATE : code ROUTINE: pb_read_sim_dat_cb | ++----------------------------------------------------------------------+ + + + PURPOSE : Call back for SIM read. + +*/ +void pb_read_sim_dat_cb(SHORT table_id) +{ + int i; + UBYTE *data_ptr; + + TRACE_FUNCTION ("pb_read_sim_dat_cb()"); + + switch (simShrdPrm.atb[table_id].reqDataFld) + { + case SIM_ECC: + data_ptr = simShrdPrm.atb[table_id].exchData; + if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) + { + phb_ctb[ECC].max_rcd = (SHORT)simShrdPrm.atb[table_id].dataLen/3; + + for (i=0; i < phb_ctb[ECC].max_rcd; i++) + { + pb_copy_ecc_entry(data_ptr, (UBYTE)i); + data_ptr += 3; + } +#ifdef SIM_TOOLKIT + if (simShrdPrm.fuRef >= 0) + { + psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCCESS); + } +#endif + } + else + { +#ifdef SIM_TOOLKIT + if (simShrdPrm.fuRef >= 0) + { + psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR); + } +#endif + pb_read_eeprom_ecc(); + } + break; + + case SIM_SST: + data_ptr = simShrdPrm.atb[table_id].exchData; + if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) + { + /* copy SIM service table */ + memset(sim_service_table, 0, sizeof(sim_service_table)); + memcpy(sim_service_table, + simShrdPrm.atb[table_id].exchData, + MINIMUM(MAX_SRV_TBL, simShrdPrm.atb[table_id].dataLen)); + + /* initialisation of the all SIM phonebooks */ + pb_sat_update_reset(SIM_ADN); + pb_sat_update_reset(SIM_FDN); + pb_sat_update_reset(SIM_BDN); + pb_sat_update_reset(SIM_SDN); + pb_sat_update_reset(SIM_MSISDN); + + /* start reading SIM phonebook */ + pb_start_build(FALSE); + } + else + pb_start_build(FALSE); + break; + + default: + break; + } + simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_set_compare | ++----------------------------------------------------------------------+ + + + PURPOSE : set a external MMI compare function for phonebook entries +*/ + +void pb_set_compare_fct (T_PHB_EXT_CMP_FCT compare_fct) +{ + ext_compare_fct = compare_fct; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_get_fdn_input_classtype | ++----------------------------------------------------------------------+ + + + PURPOSE : get fdn_input_classtype +*/ + +T_ACI_CLASS pb_get_fdn_input_classtype (void) +{ + return fdn_input_classtype; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_set_fdn_input_classtype | ++----------------------------------------------------------------------+ + + + PURPOSE : set fdn_input_classtype +*/ + +void pb_set_fdn_input_classtype (T_ACI_CLASS classtype) +{ + fdn_input_classtype = classtype; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_get_fdn_classtype | ++----------------------------------------------------------------------+ + + + PURPOSE : get fdn_classtype +*/ + +T_ACI_CLASS pb_get_fdn_classtype (void) +{ + return fdn_classtype; +} + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_set_fdn_classtype | ++----------------------------------------------------------------------+ + + + PURPOSE : set fdn_classtype +*/ + +void pb_set_fdn_classtype (T_ACI_CLASS classtype) +{ + fdn_classtype = classtype; +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_get_fdn_mode | ++----------------------------------------------------------------------+ + + PURPOSE : get fdn_mode +*/ + +UBYTE pb_get_fdn_mode (void) + +{ + return fdn_mode; +} +/* ++----------------------------------------------------------------------+ +| PROJECT: MMI-Framework MODULE : PHB | +| STATE : code ROUTINE: pb_set_fdn_mode | ++----------------------------------------------------------------------+ + + PURPOSE : set fdn_mode +*/ + +void pb_set_fdn_mode (UBYTE fdnmode) + +{ + fdn_mode = fdnmode; +} + +#endif /* #ifndef TI_PS_FFS_PHB */