diff g23m/condat/ms/src/aci/phb_sim.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_sim.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,2998 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  MMI-Framework (8417)
+|  Modul   :  PHB
++----------------------------------------------------------------------------- 
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  This modul contains the functions to establish the phone book.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifdef TI_PS_FFS_PHB
+
+#include "aci_all.h"
+#include "aci_cmh.h"
+#include "aci_mem.h"
+
+#include "phb_sim.h"
+#include "phb_aci.h"
+
+#include "ffs/ffs.h"
+
+#ifdef SIM_TOOLKIT
+#include "psa.h"
+#include "psa_sim.h"
+#include "psa_cc.h"
+#include "psa_sat.h"
+#endif /* #ifdef SIM_TOOLKIT */
+
+#include "cmh.h"
+#include "cmh_phb.h"
+#include "pcm.h"
+
+/*
+ * Constants and enumerations
+ */
+ 
+#define MAX_ECC_RCD                    5
+#define FFS_IMSI_SIZE                  8
+#define MAX_EXTNS_PER_RECORD  9
+#define MAX_ELEM_FILES               15
+#define SIM_MAX_RECORD_SIZE   256 /* Maximum size of a SIM record */
+#define RDM_DATA_FILE_ID          (0xff04)          /* File ID to store data related to LDN, LMN and LRN Phonebooks */
+#define SIZE_DATA_DATE_TIME   12
+#define MAX_EXT_RECORDS           10
+
+typedef enum
+{
+  DECREMENT = -1,
+  INCREMENT
+} T_PHB_EXT_REF_TYPE;
+  
+/*
+ * Type definitions
+ */
+ 
+typedef struct
+{
+	/* Handle for the Database */ 
+  int db_handle;
+
+  /* Maximum number of records */
+  UBYTE max_record[MAX_PHONEBOOK];
+
+  /* Number of used records */
+  UBYTE used_record[MAX_PHONEBOOK];
+
+  /* Records sizes */
+  USHORT record_size[MAX_PHONEBOOK];
+ 
+} T_PHB_SIM_DATA;
+
+#define RDM_PHB_DATA_SIZE 6
+
+/* ECC records */
+T_PHB_ECC_RECORD phb_ecc_element[MAX_ECC_RCD];
+
+LOCAL T_PHB_SIM_DATA pbs_data;
+
+/* Global arrays to hold Reference count for Extension records. */
+UBYTE ext1_ref_count[MAX_EXT_RECORDS], ext2_ref_count[MAX_EXT_RECORDS];
+UBYTE ext3_ref_count[MAX_EXT_RECORDS], ext4_ref_count[MAX_EXT_RECORDS];
+UBYTE ext5_ref_count[MAX_EXT_RECORDS];
+UBYTE ext_lmn_ref_count[MAX_EXT_RECORDS], ext_lrn_ref_count[MAX_EXT_RECORDS];
+
+/* Prototypes for search and compare functions */
+int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
+int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num);
+int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags);
+int pb_sim_number_cmp (int db_handle, USHORT field_id,USHORT recno_1,USHORT recno_2, ULONG flags);
+/* 
+ * Prototypes for local functions
+ */
+
+LOCAL void pb_sim_read_eeprom_ecc (void);
+LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count);
+LOCAL void pb_sim_revString(char *);
+LOCAL void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry);
+LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr);
+LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type);
+LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type);
+LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id);
+LOCAL USHORT pb_sim_get_size_except_tag (USHORT field_id);
+
+LOCAL int pb_sim_cmpString ( UBYTE* cur_tag, UBYTE* check_tag, UBYTE cmpLen );
+LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE* entry_tag, UBYTE* cur_tag, UBYTE len );
+LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag);
+LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id, USHORT rec_num, T_PHB_EXT_REF_TYPE ref_type);  
+LOCAL T_PHB_RETURN pb_sim_read_ext_record_for_delete(T_PHB_TYPE type, USHORT field_id, USHORT db_recno);
+
+/*
++----------------------------------------------------------------------+
+| PROJECT: MMI-Framework                MODULE : PHB                   |
+| STATE  : code                         ROUTINE: pb_sim_init       |
++----------------------------------------------------------------------+
+
+  PURPOSE :   Initializes internal data structures for SIM Phonebook.
+*/
+
+void pb_sim_init (void)
+{
+  USHORT i;
+  
+  TRACE_FUNCTION ("pb_sim_init()");
+  db_init();
+
+  /* Initialise the data structures. */
+
+  /* Initialise ECC Phonebook to contain no records. */
+  for(i = 0; i < MAX_ECC_RCD; i++)
+    phb_ecc_element[i].phy_idx = 0;
+  
+  return;
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT: MMI-Framework                MODULE : PHB                   |
+| STATE  : code                         ROUTINE: pb_sim_exit       |
++----------------------------------------------------------------------+
+
+  PURPOSE :   This function is called by pb_exit() to inform the SIM part 
+              of the phonebook to shut down.
+*/
+void pb_sim_exit (void)
+{
+  TRACE_FUNCTION ("pb_sim_exit()");
+
+  db_exit();
+
+  return;
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT: MMI-Framework                MODULE : PHB                   |
+| STATE  : code                         ROUTINE: pb_sim_set_ecc       |
++----------------------------------------------------------------------+
+
+  PURPOSE :   The emergency call numbers are read from SIM card and 
+              written to FFS.
+*/
+T_PHB_RETURN pb_sim_set_ecc (UBYTE ecc_len, const UBYTE *sim_ecc)
+{
+  USHORT ecc_rec_num;
+  UBYTE  *data_ptr;
+  
+  TRACE_FUNCTION ("pb_sim_set_ecc()");
+
+  /* Initialise used records for ECC. */ 
+  pbs_data.used_record[ECC] = 0;
+  
+  /* if SIM ECC data is not empty, copy SIM ECC data to phonebook */
+  if ( ecc_len NEQ 0)
+  {
+    data_ptr         = ( UBYTE *) sim_ecc;
+    pbs_data.max_record[ECC] = (SHORT)((ecc_len/ECC_NUM_LEN) > MAX_ECC_RCD)? MAX_ECC_RCD: ecc_len/ECC_NUM_LEN;
+    pbs_data.record_size[ECC] = ECC_NUM_LEN;
+
+    /* Store ECC into RAM, since ECC records will be less in number. */
+    for (ecc_rec_num = 0; ecc_rec_num < MAX_ECC_RCD; ecc_rec_num++)
+    {
+      if(*data_ptr NEQ 0xff)
+      {
+        memset(&phb_ecc_element[ecc_rec_num],0,sizeof(T_PHB_ECC_RECORD));
+        phb_ecc_element[ecc_rec_num].phy_idx = ecc_rec_num + 1;
+        memcpy(phb_ecc_element[ecc_rec_num].number, data_ptr, ECC_NUM_LEN);
+        data_ptr += ECC_NUM_LEN;
+        (pbs_data.used_record[ECC])++;
+      }
+    }
+  }
+  else
+  {
+    pb_sim_read_eeprom_ecc();
+  }
+
+  return PHB_OK;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_create_ef          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Creates a SIM elementary file. 
+
+*/
+T_PHB_RETURN pb_sim_create_ef  (USHORT ef, USHORT record_size, USHORT records)
+{
+  T_DB_INFO_FIELD field_info;
+  T_DB_TYPE db_type;
+  int db_result;
+
+  TRACE_FUNCTION ("pb_sim_create_ef()");
+
+  TRACE_EVENT_P1("Elementary file ID = %x",ef);
+  db_result = db_info_field(pbs_data.db_handle, ef, &field_info);
+
+  /* Check whether file already exists. */
+  if(db_result EQ DB_OK)
+  {
+    /* Check for Record size and No. of records in the present field. */
+    if((field_info.record_size EQ record_size) AND (field_info.num_records EQ records))
+      return PHB_OK;  /* Preserve the existing field. */
+    else
+    {  
+      if(pb_sim_remove_ef(ef) EQ PHB_FAIL)  /* Remove the existing file and recreate the field. */
+				return PHB_FAIL;
+    }
+  }
+  
+	/* Set DB_TYPE depending on the Elementary file. */ 
+  switch(ef)
+  {
+    case SIM_ADN:
+    case SIM_FDN:          
+    case SIM_BDN:  
+    case SIM_SDN:
+    case SIM_EXT1:
+    case SIM_EXT2:
+    case SIM_EXT3:
+    case SIM_EXT4:
+    case SIM_LND:         
+    case SIM_OCI:
+    //case SIM_ICI:
+    case FFS_LRN:
+    case FFS_LMN:
+    case FFS_EXT_LRN:
+    case FFS_EXT_LMN:
+    case SIM_EXT5:
+      db_type = DB_FREELIST;
+      break;
+        
+    case SIM_MSISDN:          
+    case SIM_IMSI:
+      db_type = DB_UNMANAGED;
+      break;
+
+    default:
+      TRACE_ERROR("Invalid ef passed to pb_sim_create_ef()");
+      return PHB_FAIL;        
+  }
+
+  db_result = db_create_field(pbs_data.db_handle, db_type, ef, record_size, records);
+
+  if(db_result EQ DB_OK)
+    return PHB_OK;
+
+  /* Return PHB_FAIL since DB has failed to create File.  */
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_write_ef          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Writes entry_size bytes content of buffer at index to the elementary file ef.
+
+*/
+T_PHB_RETURN pb_sim_write_ef (USHORT ef, USHORT phy_recno,
+                                         USHORT entry_size, const UBYTE *buffer,
+                                         BOOL *changed, USHORT *ext_record_ef, UBYTE  *ext_record_no)
+{
+  int i;
+  T_DB_CHANGED records_affected;
+
+  TRACE_FUNCTION ("pb_sim_write_ef()");
+
+  /* Initialise changed to FALSE. */
+  *changed = FALSE;
+
+  /* Check for extension records. */
+  switch (ef)
+  {
+    case SIM_ADN:
+    case SIM_MSISDN:
+    case SIM_LND:
+      *ext_record_ef = SIM_EXT1;
+      *ext_record_no = buffer[entry_size - 1];
+      break;
+
+    case SIM_FDN:
+      *ext_record_ef = SIM_EXT2;
+      *ext_record_no = buffer[entry_size - 1];
+      break;
+
+    case SIM_SDN:
+      *ext_record_ef = SIM_EXT3;
+      *ext_record_no = buffer[entry_size - 1];
+      break;
+
+    case SIM_BDN:
+      *ext_record_ef = SIM_EXT4;
+      *ext_record_no = buffer[entry_size - 1];
+      break;
+
+    case FFS_LRN:
+    case FFS_LMN:
+    case SIM_OCI: /* Release 1999 and above 31.102 clause 4.2.34 */
+      *ext_record_ef = SIM_EXT5;
+      *ext_record_no = buffer[entry_size - 15]; // Jirli, please check, 14 instead of 15?
+      break;
+
+    case SIM_EXT1:  /* Extension records can reference other extension records */
+    case SIM_EXT2:
+    case SIM_EXT3:
+    case SIM_EXT4:
+    case SIM_EXT5:
+    case FFS_EXT_LRN:
+    case FFS_EXT_LMN:
+      *ext_record_ef = ef;
+      *ext_record_no = buffer[entry_size - 1];
+      break;
+
+    default:
+      *ext_record_ef = 0;
+      *ext_record_no = 0;
+  }
+
+  /* Record is not referring any extensions. So set ef and record_no to ZERO. */ 
+  if (*ext_record_no EQ 0xff)
+  {
+    *ext_record_ef = 0;
+    *ext_record_no = 0;
+  }
+
+  if (buffer[0] NEQ 0xFF)
+  {
+    /* Write record into FFS */
+    if(db_write_record(pbs_data.db_handle, ef, phy_recno, 0, entry_size, buffer) > DB_OK)
+    {
+      if(db_read_change_log(pbs_data.db_handle, &records_affected) EQ DB_OK)
+      {
+        for(i = 0; i < records_affected.entries; i++)
+        {
+          /* Checking whether Elementary file in the database is changed. */
+          if((records_affected.field_id[i] EQ ef) AND (records_affected.record[i] EQ  phy_recno))
+          {
+            *changed = TRUE;
+            return PHB_OK;
+          }
+        }
+
+        /* Write operation has not changed File in the database. So returning PHB_OK */
+        return PHB_OK;
+      }
+      else    /* Unable to read change log from DB. So returning PHB_FAIL. */
+        return PHB_FAIL;
+    }
+    else   /* Write failure in DB. So returning PHB_FAIL */
+      return PHB_FAIL;
+  }
+  else
+  {
+    /* Empty record */
+    if (db_delete_record (pbs_data.db_handle, ef, phy_recno) NEQ DB_OK)
+      return PHB_FAIL;
+
+    if(db_read_change_log (pbs_data.db_handle, &records_affected) NEQ DB_OK)
+      return PHB_FAIL;
+
+    *changed = (records_affected.entries NEQ 0);
+    return PHB_OK;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_open          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Opens the SIM phonebook for the given SIM determined by the IMSI.
+*/
+T_PHB_RETURN pb_sim_open (const T_imsi_field *imsi_field, BOOL *changed)
+{
+  T_DB_INFO database_info;
+  UBYTE ffsIMSI[MAX_IMSI_LEN+1];
+  UBYTE simIMSI[MAX_IMSI_LEN+1];
+  UBYTE imsi[FFS_IMSI_SIZE];
+  int db_result;
+  UBYTE buffer[RDM_PHB_DATA_SIZE];
+
+  TRACE_FUNCTION("pb_sim_open()");
+
+  /* Initially set SIM changed as TRUE. */
+  *changed = TRUE;
+   
+  /* Open the database. */
+  db_result = db_open(FFS_PHB_DIR);
+
+  TRACE_EVENT_P1("DB handle is %d",db_result);
+
+  if(db_result >= DB_OK)
+  {
+    pbs_data.db_handle = db_result;
+
+    /* Get database info. */
+    db_result = db_info(pbs_data.db_handle, &database_info);
+
+    /* Read IMSI from the FFS if Database is clean. */
+    if((db_result EQ DB_OK) AND (database_info.clean EQ TRUE))
+    {
+      db_result = db_read_record(pbs_data.db_handle, SIM_IMSI, 1, 0, FFS_IMSI_SIZE, imsi);
+
+      /* Compare IMSI read from FFS with IMSI got from SIM. */
+      if(db_result > DB_OK)
+      { 
+        psaSIM_decodeIMSI ((UBYTE*) imsi_field->field,(UBYTE)imsi_field->c_field, (char *)simIMSI);
+
+        psaSIM_decodeIMSI (imsi, FFS_IMSI_SIZE, (char *)ffsIMSI);
+
+        if (!strcmp((char *)simIMSI, (char *)ffsIMSI))
+        { 
+          *changed = FALSE;
+          return PHB_OK;
+        }
+      }
+      else
+      {
+        /* Unable to read IMSI, regenerate database */
+        *changed = TRUE;
+      }
+    }
+
+    /* Remove database whenever database is Inconsistent and SIM is changed. */
+    if(db_close(pbs_data.db_handle) NEQ DB_OK)
+      return PHB_FAIL;
+
+    if(db_remove(FFS_PHB_DIR) NEQ DB_OK)
+      return PHB_FAIL;
+  }/*   if(db_result >= DB_OK) */
+
+  /* Create database: For the first time, whenever SIM is changed 
+              and whenever database is Inconsistent. */
+  db_result = db_create(FFS_PHB_DIR, MAX_ELEM_FILES, TRUE);
+
+  TRACE_EVENT_P1("DB handle is %d",db_result);
+
+  /* Creating DB is successful and valid db_handle is returned */
+  if(db_result >= DB_OK)  
+  {
+    if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, SIM_IMSI, imsi_field->c_field, 1) NEQ DB_OK)
+      return PHB_FAIL;  
+
+    if(db_write_record(pbs_data.db_handle, SIM_IMSI, 1, 0, imsi_field->c_field, imsi_field->field) < DB_OK)
+      return PHB_FAIL;
+
+    /* Create Elementary file to store RDM Phonebook data */
+    if(db_create_field(pbs_data.db_handle, DB_UNMANAGED, RDM_DATA_FILE_ID,RDM_PHB_DATA_SIZE,1) NEQ DB_OK)
+      return PHB_FAIL;
+    
+    memset(buffer,0x00, RDM_PHB_DATA_SIZE); 
+
+    if(db_write_record(pbs_data.db_handle, RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, buffer) < DB_OK)
+      return PHB_FAIL;
+      
+    return PHB_OK;
+  }
+
+  /* Unable to create Database. So returning PHB_FAIL. */ 
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_ef          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Reads *buffer from elementary file ef at index.
+*/
+T_PHB_RETURN pb_sim_read_ef (USHORT ef, USHORT recno, USHORT *entry_size, UBYTE *buffer)
+{
+  int db_result;
+  T_DB_INFO_FIELD field_info;
+
+  TRACE_FUNCTION("pb_sim_read_ef()");
+
+  if(db_info_field(pbs_data.db_handle, ef, &field_info) EQ DB_OK)
+  {
+    *entry_size = field_info.record_size;
+
+    db_result = db_read_record (pbs_data.db_handle,
+                                ef,
+                                recno,
+                                0,
+                                field_info.record_size,
+                                buffer);
+
+    if (db_result > DB_OK)
+      return PHB_OK;  /* Successfully read */
+
+    if (db_result EQ DB_EMPTY_RECORD)
+    {
+      /* Return a deleted record content */
+      memset (buffer, 0xff, *entry_size);
+      return PHB_OK;
+    }
+    return PHB_FAIL; /* Some problem reading record */
+  }
+
+  /* Returning PHB_FAIL, since DB has failed to give Info about the field. */ 
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_remove_ef          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Removes elementary file.
+*/
+T_PHB_RETURN pb_sim_remove_ef (USHORT ef)
+{
+  TRACE_FUNCTION("pb_sim_remove_ef()");
+
+  if(db_remove_field(pbs_data.db_handle, ef) EQ DB_OK)
+    return PHB_OK;
+
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_build_index          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Builds index for the given phonebook.
+*/
+
+T_PHB_RETURN pb_sim_build_index (T_PHB_TYPE type)
+{
+  USHORT field_id;
+  
+  TRACE_FUNCTION("pb_sim_build_index()");
+
+  field_id = pb_sim_get_field_id(type);
+
+  if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX, &pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+    return PHB_FAIL;
+
+  if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX, &pb_sim_number_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+    return PHB_FAIL;
+  
+  return PHB_OK;
+}
+  
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_flush_data          |
++--------------------------------------------------------------------+
+
+    PURPOSE : This function informs the SIM phonebook that SIM reading has become finished and we reached a consistent state.
+*/
+
+T_PHB_RETURN pb_sim_flush_data  (void)
+{
+
+  TRACE_FUNCTION("pb_sim_flush_data()");
+
+  if(db_flush(pbs_data.db_handle) EQ DB_OK)
+    return PHB_OK;
+
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_add_record          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Add a given record at index to the given phonebook.
+*/
+
+T_PHB_RETURN pb_sim_add_record  (T_PHB_TYPE type, USHORT phy_recno, const T_PHB_RECORD *entry, T_DB_CHANGED *rec_affected)
+{
+  USHORT field_id, ext_file_id;
+  UBYTE    tag_len, max_tag_len;
+  UBYTE   data[SIM_MAX_RECORD_SIZE];
+  UBYTE   buffer[RDM_PHB_DATA_SIZE];
+  T_DB_INFO_FIELD info_field;
+  UBYTE ext_rec_cnt = 0;
+  UBYTE ext_rec_num1, ext_rec_num2;
+  int db_result,i;
+  
+  
+  TRACE_FUNCTION("pb_sim_add_record()");
+
+  /* Handling of ECC Phonebook */
+  if(type EQ ECC)
+  {
+    if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+    {
+      phb_ecc_element[phy_recno - 1].phy_idx = phy_recno;
+      memcpy(phb_ecc_element[phy_recno - 1].number,entry->number, ECC_NUM_LEN);
+
+      return PHB_OK;
+    }
+    else
+      return PHB_FAIL;
+  }
+  
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+  TRACE_EVENT_P1("pb_sim_get_field_id->Field_id: %x", field_id);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  TRACE_EVENT_P1("Ext_Field_id: %x", ext_file_id);
+
+  db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
+  
+  /* Get record size to calculate alpha_len for the entry */
+  if(db_result NEQ DB_OK)
+  {
+    TRACE_EVENT_P1("db_result = %d",db_result);
+    return PHB_FAIL;
+  }
+
+  /* Handling of LDN, LMN and LRN Phonebook records.  */
+  if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+  {
+    if(phy_recno NEQ 1)
+      return PHB_FAIL;
+    
+    /* Read data related to LDN,LMN and LRN Phonebooks from FFS */
+    db_result = db_read_record(pbs_data.db_handle, 
+                         RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, buffer);
+
+    /* Check for DB Failure. */
+    if(db_result < DB_OK)
+      return PHB_FAIL;
+
+
+    /* Information for handling Cyclic RDM Records 
+    ----------------------------------------
+          buffer[0] ---> Most Recent in LDN
+          buffer[1] ---> Oldest in LDN
+          buffer[2] ---> Most Recent in LMN
+          buffer[3] ---> Oldest in LMN
+          buffer[4] ---> Most Recent in LRN
+          buffer[5] ---> Oldest in LRN
+    ---------------------------------------- */
+   
+    if(type EQ LDN)               /* Circular entry handling for LDN */
+    {
+      buffer[0] ++;
+             
+      if(buffer[0] > info_field.num_records)
+				buffer[0] = 1;
+
+      if(buffer[0] EQ buffer[1])
+      { 
+        buffer[1]++;
+
+				if(buffer[1] >  info_field.num_records)
+					buffer[1] = 1;
+      }
+
+      phy_recno = buffer[0];
+
+      if(buffer[1] EQ 0)
+        buffer[1] = 1;
+    }
+
+    if(type EQ LMN)          /* Circular entry handling for LMN */
+    {
+      buffer[2]++;
+              
+      if(buffer[2] > info_field.num_records)
+				buffer[2] = 1;
+
+      if(buffer[2] EQ buffer[3])
+      {  
+        buffer[3]++;
+
+				if(buffer[3] >  info_field.num_records)
+					buffer[3] = 1;  
+      }
+
+      phy_recno = buffer[2];
+
+      if(buffer[3] EQ 0)
+        buffer[3] = 1;
+    }
+
+    if(type EQ LRN)         /* Circular entry handling for LRN */
+    {
+      buffer[4]++;
+
+      if(buffer[4] > info_field.num_records)
+        buffer[4] = 1;
+
+      if(buffer[4] EQ buffer[5])
+      { 
+				buffer[5]++;
+
+				if(buffer[5] >  info_field.num_records)
+					buffer[5] = 1;  
+      }
+
+      phy_recno = buffer[4];
+
+      if(buffer[5] EQ 0)
+        buffer[5] = 1;
+    }
+
+    TRACE_EVENT_P3("%d %d %d", buffer[0], buffer[1],buffer[2]);
+    TRACE_EVENT_P3("%d %d %d", buffer[3], buffer[4],buffer[5]);
+    /* Write data related to LDN,LMN and LRN Phonebooks to FFS */
+    db_result = db_write_record(pbs_data.db_handle, 
+                         RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, buffer);
+
+    /* Check for DB Failure. */
+    if(db_result < DB_OK)
+      return PHB_FAIL;
+  }/* if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN)) */
+  
+  /* Convert T_PHB_TYPE into data structures as described in ETSI 11.11                  */
+  /*  Bytes        Description                                      M/O   Length            |
+  ----------------------------------------------------------------------
+       1 to X          Alpha Identifier                                O       X bytes
+       X+1                Length of BCD number/SSC contents    M       1 byte
+       X+2                TON and NPI                                         M    1 byte
+       X+3 to X+12  Dialling Number/SSC String                   M     10 bytes
+       X+13        Capability/Configuration Identifier          M      1 byte
+       X+14        Extension Record Identifier                   M     1 byte
+       -------------------------------------------------------
+       Extra fields for LDN, LMN, and LMN Phonebook records (As per 31.102)
+       -------------------------------------------------------
+       X+15 to X+21 Outgoing call date and time                  M     7 bytes
+       X+22 to X+24 Outgoing call duration                          M      3 bytes 
+       X+26              Line of the call                                      M    1 byte (New field added to 
+                                                                                                         store line of call)
+  ----------------------------------------------------------------------*/
+
+  tag_len = pb_sim_get_entry_len(entry->tag, PHB_MAX_TAG_LEN);
+
+  max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+
+  if(tag_len > max_tag_len)
+    return PHB_TAG_EXCEEDED;
+
+  memset(data, 0xFF, sizeof(data));
+  memcpy(data, entry->tag, tag_len);
+
+  if(entry->number[10] NEQ 0xFF)
+  {
+    data[max_tag_len] = 11; /* max. length */
+  }
+  else
+  {
+    data[max_tag_len] = entry->len + 1;
+  }
+
+  data[max_tag_len+1] = entry->ton_npi;
+  memcpy((char *)&data[max_tag_len+2], 
+           (char *)entry->number, 10);
+  data[max_tag_len+12] = entry->cc_id;
+
+  /* Copy data specific to records of Phonebook Types (LRN, LDN and LMN). */  
+  if((type EQ LDN) OR (type EQ LRN) OR (type EQ LMN))
+  {
+    if(entry->v_time)
+    {
+      data[max_tag_len+14] = entry->time.year;
+      data[max_tag_len+15] = entry->time.month;
+      data[max_tag_len+16] = entry->time.day;
+      data[max_tag_len+17] = entry->time.hour;
+      data[max_tag_len+18] = entry->time.minute;
+      data[max_tag_len+19] = entry->time.second;
+      data[max_tag_len+20] = entry->time.time_zone;
+
+      data[max_tag_len+21] = (UBYTE)((entry->time.duration >> 16) & 0xff);
+      data[max_tag_len+22] = (UBYTE)((entry->time.duration >> 8) & 0xff);
+      data[max_tag_len+23] = (UBYTE)((entry->time.duration) & 0xff);
+
+    }
+
+    if(entry->v_line)
+    {
+      data[max_tag_len+24] = entry->line;
+    }
+    
+  }
+
+  TRACE_EVENT_P1("Number = %s",entry->number);
+  /* Check if extension records are needed */
+
+  /* Check how many extension records are needed for number */ 
+  if(entry->number[10] NEQ 0xFF)
+  {
+    ext_rec_cnt = entry ->len - 10;
+
+    if(ext_rec_cnt % 10)
+      ext_rec_cnt = (ext_rec_cnt  / 10) + 1;
+    else
+      ext_rec_cnt = (ext_rec_cnt  / 10);
+  }
+
+  /* Check how many extension records are needed for subaddress */ 
+  if(entry->subaddr[0] NEQ 0xFF)
+  {
+    ext_rec_cnt++;
+  }
+
+  if(entry->subaddr[11] NEQ 0xFF)
+  {
+    ext_rec_cnt++;
+  } 
+
+  TRACE_EVENT_P1("phy_recno = %d",phy_recno);
+
+  TRACE_EVENT_P2("no_rec = %d, used_rec = %d",info_field.num_records,info_field.used_records);
+
+  /* If record number is not mentioned, search for the free record and add the entry. */
+  if(phy_recno EQ 0)
+  {
+    db_result = db_find_free_record( pbs_data.db_handle, field_id);
+
+    /* Database is unable to find the free record. So returning PHB_FULL. */
+    if(db_result EQ DB_RECORD_NOT_FOUND)
+      return PHB_FULL;
+
+    if(db_result < DB_OK)
+      return PHB_FAIL;
+
+    /* Database has returned the free record number. */
+    phy_recno = db_result;
+  }
+  
+  /* Write record if entry does not require extension records */
+  if(ext_rec_cnt EQ 0)              
+  {
+    /* Write record into FFS  */
+    if(db_write_record(pbs_data.db_handle, field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
+      return PHB_FAIL;
+
+    /* For LDN record also write to SIM_LDN (without date and time Details */
+    if(type EQ LDN)
+    {
+      memset(&data[max_tag_len + pb_sim_get_size_except_tag(field_id)], 0xFF, 
+        SIZE_DATA_DATE_TIME);
+
+     /* if(db_info_field(pbs_data.db_handle, SIM_LND, &info_field) NEQ DB_OK)
+        return PHB_FAIL;
+
+      if(db_write_record(pbs_data.db_handle, SIM_LND, phy_recno, 0, info_field.record_size, data) < DB_OK)
+        return PHB_FAIL;*/
+    }
+
+  }
+  else        /* We need to find free extension record. */
+  {
+    TRACE_EVENT_P1("Extension records = %d",ext_rec_cnt);
+    /* Search for free extension records */
+
+		/* Check whether extension file has required no. of free records. */
+		db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
+
+		if((info_field.num_records - info_field.used_records) < ext_rec_cnt)
+			return PHB_FAIL;
+		
+		/* Required no. of free extension records are found */
+    ext_rec_num1= db_find_free_record( pbs_data.db_handle,ext_file_id);
+
+    /* DB has returned non-zero positive number. 
+            (Valid record number which is free). */ 
+    if(ext_rec_num1 > DB_OK) 
+    {  /* Set Extension record Identifier */
+      data[max_tag_len+13] = ext_rec_num1;    
+
+      db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
+
+      /* Write record into FFS */
+      if(db_write_record(pbs_data.db_handle, 
+        field_id, phy_recno, 0, info_field.record_size, data) < DB_OK)
+				return PHB_FAIL;
+        
+    }
+    else
+			return PHB_FAIL;
+
+		db_result = db_info_field(pbs_data.db_handle, ext_file_id, &info_field);
+
+		/* Prepare extension data and write into Extension file after finding the free records. */
+    for(i = 0; i < ext_rec_cnt; i++)
+    {
+      pb_sim_prepare_ext_data(data, i, (UBYTE*)entry->number, entry->len, (UBYTE*)entry->subaddr);
+
+      /* Find next free record to chain the extension records. */
+		  ext_rec_num2 = db_find_free_record( pbs_data.db_handle,ext_file_id);
+		 
+      /* Chain extension records and set last link to "FF" */
+      if(i NEQ (ext_rec_cnt - 1))
+        data[12] =  ext_rec_num2;
+          
+      /* Write extension record into FFS */
+      if(db_write_record(pbs_data.db_handle, ext_file_id, ext_rec_num1, 0, info_field.record_size, data) < DB_OK)
+        return PHB_FAIL;
+
+			if(pb_sim_update_extn_records(ext_file_id, ext_rec_num1, INCREMENT) EQ PHB_FAIL)
+				return PHB_FAIL;
+
+		  /* Preserve the previous free record number. */ 
+		  ext_rec_num1 = ext_rec_num2;
+    }
+    
+  }  
+
+  /* Get information about changed records from the database. */
+  if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
+    return PHB_FAIL;
+
+  if((type NEQ LDN) AND (type NEQ LMN) AND (type NEQ LRN))
+  {
+    /* Update the sorted indexes. */
+    if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX, &pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+      return PHB_FAIL;
+
+    if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX, &pb_sim_number_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+      return PHB_FAIL;
+  }
+  else
+  {
+    /* Remove RDM data record from the list */
+    if(rec_affected->entries NEQ 0)
+    {
+      rec_affected->entries -= 2;
+  
+      /* Remove the record from the list */
+      memmove (&rec_affected->field_id[0],
+           &rec_affected->field_id[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+      memmove (&rec_affected->record[0],
+           &rec_affected->record[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+
+			/* Remove the record from the list */
+      memmove (&rec_affected->field_id[0],
+           &rec_affected->field_id[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+      memmove (&rec_affected->record[0],
+           &rec_affected->record[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+    
+			/* Remove extension record from the list. */
+			if(ext_rec_cnt NEQ 0)
+			{
+				rec_affected->entries --;
+  
+        /* Remove the record from the list */
+        memmove (&rec_affected->field_id[0],
+           &rec_affected->field_id[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+
+				memmove (&rec_affected->record[0],
+           &rec_affected->record[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+			}
+    }
+  }
+
+  return PHB_OK;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_del_record         |
++--------------------------------------------------------------------+
+
+    PURPOSE : Delete a given record at phy_recno from the given phonebook.
+*/
+
+T_PHB_RETURN pb_sim_del_record  (T_PHB_TYPE type, USHORT phy_recno, T_DB_CHANGED *rec_affected)
+{
+  USHORT field_id, ext_file_id, db_recno;
+  UBYTE   buffer[RDM_PHB_DATA_SIZE], rec_cnt;
+  T_DB_INFO_FIELD info_field;
+  UBYTE   data[SIM_MAX_RECORD_SIZE];
+
+
+  TRACE_FUNCTION("pb_sim_del_record()");
+
+  /* Handling of ECC Phonebook */
+  if(type EQ ECC)
+  {
+    if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+    {
+      phb_ecc_element[phy_recno - 1].phy_idx = 0;
+      memset(phb_ecc_element[phy_recno - 1].number, 0, ECC_NUM_LEN);
+
+      return PHB_OK;
+    }
+    else
+      return PHB_FAIL;
+  }
+
+  TRACE_EVENT_P1("phy_recno = %d", phy_recno);
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  /* Get no. of records in the field */
+  if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+    return PHB_FAIL;
+  
+	/* Information for handling Cyclic RDM Records 
+    ----------------------------------------
+          buffer[0] ---> Most Recent in LDN
+          buffer[1] ---> Oldest in LDN
+          buffer[2] ---> Most Recent in LMN
+          buffer[3] ---> Oldest in LMN
+          buffer[4] ---> Most Recent in LRN
+          buffer[5] ---> Oldest in LRN
+    ---------------------------------------- */
+
+  /* Handling of LDN, LMN and LRN Phonebook records.  */
+  if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+  {
+    /* Read data related to LDN,LMN and LRN Phonebooks from FFS */
+    if(db_read_record(pbs_data.db_handle, RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
+      return PHB_FAIL;
+
+    if(type EQ LDN)               /* Circular entry handling for LDN */
+    {
+      db_recno = buffer[0];
+
+      if(phy_recno NEQ 1)
+	  {
+		for(rec_cnt = 0; rec_cnt < (phy_recno - 1) ; rec_cnt++)
+		{
+		  db_recno--;
+
+		  if(db_recno EQ 0)
+			db_recno = (UBYTE)info_field.num_records;
+
+		  while(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+		  {  
+			db_recno--;
+
+			if(db_recno EQ 0)
+			  db_recno = (UBYTE)info_field.num_records;
+		  }
+		}
+	  }
+
+	  if(buffer[0] EQ buffer[1])
+        buffer[0] = buffer[1] = 0;
+
+	  if(buffer[0] EQ db_recno)
+      {  
+		buffer[0]--;
+
+        if(buffer[0] EQ 0)
+		  buffer[0] = (UBYTE)info_field.num_records;
+
+        while(db_read_record(pbs_data.db_handle, field_id, buffer[0], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[0]--;
+
+		  if(buffer[0] EQ 0)
+		    buffer[0] = (UBYTE)info_field.num_records;
+		}
+      }
+
+	  if(buffer[1] EQ db_recno)
+      {  
+	    buffer[1]++;
+
+		if(buffer[1] EQ info_field.num_records)
+		  buffer[1] = 1;
+
+		while(db_read_record(pbs_data.db_handle, field_id, buffer[1], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[1]++;
+
+		  if(buffer[1] EQ info_field.num_records)
+		    buffer[1] = 1;
+		}
+	  }
+    }
+
+    if(type EQ LMN)          /* Circular entry handling for LMN */
+    {
+      db_recno = buffer[2];
+
+      if(phy_recno NEQ 1)
+	  {
+		for(rec_cnt = 0; rec_cnt < (phy_recno - 1) ; rec_cnt++)
+		{
+		  db_recno--;
+
+		  if(db_recno EQ 0)
+			db_recno = (UBYTE)info_field.num_records;
+
+		  while(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+		  {  
+			db_recno--;
+
+			if(db_recno EQ 0)
+			  db_recno = (UBYTE)info_field.num_records;
+		  }
+		}
+	  }
+
+	  if(buffer[2] EQ buffer[3])
+        buffer[2] = buffer[3] = 0;
+
+	  if(buffer[2] EQ db_recno)
+      {  
+	    buffer[2]--;
+
+        if(buffer[2] EQ 0)
+		  buffer[2] = (UBYTE)info_field.num_records;
+
+        while(db_read_record(pbs_data.db_handle, field_id, buffer[2], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[2]--;
+
+		  if(buffer[2] EQ 0)
+		     buffer[2] = (UBYTE)info_field.num_records;
+		}
+      }
+
+	  if(buffer[3] EQ db_recno)
+      {  
+	    buffer[3]++;
+
+		if(buffer[3] EQ info_field.num_records)
+		  buffer[3] = 1;
+
+		while(db_read_record(pbs_data.db_handle, field_id, buffer[3], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[3]++;
+
+		  if(buffer[3] EQ info_field.num_records)
+		    buffer[3] = 1;
+		}
+	  }
+    }
+
+    if(type EQ LRN)         /* Circular entry handling for LRN */
+    {
+      db_recno = buffer[4];
+
+      if(phy_recno NEQ 1)
+	  {
+	    for(rec_cnt = 0; rec_cnt < (phy_recno - 1) ; rec_cnt++)
+		{
+		  db_recno--;
+
+		  if(db_recno EQ 0)
+			db_recno = (UBYTE)info_field.num_records;
+
+		  while(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+		  {  
+		    db_recno--;
+
+			if(db_recno EQ 0)
+			  db_recno = (UBYTE)info_field.num_records;
+		  }
+		}
+	  }
+
+	  if(buffer[4] EQ buffer[5])
+        buffer[4] = buffer[5] = 0;
+
+	  if(buffer[4] EQ db_recno)
+      {  
+		buffer[4]--;
+
+        if(buffer[4] EQ 0)
+		  buffer[4] = (UBYTE)info_field.num_records;
+
+        while(db_read_record(pbs_data.db_handle, field_id, buffer[4], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[4]--;
+
+		  if(buffer[4] EQ 0)
+		    buffer[4] = (UBYTE)info_field.num_records;
+		}
+      }
+
+	  if(buffer[5] EQ db_recno)
+      {  
+	    buffer[5]++;
+
+		if(buffer[5] EQ info_field.num_records)
+		  buffer[5] = 1;
+
+		while(db_read_record(pbs_data.db_handle, field_id, buffer[5], 0, info_field.record_size, data) < DB_OK)
+		{  
+		  buffer[5]++;
+
+		  if(buffer[5] EQ info_field.num_records)
+		    buffer[5] = 1;
+		}
+	  }
+    }
+
+    TRACE_EVENT_P1("db_recno = %d ", db_recno);
+    TRACE_EVENT_P3("%d %d %d", buffer[0], buffer[1],buffer[2]);
+    TRACE_EVENT_P3("%d %d %d", buffer[3], buffer[4],buffer[5]);
+    /* Write data related to LDN,LMN and LRN Phonebooks to FFS */
+    if(db_write_record(pbs_data.db_handle, RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
+      return PHB_FAIL;
+  }
+	else
+  {
+		db_recno = phy_recno;
+	}
+  
+  
+  /* Delete extension records if not referenced. */
+  if(pb_sim_read_ext_record_for_delete(type, field_id, db_recno) EQ PHB_FAIL)
+	 return PHB_FAIL;
+
+  /* Delete record from FFS. */
+  if(db_delete_record(pbs_data.db_handle, field_id,db_recno) NEQ DB_OK)
+    return PHB_FAIL;
+
+  /* Get information about changed records from the database. */
+  if(db_read_change_log(pbs_data.db_handle, rec_affected) NEQ DB_OK)
+    return PHB_FAIL;
+
+  if((type NEQ LDN) AND (type NEQ LMN) AND (type NEQ LRN))
+  {
+    /* Update the sorted indexes. */
+    if(db_update_index(pbs_data.db_handle, field_id, NAME_IDX, &pb_sim_alpha_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+      return PHB_FAIL;
+
+    if(db_update_index(pbs_data.db_handle, field_id, NUMBER_IDX, &pb_sim_number_cmp, PHB_MATCH_PARTIAL) NEQ DB_OK)
+      return PHB_FAIL;
+  }
+  else
+  {
+    
+    if(rec_affected->entries NEQ 0)
+    {
+      /* Remove RDM data record from the list */
+      rec_affected->entries -= 2;
+  
+      /* Remove the record from the list */
+      memmove (&rec_affected->field_id[0],
+           &rec_affected->field_id[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+      memmove (&rec_affected->record[0],
+           &rec_affected->record[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+
+    /* Remove the record from the list */
+      memmove (&rec_affected->field_id[0],
+           &rec_affected->field_id[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+      memmove (&rec_affected->record[0],
+           &rec_affected->record[1],
+           sizeof (USHORT) * (DB_MAX_AFFECTED - 1));
+    }   
+
+    TRACE_EVENT_P1("rec-affected = %d", rec_affected->entries);
+  }
+  
+  return PHB_OK;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_record  |
++--------------------------------------------------------------------+
+
+    PURPOSE : Read a given physical record from the flash based phonebook.
+*/
+
+T_PHB_RETURN pb_sim_read_record (T_PHB_TYPE type, USHORT phy_recno, T_PHB_RECORD *entry)
+{
+  USHORT field_id, ext_file_id;
+  USHORT db_recno;
+  T_DB_INFO_FIELD info_field;
+  UBYTE   buffer[RDM_PHB_DATA_SIZE];
+  UBYTE data[SIM_MAX_RECORD_SIZE], *ptr;
+  UBYTE max_tag_len;
+  UBYTE ext_rcd_num;
+
+  TRACE_FUNCTION("pb_sim_read_record()");
+
+  /* Handling of ECC Phonebook */
+  if(type EQ ECC)
+  {
+    if((phy_recno > 0 ) AND (phy_recno <= MAX_ECC_RCD))
+    {
+      entry->phy_recno = phy_recno;
+      memcpy(entry->number, phb_ecc_element[phy_recno - 1].number, ECC_NUM_LEN);  
+      return PHB_OK;
+    }
+    else
+      return PHB_FAIL;
+  }
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  /* Read record from the database. */
+  if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+    return PHB_FAIL;
+  
+	/* Information for handling Cyclic RDM Records 
+    ----------------------------------------
+          buffer[0] ---> Most Recent in LDN
+          buffer[1] ---> Oldest in LDN
+          buffer[2] ---> Most Recent in LMN
+          buffer[3] ---> Oldest in LMN
+          buffer[4] ---> Most Recent in LRN
+          buffer[5] ---> Oldest in LRN
+    ---------------------------------------- */
+
+  /* Handling of LDN, LMN and LRN Phonebook records.  */
+  if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+  {
+    /* Read data related to LDN,LMN and LRN Phonebooks from FFS */
+    if(db_read_record(pbs_data.db_handle, 
+        RDM_DATA_FILE_ID, 1, 0, RDM_PHB_DATA_SIZE, (UBYTE *) buffer) < DB_OK)
+      return PHB_FAIL;
+
+    /* Since LDN, LMN and LRN records are circular entries, 
+           most recent will be the 1st record and 
+              entries increase towards the oldest one for Reading.   */
+    if(type EQ LDN)
+    {
+      if(buffer[0] EQ 0)
+        buffer[0] = 1; 
+
+      db_recno =  buffer[0] - phy_recno + 1;
+      db_recno = db_recno % (info_field.num_records);
+
+      if(db_recno EQ 0)
+        db_recno = (info_field.num_records);
+    }
+
+    if(type EQ LMN)
+    {
+      if(buffer[2] EQ 0)
+        buffer[2] = 1; 
+
+      db_recno =  buffer[2] - phy_recno + 1;
+      db_recno = db_recno % (info_field.num_records);
+
+      if(db_recno EQ 0)
+        db_recno = (info_field.num_records);
+    }
+
+    if(type EQ LRN)
+    {
+      if(buffer[4] EQ 0)
+        buffer[4] = 1; 
+
+      db_recno =  buffer[4] - phy_recno + 1;
+      db_recno = db_recno % (info_field.num_records);
+
+      if(db_recno EQ 0)
+        db_recno = (info_field.num_records);
+    }
+  }
+  else
+    db_recno = phy_recno;
+
+  TRACE_EVENT_P2("db_recno = %d phy_recno = %d",db_recno, phy_recno);
+  TRACE_EVENT_P3("%d %d %d", buffer[0], buffer[1],buffer[2]);
+  TRACE_EVENT_P3("%d %d %d", buffer[3], buffer[4],buffer[5]);
+    
+
+  if(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+    return PHB_FAIL;
+
+  /* Convert SIM data to the type T_PHB_RECORD. */
+  ptr = data;
+  max_tag_len = MINIMUM ((info_field.record_size) - pb_sim_get_size_except_tag(field_id), PHB_MAX_TAG_LEN);
+
+  entry->phy_recno = phy_recno;
+  entry->tag_len = (UBYTE)pb_sim_get_entry_len(ptr, max_tag_len);
+
+  memset(entry->tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+  memcpy ( (char*)entry->tag, (char*)ptr, entry->tag_len );
+
+  ptr += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+
+  max_tag_len = (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+  
+  entry->len     = *ptr - 1;
+  ++ptr;
+  entry->ton_npi = *ptr;
+  ++ptr;
+  
+  memset(entry->number, 0xFF, PHB_PACKED_NUM_LEN);
+  memcpy( (char*)entry->number, (char*)ptr, entry->len );
+  ptr += 10;
+  entry->cc_id     = *ptr;
+  ++ptr;
+
+  /* Copy data specific to records of LDN, LMN, and LRN phonebook types. */ 
+  if((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN))
+  {
+    entry->v_time = 1;
+    
+    entry->time.year=data[max_tag_len+14] ;
+    entry->time.month=data[max_tag_len+15];
+    entry->time.day=data[max_tag_len+16];
+    entry->time.hour=data[max_tag_len+17] ;
+    entry->time.minute= data[max_tag_len+18];
+    entry->time.second=data[max_tag_len+19] ;
+    entry->time.time_zone=data[max_tag_len+20];
+
+    entry->time.duration = (data[max_tag_len+21] << 16) +
+                           (data[max_tag_len+22] << 8) +
+                           (data[max_tag_len+23] );
+
+    entry->v_line = 1;
+    entry->line=data[max_tag_len+24];
+
+  }
+
+  if (*ptr NEQ 0xFF) /* check for extention records */
+  {
+    ext_rcd_num =(UBYTE)*ptr;
+
+    if(db_info_field(pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
+      return PHB_FAIL;
+
+    /* Reset pointer to start location. */
+    ptr = data;
+
+    memset(ptr, 0xFF, info_field.record_size);
+
+    if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, ptr) < DB_OK) 
+      return PHB_FAIL;
+    
+    pb_sim_read_ext(ptr, entry);
+
+    while(*(ptr + 12) NEQ 0xFF) /* check if a further EXT entry exists */
+    {
+      memset(ptr, 0xFF, info_field.record_size);
+
+      db_read_record(pbs_data.db_handle, ext_file_id, (USHORT)*(ptr+12), 0, info_field.record_size,ptr); 
+
+      pb_sim_read_ext(ptr, entry);     
+    }
+  }
+  
+  return PHB_OK;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_alpha_record      |
++--------------------------------------------------------------------+
+
+    PURPOSE : Read a given physical record from the flash based phonebook in alphabetical order.
+*/
+
+T_PHB_RETURN pb_sim_read_alpha_record   (T_PHB_TYPE type, USHORT order_num, T_PHB_RECORD *entry)
+{
+  int db_result;
+  USHORT field_id, ext_file_id;
+  
+  TRACE_FUNCTION("pb_sim_read_alpha_record()");
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  /* Read record from the FFS. */
+  db_result = db_get_phy_from_idx(pbs_data.db_handle, field_id, NAME_IDX, order_num);
+
+  if(db_result > DB_OK)
+  {
+    return pb_sim_read_record(type, (USHORT)db_result, entry) ;
+  }
+
+  /* Check whether index is vaild. */
+  if(db_result EQ DB_INVALID_INDEX)
+    return PHB_INVALID_IDX;
+
+  /* Unable to get record from the database. Hence returning PHB_FAIL. */
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_number_record       |
++--------------------------------------------------------------------+
+
+    PURPOSE : Read a given physical record from the flash based phonebook in number sorted order.
+*/
+
+T_PHB_RETURN pb_sim_read_number_record  (T_PHB_TYPE type, USHORT order_num, T_PHB_RECORD *entry)
+{
+  int db_result;
+  USHORT field_id, ext_file_id;
+  
+  TRACE_FUNCTION("pb_sim_read_number_record()");
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  /* Read record from the FFS. */
+  db_result = db_get_phy_from_idx(pbs_data.db_handle, field_id, NUMBER_IDX, order_num);
+
+  if(db_result > DB_OK)
+  {
+    return pb_sim_read_record(type, (USHORT)db_result, entry) ;
+  }
+  else if(db_result EQ DB_INVALID_INDEX)
+    return PHB_INVALID_IDX;
+  else
+    return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_search_name        |
++--------------------------------------------------------------------+
+
+    PURPOSE : Finds the first entry matching the search tag.
+*/
+
+T_PHB_RETURN pb_sim_search_name (T_PHB_TYPE type, T_PHB_MATCH match, const T_ACI_PB_TEXT *search_tag, SHORT *order_num)
+{
+  T_ACI_PB_TEXT key;
+  int res;
+  USHORT field_id, ext_file_id;
+  
+  TRACE_FUNCTION("pb_sim_search_name()");
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  key.len = search_tag->len;
+  key.cs  = search_tag->cs;
+  pb_sim_cvt_alpha_for_cmp ((UBYTE*) search_tag->data, (UBYTE*) key.data, search_tag->len);
+
+  res = db_search(pbs_data.db_handle, field_id, NAME_IDX, (UBYTE*) order_num, pb_sim_search_alpha_func, match, (const UBYTE*)&key);
+
+  if(res > DB_OK)
+  {
+    return PHB_OK;
+  }
+
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_search_number         |
++--------------------------------------------------------------------+
+
+    PURPOSE : Finds the first entry matching the number.
+*/
+
+T_PHB_RETURN pb_sim_search_number   (T_PHB_TYPE type, const UBYTE *number, SHORT *order_num)
+{
+  int res, i;
+  CHAR  cur_number[MAX_PHB_NUM_LEN];
+  CHAR  rev_number[MAX_PHB_NUM_LEN];
+  int cmpLen, cmp_res;
+  USHORT field_id, ext_file_id;
+   
+  TRACE_FUNCTION("pb_sim_search_number()");
+
+  /* Handling for ECC Phonebook. */
+  if(type EQ ECC)
+  {
+    for(i = 0; i < pbs_data.max_record[ECC]; i++)
+    {
+
+      cmhPHB_getAdrStr(cur_number, MAX_PHB_NUM_LEN - 1,phb_ecc_element[i].number,pbs_data.record_size[ECC]);
+  
+      pb_sim_revString(cur_number);
+
+      strcpy( rev_number,(const char*)number);
+
+      pb_sim_revString(rev_number);
+
+      cmpLen = MINIMUM(strlen((const char*) cur_number), strlen((const char*)number));
+
+      cmp_res = pb_sim_cmpString((UBYTE*)cur_number, (UBYTE*)rev_number, cmpLen);
+
+      if(cmp_res NEQ 0)
+        return PHB_FAIL;
+      else
+      {
+				return PHB_OK;
+      }
+    }
+  }
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+
+  TRACE_EVENT_P2("type = %d field_id = %x", type, field_id);
+
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  res = db_search(pbs_data.db_handle, field_id, NUMBER_IDX, (UBYTE*)order_num, &pb_sim_search_num_func, PHB_MATCH_PARTIAL, number);
+
+  if(res > DB_OK)
+  {
+    return PHB_OK;
+  }
+
+  return PHB_FAIL;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_sizes          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Reads the sizes of a given phonebook.
+*/
+
+T_PHB_RETURN pb_sim_read_sizes  (T_PHB_TYPE type, SHORT      *max_rcd, SHORT      *used_rcd, UBYTE      *tag_len)
+{
+  T_DB_INFO_FIELD info_field;
+  USHORT field_id;
+  int db_result;
+
+  TRACE_FUNCTION("pb_sim_read_sizes()");
+
+  /* Handling for ECC Phonebook */
+  if(type EQ ECC)
+  {
+    *max_rcd = pbs_data.max_record[ECC];
+    *used_rcd = pbs_data.used_record[ECC];
+    *tag_len = 0; /* To Do:Alpha tag will not be there for ECC. So assigning zero here */
+    return PHB_OK;
+  }
+  
+
+  /* Get Elementary file ID for the Phonebook type. */
+  field_id = pb_sim_get_field_id(type);
+
+  db_result = db_info_field(pbs_data.db_handle, field_id, &info_field);
+  
+  TRACE_EVENT_P1("db_result = %d", db_result);
+
+  if(db_result EQ DB_OK)
+  {
+    *max_rcd  = info_field.num_records;
+    *used_rcd = info_field.used_records;
+    *tag_len  = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+    return PHB_OK;
+  }
+
+  return PHB_FAIL;
+  
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_get_entry_len          |
++--------------------------------------------------------------------+
+
+    PURPOSE : Used to get the length in bytes of a given entry which is coded as given in 11.11 Annex B.
+*/
+
+int pb_sim_get_entry_len    (const UBYTE *pb_tag, UBYTE max_pb_len)
+{
+  
+  int   pb_len    = 0;
+  UBYTE inc_count = 1;
+  BOOL  ucs2      = FALSE;
+  UBYTE chars = 0;
+
+  TRACE_FUNCTION("pb_sim_get_entry_len()");
+
+  if (*pb_tag EQ 0x80)
+  {
+    ucs2 = TRUE;
+    inc_count = 2;              /* check two bytes */
+    pb_len = 1;                 /* skip the 0x80 */
+  }
+  else if (*pb_tag EQ 0x81 OR *pb_tag EQ 0x82)
+  {
+    if (*pb_tag EQ 0x81)
+      pb_len = 3;                 /* 0x80 + len + pointer */
+    else
+      pb_len = 4;                 /* 0x80 + len + 2xpointer */
+
+    chars = pb_tag[1];
+    pb_tag += pb_len;                  /* go to data */
+    while (chars)
+    {
+      if (*pb_tag++ & 0x80)
+        pb_len+=2;
+      else
+        pb_len+=1;
+
+      pb_tag++;
+      chars--;
+    }
+    return MINIMUM(pb_len,max_pb_len);
+  }
+
+  while (pb_len < max_pb_len)
+  {
+    if (ucs2 EQ TRUE)
+    {
+      if (!(pb_len+1 < max_pb_len)) /* Check also if we traverse the upper bound */
+        break;                      /* so only a "half" UCS2 element is remaining */
+    }
+    if (pb_tag[pb_len] EQ 0xFF)
+    { 
+      /* one 0xFF indicates the end of a non UCS2 string */
+      if (ucs2 EQ FALSE)
+      {
+        break;
+      }
+      /* two 0xFF indicates the end of a UCS2 string */
+      if (pb_tag[pb_len + 1] EQ 0xFF)
+      {
+        break;
+      }
+    }
+    pb_len += inc_count;
+  }
+
+  return (pb_len);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_alpha_cmp           |
++--------------------------------------------------------------------+
+
+    PURPOSE : Compares alpha identifier of two records.
+*/
+int pb_sim_alpha_cmp (int db_handle, USHORT field_id, USHORT recno_1, USHORT recno_2, ULONG flags)
+{
+  T_PHB_RECORD entry_1,entry_2;
+  UBYTE cmpLen = 0;
+  UBYTE *buffer;
+  UBYTE max_tag_len;
+  UBYTE cur_tag[PHB_MAX_TAG_LEN], check_tag[PHB_MAX_TAG_LEN];
+  int   cmp_res;
+  T_DB_INFO_FIELD info_field;
+  
+  TRACE_FUNCTION("pb_sim_alpha_cmp()");
+
+  
+  db_info_field(db_handle, field_id, &info_field);
+
+  MALLOC(buffer, info_field.record_size);
+
+  /* Read the first record. */
+  db_read_record(db_handle, field_id, recno_1, 0, info_field.record_size, buffer);
+
+  /* Unpack record 1 to do a string comparison on the alpha identifier field */
+  max_tag_len = MINIMUM ( (info_field.record_size) - pb_sim_get_size_except_tag(field_id), 
+                                            PHB_MAX_TAG_LEN);
+  entry_1.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
+  
+  memset(entry_1.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+  memcpy ( (char*)entry_1.tag, (char*)buffer, entry_1.tag_len );
+
+  pb_sim_cvt_alpha_for_cmp ( entry_1.tag, cur_tag, entry_1.tag_len );
+
+  memset(buffer, 0, info_field.record_size);
+
+  /* Read the second record. */
+  db_read_record(db_handle, field_id, recno_2, 0, info_field.record_size, buffer);
+
+  /* Unpack record 2 to do a string comparison on the alpha identifier field */
+  max_tag_len = MINIMUM ((info_field.record_size) - pb_sim_get_size_except_tag(field_id), 
+                                           PHB_MAX_TAG_LEN);
+  entry_2.tag_len = (UBYTE)pb_sim_get_entry_len(buffer, max_tag_len);
+  
+  memset(entry_2.tag, 0xFF, PHB_MAX_TAG_LEN); /* init the tag value */
+  memcpy ( (char*)entry_2.tag, (char*)buffer, entry_2.tag_len );
+
+  pb_sim_cvt_alpha_for_cmp ( entry_2.tag, check_tag, entry_2.tag_len );
+
+  cmpLen = MINIMUM ( entry_1.tag_len,
+                           entry_2.tag_len );
+
+  TRACE_EVENT_P1("%d", cmpLen);
+      
+  cmp_res = pb_sim_cmpString ( cur_tag, check_tag, cmpLen );
+
+	if (cmp_res EQ 0) 
+  {
+    /* Correct result when length was different, ACIPHB201 */
+    if (entry_1.tag_len < entry_2.tag_len)
+      cmp_res = -1;
+    else if (entry_1.tag_len > entry_2.tag_len)
+      cmp_res = 1;
+  }
+
+  MFREE(buffer);
+
+  return cmp_res;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_number_cmp     |
++--------------------------------------------------------------------+
+
+    PURPOSE : Compares two numbers of two records.
+*/
+int pb_sim_number_cmp (int db_handle,
+                                USHORT field_id, 
+                                USHORT recno_1, 
+                                USHORT recno_2,
+                        ULONG  flags)
+{
+  T_PHB_RECORD entry_1,entry_2;
+  T_DB_INFO_FIELD info_field;
+  UBYTE cmpLen = 0;
+  UBYTE *buffer, *tmp_buffer;
+  UBYTE ext_rcd_num;
+  UBYTE max_tag_len;
+  CHAR           cur_number[MAX_PHB_NUM_LEN];
+  CHAR           ref_number[MAX_PHB_NUM_LEN];
+  int   cmp_res;
+  USHORT file_id;
+
+  TRACE_FUNCTION("pb_sim_number_cmp()");
+
+  MALLOC(buffer, sizeof(T_PHB_RECORD));
+
+  /* Store pointer to free the memory allocation. */
+  tmp_buffer = buffer;
+
+  memset(buffer,0xFF,sizeof(T_PHB_RECORD));
+
+  db_info_field(db_handle, field_id, &info_field);
+  
+  /* Read record recno_1 from the database using db_read_record() */
+  db_read_record(db_handle, field_id, recno_1, 0, info_field.record_size, buffer);
+
+  /* Read only number from the buffer. */
+  
+  buffer += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+  entry_1.len     = *(buffer++) - 1;
+  entry_1.ton_npi = *buffer++;
+  
+  memset(entry_1.number, 0xFF, PHB_PACKED_NUM_LEN);
+  memcpy( (char*)entry_1.number, (char*)buffer, entry_1.len );
+  buffer += 10; 
+  entry_1.cc_id     = *buffer++;
+
+  if (*buffer != 0xFF) /* check for extention records */
+  {
+    file_id = pb_sim_get_ext_file_id(field_id);
+    if (file_id != 0xFFFF)
+    {
+      ext_rcd_num = (UBYTE)*buffer;
+
+      db_info_field(db_handle, file_id, &info_field);
+      
+      /* Set the buffer to starting location. */
+      buffer = tmp_buffer;
+
+      memset(buffer, 0xFF, info_field.record_size);
+
+      db_read_record(db_handle, file_id, ext_rcd_num, 0, info_field.record_size,buffer);
+
+      pb_sim_read_ext(buffer, &entry_1);
+
+      while(*(buffer + 12) NEQ 0xFF)
+      {
+        memset(buffer, 0xFF, info_field.record_size);
+        db_read_record(db_handle, file_id, *(buffer + 12), 0, info_field.record_size,buffer);
+        pb_sim_read_ext(buffer, &entry_1);
+      }
+    }
+  }
+
+  /* Set the buffer to starting location. */
+  buffer = tmp_buffer;
+
+  memset(buffer, 0xFF, sizeof(T_PHB_RECORD));
+   
+  /* Read record recno_2 from the database using db_read_record() */
+  db_read_record(db_handle, field_id, recno_2, 0, info_field.record_size, buffer);
+
+  max_tag_len = info_field.record_size - pb_sim_get_size_except_tag(field_id);
+  /* Read only number from the buffer. */
+  buffer += max_tag_len;
+  entry_2.len     = *(buffer++) - 1;
+  entry_2.ton_npi = *buffer++;
+  
+  memset(entry_2.number, 0xFF, PHB_PACKED_NUM_LEN);
+  memcpy( (char*)entry_2.number, (char*)buffer, entry_2.len );
+  buffer += 10; 
+  entry_2.cc_id     = *buffer++;
+
+  if (*buffer != 0xFF) /* check for extention records */
+  {
+    if (file_id != 0xFFFF)
+    {
+      ext_rcd_num = (UBYTE)*buffer;
+      
+      /* Set the buffer to starting location. */
+      buffer = tmp_buffer;
+
+      memset(buffer, 0xFF,info_field.record_size);
+      
+      db_read_record(db_handle, file_id, ext_rcd_num, 0, info_field.record_size,buffer); 
+
+      pb_sim_read_ext(buffer, &entry_2);
+
+      while(*(buffer + 12) NEQ 0xFF)
+      {
+        memset(buffer, 0xFF,info_field.record_size);
+        db_read_record(db_handle, file_id, *(buffer + 12), 0, info_field.record_size,buffer);
+        pb_sim_read_ext(buffer, &entry_2);
+      }
+    }
+  }
+ 
+  cmhPHB_getAdrStr(cur_number,
+        MAX_PHB_NUM_LEN - 1,
+        entry_1.number,
+        entry_1.len);
+  cmhPHB_getAdrStr(ref_number,
+        MAX_PHB_NUM_LEN - 1,
+        entry_2.number,
+        entry_2.len);
+
+  /* Reverse the first number to compare number from right. */
+  pb_sim_revString(cur_number);
+
+  /* Reverse the second number to compare number from right. */
+  pb_sim_revString(ref_number);
+  
+  cmp_res = strcmp((char *)cur_number, (char *)ref_number);
+
+  MFREE(tmp_buffer);
+  return cmp_res;
+  
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_read_ext     |
++--------------------------------------------------------------------+
+
+    PURPOSE : Reads extension records from the database and copies them to number.
+*/
+/* Extesion records will be stored as per 11.11.
+          Bytes         Description      M/O    Length
+          --------------------------------------
+              1        Record type         M    1 byte
+           2 to 12  Extension data  M   11 bytes
+             13        Identifier                 M 1 byte
+          --------------------------------------*/
+
+void pb_sim_read_ext(UBYTE *buffer, T_PHB_RECORD *entry)
+{
+  UBYTE data_len;
+  UBYTE data_type;
+  UBYTE *data;
+  
+  TRACE_FUNCTION("pb_sim_read_ext()");
+
+  /* If this extension record is not empty, it is written in phonebook. */
+  data = buffer;
+ 
+  data_type = *data;
+  data_len = *(data+1);
+
+  switch (data_type)
+  {
+   
+    case 1: /* Called Party Subaddress */
+    {
+			int sa_len = 0;
+      while (sa_len<PHB_PACKED_NUM_LEN)  /* get length of possible already stored subaddr if more than one EXT is used */
+      {
+        if (entry->subaddr[sa_len] EQ 0xFF)
+					break;
+        else if ((entry->subaddr[sa_len] & 0xF0) EQ 0xF0)
+        {
+          sa_len++;
+          break;
+        }
+        else
+          sa_len++;
+      }
+
+      pb_sim_nibblecopy (entry->subaddr,
+                         sa_len,
+                         data + 2,
+                         data_len);
+    }
+    break;
+        
+    case 2: /* Additional data */
+      entry->len =
+      pb_sim_nibblecopy (entry->number,
+                         entry->len,
+                         data + 2,
+                         data_len);
+      break;
+
+      default: /* unknown type */
+        break;
+  }
+
+  return;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_revString                      |
++--------------------------------------------------------------------+
+
+    PURPOSE : Reverses a string within the same variable.
+*/
+
+void pb_sim_revString(char *str)
+{
+  UBYTE i, j,str_len;
+  char ch;
+
+  TRACE_FUNCTION("pb_sim_revString()");
+
+  str_len = strlen(str);
+  
+  for(i = 0, j = str_len - 1;i < (str_len / 2); i++, j--)
+  {
+    ch = *(str + i);
+    *(str + i) = *(str + j);
+    *(str + j) = ch;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_search_alpha_func                      |
++--------------------------------------------------------------------+
+
+    PURPOSE : Searches for a given alpha key in the database.
+*/
+
+int pb_sim_search_alpha_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num)
+{
+  T_ACI_PB_TEXT *search_key;
+  T_PHB_RECORD entry;
+  UBYTE cmpLen = 0;
+  T_PHB_TYPE phb_type;
+  UBYTE cur_tag[PHB_MAX_TAG_LEN];
+  int   cmp_res;
+
+  TRACE_FUNCTION("pb_sim_search_alpha_func()");
+
+  /* Cast search key to appropriate data structure */
+  search_key = (T_ACI_PB_TEXT *)key;
+
+  /* Get PHB type from field ID using PHB_ACI function. */ 
+  phb_type = pb_get_phb_type_from_ef(field_id);
+
+  /* Read record from the database. */
+  pb_sim_read_record(phb_type, rec_num, &entry);
+	
+  pb_sim_cvt_alpha_for_cmp ( entry.tag, cur_tag, entry.tag_len );
+
+  cmpLen = search_key->len;
+  
+  if(flags EQ PHB_MATCH_PARTIAL)
+    cmpLen = MINIMUM ( entry.tag_len, cmpLen);
+
+  TRACE_EVENT_P1( "cmpLen=%d", cmpLen );
+      
+  cmp_res = pb_sim_cmpString ( cur_tag, search_key->data, cmpLen );
+  
+  return cmp_res;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_search_num_func                      |
++--------------------------------------------------------------------+
+
+    PURPOSE : Searches for a given number key in the database.
+*/
+int pb_sim_search_num_func(ULONG flags, const UBYTE *key, int db_handle, USHORT field_id, USHORT rec_num)
+{
+  T_PHB_RECORD entry;
+  UBYTE cmpLen = 0;
+  T_PHB_TYPE phb_type;
+  CHAR  cur_number[MAX_PHB_NUM_LEN];
+  CHAR  rev_key[MAX_PHB_NUM_LEN];
+  int   cmp_res;
+   
+  TRACE_FUNCTION("pb_sim_search_num_func()");
+
+  /* Get PHB type from field ID using PHB_ACI function. */ 
+  phb_type = pb_get_phb_type_from_ef(field_id);
+
+  /* Read record from the database. */
+  if(pb_sim_read_record(phb_type, rec_num, &entry) NEQ PHB_OK)
+    return -1;
+	
+  cmhPHB_getAdrStr(cur_number,
+        MAX_PHB_NUM_LEN - 1,
+        entry.number,
+        entry.len);
+  
+  /* Reverse the first number to compare number from right. */
+  pb_sim_revString(cur_number);
+
+  /* Reverse the second number to compare number from right. */
+  
+  strcpy (rev_key, (const char*) key);
+  
+  pb_sim_revString(rev_key);
+
+  cmpLen = strlen(rev_key);
+
+  if(flags EQ PHB_MATCH_PARTIAL)
+    cmpLen = MINIMUM(strlen(cur_number), cmpLen);
+  
+  TRACE_EVENT_P1("Number to be compared: %s", cur_number);
+  TRACE_EVENT_P1("Number to be searched: %s", rev_key);
+    
+  cmp_res = pb_sim_cmpString((UBYTE*)cur_number, (UBYTE*)rev_key, 7);
+
+  TRACE_EVENT_P1("Result of the comparison: %d", cmp_res);
+
+  return cmp_res;
+  
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417)         MODULE: PHB                  |
+| STATE  : code                         ROUTINE: pb_sim_nibblecopy                      |
++--------------------------------------------------------------------+
+
+    PURPOSE : Used to convert BCD nibbles to string.
+*/
+    
+LOCAL int pb_sim_nibblecopy (UBYTE dest[], int destlen, UBYTE src[], int count)
+{
+
+  int i;
+  int nibble;
+
+  int destnibble=destlen*2;
+
+  TRACE_FUNCTION("pb_sim_nibblecopy()");
+
+  if (destnibble)
+  {
+    if ((dest[destlen-1] & 0xF0) == 0xF0)    /* check if there is space in last nibble */
+      destnibble--;
+  }
+
+  for ( i=0; i<count*2; i++ )
+  {
+    /* check if we access out of bounds */
+    if (destnibble/2 >= PHB_PACKED_NUM_LEN)
+      return PHB_PACKED_NUM_LEN;
+
+    /* get nibble */
+    if (i%2 == 0)
+      nibble = src[i/2] & 0x0F;
+    else
+      nibble = (src[i/2] & 0xF0) >> 4;
+
+    if (nibble == 0xF)      /* end of number detected */
+      break;
+
+    /* put nibble */
+    if (destnibble%2 == 0)
+    {
+      dest[destnibble/2] &= 0xF0;
+      dest[destnibble/2] |= nibble;
+    }
+    else
+    {
+      dest[destnibble/2] &= 0x0F;
+      dest[destnibble/2] |= nibble << 4;
+    }
+
+    destnibble++;
+  }
+  return destnibble/2 + destnibble%2; /* round up */
+}
+
+/*
++------------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)         MODULE: PHB                     |
+| STATE   : code                         ROUTINE : pb_sim_read_eeprom_ecc    |
++------------------------------------------------------------------------+
+
+  PURPOSE : Read EC number from EEPROM.
+
+*/
+LOCAL void pb_sim_read_eeprom_ecc (void)
+{
+  EF_ECC       efecc;
+  UBYTE        *data_ptr;
+  UBYTE        version;
+  int          rec_ctr;
+
+  TRACE_FUNCTION("pb_sim_read_eeprom_ecc()");
+
+  /* Initialise ECC Phonebook Info. */
+  pbs_data.max_record[ECC] = MAX_ECC_RCD;
+  pbs_data.used_record[ECC] = 0;
+
+  if (pcm_ReadFile((UBYTE *)EF_ECC_ID,
+                    SIZE_EF_ECC,
+                    (UBYTE *)&efecc,
+                    &version) EQ DRV_OK)
+  {   
+    { /* workaround when invalid data stored on PCM */
+      CHAR  ecc_number[MAX_PHB_NUM_LEN];
+      int   num_len;
+
+      data_ptr = efecc.ecc1;
+      
+      for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
+      {
+        if (*data_ptr NEQ 0xFF)
+        {
+          cmhPHB_getAdrStr (ecc_number,
+                            MAX_PHB_NUM_LEN - 1,
+                            data_ptr,
+                            ECC_NUM_LEN);
+          for (num_len = 0; num_len < ECC_NUM_LEN; num_len++)
+          {
+            if (!isdigit (ecc_number[num_len]))
+            {
+              TRACE_EVENT_P2 ("[ERR] pb_read_eeprom_ecc(): invalid character found %c (%d)",
+                              ecc_number[num_len], rec_ctr);
+              return;
+            }
+          }
+        }
+        data_ptr += ECC_NUM_LEN;
+      }
+    } /* workaround end */  
+    
+    data_ptr = &efecc.ecc1[0];
+
+    memset( phb_ecc_element,0, (pbs_data.max_record[ECC] * sizeof(T_PHB_ECC_RECORD)) );
+
+    for (rec_ctr=0; rec_ctr < pbs_data.max_record[ECC]; rec_ctr++)
+    {
+      if(*data_ptr NEQ 0xff)
+      {
+        phb_ecc_element[rec_ctr].phy_idx = rec_ctr + 1;
+        memcpy(phb_ecc_element[rec_ctr].number, data_ptr, ECC_NUM_LEN);
+        data_ptr += ECC_NUM_LEN;
+        (pbs_data.used_record[ECC])++;
+      }
+    }
+  }
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT :                              MODULE  : PHB                 |
+| STATE   : code                         ROUTINE : pb_sim_prepare_ext_data |
++----------------------------------------------------------------------+
+
+
+    PURPOSE :   Prepare the data for the extention record.
+                If NULL pointer is given for number and subaddress
+                then the extention record will marked as unused
+
+*/
+/* Extesion records will be stored as per 11.11.
+          Bytes         Description      M/O    Length
+          --------------------------------------
+              1        Record type         M    1 byte
+           2 to 12  Extension data  M   11 bytes
+             13        Identifier                 M 1 byte
+          --------------------------------------*/
+
+LOCAL void pb_sim_prepare_ext_data(UBYTE *ext_data, int ext_count, UBYTE *number, UBYTE no_len, UBYTE *subaddr)
+{
+  UBYTE *data_num = NULL;
+  UBYTE *data_subadd = NULL;
+
+  TRACE_FUNCTION("pb_sim_prepare_ext_data()");
+
+  if(number[10] NEQ 0xFF)
+    data_num = number + ((ext_count + 1) * 10);
+  
+  data_subadd = subaddr + (ext_count * 11);
+  
+  memset(ext_data, 0xFF, sizeof(ext_data));
+
+  if ((data_num NEQ NULL) AND (*data_num NEQ 0xFF))
+  {
+    /* Set record type to 2 which corresponds to Additional data.  Record type as per 11.11 */
+    ext_data[0] = 2;
+    ext_data[1] = no_len - ((ext_count + 1) * 10);
+    memcpy (ext_data + 2, data_num, 10);
+  }
+  else if ((data_subadd NEQ NULL) AND (*data_subadd NEQ 0xFF))
+  {
+    TRACE_EVENT ("SUBADDRESS EXTENTION");
+	 /* Set record type to 1 which corresponds to Called Party Subaddress. Record type as per 11.11 */
+    ext_data[0] = 1;
+    memcpy (ext_data + 1, data_subadd, 11);
+  }
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT :                              MODULE  : PHB                 |
+| STATE   : code                         ROUTINE : pb_sim_get_field_id |
++----------------------------------------------------------------------+
+
+
+    PURPOSE :   Returns field ID for the corresponding Phonebook type.
+
+*/
+LOCAL USHORT pb_sim_get_field_id (T_PHB_TYPE type)
+{
+  USHORT field_id;
+
+  TRACE_FUNCTION("pb_sim_get_field_id()");
+
+  /* Get Elementary file ID for the Phonebook type. */
+  switch(type)
+  {
+    case ADN:
+      field_id = SIM_ADN;
+      break;
+
+    case LDN:
+      field_id = SIM_OCI;
+      break;
+
+    case LRN:
+      field_id = FFS_LRN;
+      break;
+
+    case LMN:
+      field_id = FFS_LMN;
+      break;
+
+    case UPN:
+      field_id = SIM_MSISDN;
+      break;
+
+    case FDN:
+      field_id = SIM_FDN;
+      break;
+
+    case SDN:
+      field_id = SIM_SDN;
+      break;
+
+    case BDN:
+      field_id = SIM_BDN;
+      break;
+
+    default:
+      TRACE_ERROR ("No such field");
+      field_id = 0;
+      break;
+  }
+
+  return field_id;
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT :                              MODULE  : PHB                 |
+| STATE   : code                         ROUTINE : pb_sim_get_ext_file |
++----------------------------------------------------------------------+
+
+
+    PURPOSE :   Returns field ID for the corresponding Phonebook type.
+
+*/
+LOCAL USHORT pb_sim_get_ext_file (T_PHB_TYPE type)
+{
+  USHORT ext_file_id;
+
+  TRACE_FUNCTION("pb_sim_get_ext_file()");
+
+  /* Get Extension Elementary file ID for the Phonebook type. */
+  switch(type)
+  {
+    case ADN:
+    case UPN:
+      ext_file_id = SIM_EXT1;
+      break;
+
+    case FDN:
+      ext_file_id = SIM_EXT2;
+      break;
+
+    case SDN:
+      ext_file_id = SIM_EXT3;
+      break;
+
+    case BDN:
+      ext_file_id = SIM_EXT4;
+      break;
+
+    case LDN:
+      ext_file_id = SIM_EXT5;
+      break;
+
+    case LRN:
+      ext_file_id = FFS_EXT_LRN;
+      break;
+
+    case LMN:
+      ext_file_id = FFS_EXT_LMN;
+      break;
+
+    default:
+      ext_file_id = 0; /* Avoid lint warning */
+      break;
+  }
+
+  return ext_file_id;
+}
+
+/*
++---------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)       MODULE  : PHB                  |
+| STATE   : code                       ROUTINE : pb_sim_cvt_alpha_for_cmp |
++---------------------------------------------------------------------+
+
+  PURPOSE : convert alpha to lower case when not unicode
+
+*/
+LOCAL void pb_sim_cvt_alpha_for_cmp ( UBYTE *src,
+                                      UBYTE *dst,
+                                      UBYTE len )
+{
+  int i;
+
+  TRACE_FUNCTION("pb_sim_cvt_alpha_for_cmp()");
+
+  if (*src NEQ 0x80) /* 11.11 Annex B 0x80 is the UCS2 indicator */
+  {
+    for ( i = 0; i < len; i++ )
+      dst[i] = (UBYTE)tolower((int)src[i]);
+  }
+  else
+  {
+    memcpy (dst, src, len);
+  }
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT :                              MODULE  : PHB                 |
+| STATE   : code                         ROUTINE : pb_sim_get_ext_file_id                           |
++----------------------------------------------------------------------+
+
+
+    PURPOSE :   Returns Extension field ID for the corresponding field ID of a Phonebook.
+
+*/
+LOCAL USHORT pb_sim_get_ext_file_id (USHORT field_id)
+{
+  USHORT ext_file_id;
+
+  TRACE_FUNCTION("pb_sim_get_ext_file_id()");
+
+  /* Get Extension Elementary file ID for the Phonebook type. */
+  switch(field_id)
+  {
+    case SIM_ADN:
+    case SIM_LND:
+    case SIM_MSISDN:
+      ext_file_id = SIM_EXT1;
+      break;
+
+    case SIM_FDN:
+      ext_file_id = SIM_EXT2;
+      break;
+
+    case SIM_SDN:
+      ext_file_id = SIM_EXT3;
+      break;
+
+    case SIM_BDN:
+      ext_file_id = SIM_EXT4;
+      break;
+
+    case SIM_OCI:
+      ext_file_id = SIM_EXT5;
+      break;
+
+    case FFS_LRN:
+      ext_file_id = FFS_EXT_LRN;
+      break;
+
+    case FFS_LMN:
+      ext_file_id = FFS_EXT_LMN;
+      break;
+
+    default:
+      ext_file_id = 0; /* Avoid lint warning */
+      break;
+  }
+
+  return ext_file_id;
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT :                              MODULE  : PHB                 |
+| STATE   : code                         ROUTINE : pb_sim_find_free_record                        |
++----------------------------------------------------------------------+
+
+
+    PURPOSE :   Returns free record number for the Phonebook type.
+
+*/
+GLOBAL int  pb_sim_find_free_record   (T_PHB_TYPE type)
+{
+  int db_result;
+  unsigned i;
+  USHORT field_id;
+
+  TRACE_FUNCTION("pb_sim_find_free_record()");
+
+  switch (type)
+  {
+    case ECC: /* ECC not stored in DB, special handling */
+      for (i = 0; i < pbs_data.max_record[ECC]; i++)
+      {
+        if (phb_ecc_element[i].phy_idx EQ 0)
+          return i + 1;
+      }
+      return 0; /* No free record found */
+
+    case LDN:
+    case LRN:
+    case LMN:
+      return 1; /* For cyclic entries always the first */
+
+    default:
+      /* Get Elementary file ID for the Phonebook type. */
+      field_id = pb_sim_get_field_id(type);
+
+      db_result = db_find_free_record(pbs_data.db_handle, field_id);
+      
+			if (db_result <= 0)
+        return 0; /* No free record */
+      
+			return db_result;
+  }
+}
+
+/*
++-------------------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)        MODULE  : PHB                           |
+| STATE   : code                        ROUTINE : pb_sim_get_size_except_tag    |
++-------------------------------------------------------------------------------+
+
+  PURPOSE : Returns size of data excluding length of tag (alpha identifier)
+*/
+USHORT pb_sim_get_size_except_tag (USHORT field_id)
+{
+
+  TRACE_FUNCTION("pb_sim_get_size_except_tag()");
+  switch(field_id)
+  {
+    case SIM_ADN:
+    case SIM_FDN:
+    case SIM_BDN:
+    case SIM_MSISDN:
+    case SIM_SDN:
+      return 14; /* 11.11 */
+
+    case FFS_LRN:
+    case FFS_LMN:
+    case SIM_OCI:
+      return 27; /* Using EF_OCI, 31.102 4.2.34 */
+
+    //case SIM_ICI:
+    //  return 28; /* Using EF_ICI, 31.102 4.2.33 */
+
+    default:
+      TRACE_ERROR("Invalid field ID passed !");
+      return 0;
+  }
+}
+/*
++--------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)        MODULE  : PHB                |
+| STATE   : code                        ROUTINE : pb_sim_cmpString          |
++--------------------------------------------------------------------+
+
+  PURPOSE : compare two strings.
+            if s1 < s2 return value < 0
+            if s1 = s2 return value = 0
+            if s1 > s2 return value > 0
+*/
+
+static int pb_sim_cmpString ( UBYTE *s1, UBYTE *s2, UBYTE len )
+{
+  int n = 0;
+
+  /* TRACE_FUNCTION("pb_sim_cmpString()"); */ /* Called too often to trace */
+
+  if ((*s1 EQ 0x80) AND
+      (*s2 NEQ 0x80)    )
+  {
+    s1++;
+    len--;
+    return pb_sim_cmp2Bytes(s1, s2, len, 1);
+  }
+  else if ((*s1 NEQ 0x80) AND
+           (*s2 EQ 0x80)     )
+  {
+    s2++;
+    len--;
+    return pb_sim_cmp2Bytes(s1, s2, len, 2);
+  }
+  else
+  {
+    while (*s1 EQ *s2)
+    {
+      if (*s1 EQ 0xff)
+        return 0;
+      s1++;
+      s2++;
+      n++;
+      if (n EQ len)
+        return 0;
+    }
+
+    if ((*s1 > *s2) AND (*s1 NEQ 0xff))
+      return 1;
+
+    return -1;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)        MODULE  : PHB                |
+| STATE   : code                        ROUTINE : pb_sim_cmp2Bytes       |
++--------------------------------------------------------------------+
+
+  PURPOSE : compare two strings.
+            if s1 < s2 return value < 0
+            if s1 = s2 return value = 0
+            if s1 > s2 return value > 0
+
+            flag = 1, s1 is unicode
+            flag = 2, s2 is unicode
+*/
+
+LOCAL int pb_sim_cmp2Bytes(UBYTE *s1, UBYTE *s2, UBYTE len, UBYTE flag)
+{
+  int n = 0;
+
+  /*  TRACE_FUNCTION("pb_sim_cmp2Bytes()"); */
+
+  if (flag EQ 1)
+  {
+    while ( (*s1 EQ 0x00 OR *s1 EQ 0xFF ) AND ( *(s1+1) EQ *s2) )
+    {
+      if (*s1 EQ 0xff AND *(s1+1) EQ 0xFF)
+        return 0;
+      
+			s1 += 2;
+      s2++;
+      n += 2;
+
+      if (n >= len)
+        return 0;
+    }
+
+    if ( ( *s1 > 0 AND *s1 NEQ 0xff ) OR
+         ( !*s1 AND ( *(s1+1) > *s2 ) ) )
+      return 1;
+
+    return -1;
+  }
+
+  if (flag EQ 2)
+  {
+    while ((*s2 EQ 0x00 OR *s2 EQ 0xFF) AND (*s1 EQ *(s2+1)))
+    {
+      if (*s2 EQ 0xff AND *(s2+1) EQ 0xFF)
+        return 0;
+      
+			s1++;
+      s2 += 2;
+      n += 2;
+
+      if (n >= len)
+        return 0;
+    }
+
+    if ((*s2 > 0 AND *s2 NEQ 0xff) OR
+        (!*s2 AND (*(s2+1) > *s1))    )
+      return -1;
+
+    return 1;
+  }
+  return -1;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)        MODULE  : PHB                                       |
+| STATE   : code                       ROUTINE : pb_sim_update_extn_records                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Update reference count for extension record and 
+                   delete if record is not referenced at all.
+*/
+LOCAL T_PHB_RETURN pb_sim_update_extn_records(USHORT ext_field_id, USHORT rec_num, T_PHB_EXT_REF_TYPE ref_type)
+{
+	BOOL delete_record = FALSE;
+	int db_result;
+
+  /* Depending on the Extension file update the corresponding array. */
+  if(ref_type EQ DECREMENT)
+  {
+    switch(ext_field_id)
+    {
+      case SIM_EXT1:
+				ext1_ref_count[rec_num]--;
+
+				if(ext1_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+				
+	    case SIM_EXT2:
+				ext2_ref_count[rec_num]--;
+
+				if(ext2_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+
+	    case SIM_EXT3:
+				ext3_ref_count[rec_num]--;
+
+				if(ext3_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+			
+			case SIM_EXT4:
+				ext4_ref_count[rec_num]--;
+
+				if(ext4_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+
+			case SIM_EXT5:
+				ext5_ref_count[rec_num]--;
+
+				if(ext5_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+
+			case FFS_EXT_LRN:
+				ext_lrn_ref_count[rec_num]--;
+
+				if(ext_lrn_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+
+			case FFS_EXT_LMN:
+				ext_lmn_ref_count[rec_num]--;
+
+				if(ext_lmn_ref_count[rec_num] EQ 0)
+					delete_record = TRUE;
+
+				break;
+						
+			default:
+				return PHB_FAIL;
+    }
+  }	
+
+	if(ref_type EQ INCREMENT)
+  {
+    switch(ext_field_id)
+    {
+      case SIM_EXT1:
+				ext1_ref_count[rec_num]++;
+				break;
+				
+	    case SIM_EXT2:
+				ext2_ref_count[rec_num]++;
+				break;
+
+	    case SIM_EXT3:
+				ext3_ref_count[rec_num]++;
+				break;
+			
+			case SIM_EXT4:
+				ext4_ref_count[rec_num]++;
+				break;
+
+			case SIM_EXT5:
+				ext5_ref_count[rec_num]++;
+				break;
+
+			case FFS_EXT_LRN:
+				ext_lrn_ref_count[rec_num]++;
+				break;
+
+			case FFS_EXT_LMN:
+				ext_lmn_ref_count[rec_num]++;
+				break;
+						
+			default:
+				return PHB_FAIL;
+    }
+  }	
+
+  /* Delete the extension record if it is not referenced. */
+  if(delete_record EQ TRUE)
+	{
+		db_result = db_delete_record(pbs_data.db_handle, ext_field_id, rec_num);
+
+		if(db_result < DB_OK)
+			return PHB_FAIL;
+  }
+
+	return PHB_OK;
+
+	
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : MMI-Framework (8417)        MODULE  : PHB                                       |
+| STATE   : code                       ROUTINE : pb_sim_read_ext_record_for_delete       |
++--------------------------------------------------------------------+
+
+  PURPOSE : Read extension records and update the records.
+  
+*/
+LOCAL T_PHB_RETURN pb_sim_read_ext_record_for_delete(T_PHB_TYPE type, USHORT field_id, USHORT db_recno)
+{
+  USHORT ext_file_id;
+  T_DB_INFO_FIELD info_field;
+  UBYTE   buffer[RDM_PHB_DATA_SIZE];
+  UBYTE data[SIM_MAX_RECORD_SIZE], *ptr;
+  UBYTE max_tag_len;
+  UBYTE ext_rcd_num;
+	T_PHB_RECORD entry;
+
+  TRACE_FUNCTION("pb_sim_read_ext_record_for_delete()");
+
+  
+  /* Get Extension file for the Phonebook type. */
+  ext_file_id = pb_sim_get_ext_file(type);
+
+  /* Read record from the database. */
+  if(db_info_field(pbs_data.db_handle, field_id, &info_field) NEQ DB_OK)
+    return PHB_FAIL;
+  
+  if(db_read_record(pbs_data.db_handle, field_id, db_recno, 0, info_field.record_size, data) < DB_OK)
+    return PHB_FAIL;
+
+  /* Convert SIM data to the type T_PHB_RECORD. */
+  ptr = data;
+  max_tag_len = MINIMUM ((info_field.record_size) - pb_sim_get_size_except_tag(field_id), PHB_MAX_TAG_LEN);
+
+  ptr += (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+
+  max_tag_len = (info_field.record_size) - pb_sim_get_size_except_tag(field_id);
+  
+  ++ptr;
+  ++ptr;
+  
+  ptr += 10;
+  ++ptr;
+
+  if (*ptr NEQ 0xFF) /* check for extention records */
+  {
+    ext_rcd_num =(UBYTE)*ptr;
+
+    if(db_info_field(pbs_data.db_handle, ext_file_id, &info_field) NEQ DB_OK)
+      return PHB_FAIL;
+
+    /* Reset pointer to start location. */
+    ptr = data;
+
+    memset(ptr, 0xFF, info_field.record_size);
+
+    if(db_read_record(pbs_data.db_handle, ext_file_id, ext_rcd_num, 0, info_field.record_size, ptr) < DB_OK) 
+      return PHB_FAIL;
+
+	if(pb_sim_update_extn_records(ext_file_id, ext_rcd_num, DECREMENT) EQ PHB_FAIL)
+	  return PHB_FAIL;
+	
+    pb_sim_read_ext(ptr, &entry);
+
+    while(*(ptr + 12) NEQ 0xFF) /* check if a further EXT entry exists */
+    {
+      memset(ptr, 0xFF, info_field.record_size);
+
+      db_read_record(pbs_data.db_handle, ext_file_id, (USHORT)*(ptr+12), 0, info_field.record_size,ptr);
+
+      if(pb_sim_update_extn_records(ext_file_id, (USHORT)*(ptr+12), DECREMENT) EQ PHB_FAIL)
+	    return PHB_FAIL;
+
+      pb_sim_read_ext(ptr, &entry);     
+    }
+  }
+  
+  return PHB_OK;
+}
+#endif /* #ifdef TI_PS_FFS_PHB */
+