view src/aci2/mfw/CPHS_mod.c @ 662:8cd8fd15a095

SIM speed enhancement re-enabled and made configurable TI's original code supported SIM speed enhancement, but Openmoko had it disabled, and OM's disabling of speed enhancement somehow caused certain SIM cards to start working which didn't work before (OM's bug #666). Because our FC community is much smaller in year 2020 than OM's community was in their day, we are not able to find one of those #666-affected SIMs, thus the real issue they had encountered remains elusive. Thus our solution is to re-enable SIM speed enhancement and simply wait for if and when someone runs into a #666-affected SIM once again. We provide a SIM_allow_speed_enhancement global variable that allows SIM speed enhancement to be enabled or disabled per session, and an /etc/SIM_spenh file in FFS that allows it to enabled or disabled on a non-volatile basis. SIM speed enhancement is now enabled by default.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 May 2020 05:02:28 +0000
parents 93999a60b835
children
line wrap: on
line source

/*-----------------------Include Files---------------------------------*/

#define ENTITY_MFW


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#if defined (NEW_FRAME)

#include "typedefs.h"
#include "vsi.h"
#include "pei.h"
#include "custom.h"
#include "gsm.h"

#else

#include "STDDEFS.H"
#include "custom.h"
#include "gsm.h"
#include "vsi.h"

#endif

#include "prim.h"
#ifndef PCM_2_FFS
#include "pcm.h"
#endif


#ifndef GPRS
#include "ffs/ffs.h"
#undef GPRS  /* ffs.h anyhow defines GPRS: has to be undef ifndef GPRS */

#else /* GPRS */
#include "ffs/ffs.h"
#endif /* GPRS */

#ifndef PCM_2_FFS
#include "ffs_coat.h"
#endif

#ifdef SIM_TOOLKIT
//#include "mfw_sat.h"
#endif

#include "message.h"
#include "prim.h"
#include "aci_cmh.h"
#if defined (FAX_AND_DATA)
#include "aci_fd.h"
#endif

#ifdef GPRS
#include "gprs.h"
#endif
#include "dti_conn_mng.h"

#include "phb.h"
#include "psa.h"
#include "cmh.h"
#include "cmh_phb.h"
#include "psa.h"
#include "psa_sim.h"
#include "cus_aci.h"
#include "cmh_mm.h"
#include "cmh_sim.h"
#include "CPHS_mod.h"

/*--------------------- Constant definitions  ---------------------------*/


#define MFW_INVALID_SIM_DATA	0xFF
#define MAX_CPHS_ENTRY          4
#define MAX_PCM_MAILBOX_LEN     10


#define NO_ALLOCATED 0
#define FALSE 0
#define TRUE 1
#define LONG_NAME         26
#define SHORT_NAME        10
#define SP_NAME           17
#define NUMERIC_LENGTH    6

#ifdef TI_PS_FFS_PHB
#define PHB_MAX_LEN       MAX_PHB_NUM_LEN /* Phonebook number length + '\0' */
#else
//GW-SPR#762- 40 digit phonebook size.
#ifdef PHONEBOOK_EXTENSION
#define PHB_MAX_LEN        41 /* Phonebook number length + '\0' */
#else
#define PHB_MAX_LEN        21 /* Phonebook number length + '\0' */
#endif /* else, #ifdef PHONEBOOK_EXTENSION */
#endif /* else, #ifdef TI_PS_FFS_PHB */

/*--------------------- Types --------------------------------------*/
typedef enum              /* numbering plan identifier */
{
  CPHS_NPI_UNKNOWN,
  CPHS_NPI_ISDN      = 1,
  CPHS_NPI_DATA      = 3,
  CPHS_NPI_TELEX     = 4,
  CPHS_NPI_NATIONAL  = 8,
  CPHS_NPI_PRIVATE   = 9,
  CPHS_NPI_M_ERMES   = 10,
  CPHS_NPI_M_CTS     = 11
} T_PHB_NPI;

typedef enum            /* type of number */
{
  CPHS_TON_UNKNOWN,
  CPHS_TON_INTERNATIONAL,
  CPHS_TON_NATIONAL,
  CPHS_TON_NET_SPECIFIC,
  CPHS_TON_DED_ACCESS,
  CPHS_TON_ALPHA_NUMERIC,
  CPHS_TON_ABBREVIATED,
  CPHS_TON_EXTENDED
} T_CPHS_PHB_TON;

typedef enum              /* CPHS service */
{
  CPHS_CSP = 1,             /* customer service profile */
  CPHS_SST,                 /* service string table     */
  CPHS_MB_NUMBER,           /* mailbox numbers          */
  CHPS_NAME_SHORT,          /* operator name shortform  */
  CHPS_INFO_NUMBERS         /* information numbers      */
} T_CPHS_SERVICE;

#define CPHS_SERVICE_TABLE   2 /* size of CPHS service table            */
#define CPHS_INFO_SIZE   3 /* size of CPHS information field (6F16) */
#define CPHS_ONS_SIZE   20 /* size of operator name string (6F14) - read first 20 bytes only */
#define CPHS_ONSF_SIZE  10 /* size of operator name short form (6F18) */
#define CPHS_MIN_MBN_SIZE 14
#define CPHS_MBS_SIZE    2 /* size of voice message waiting flag (6F11) */
#define CPHS_CFF_SIZE    2 /* size of call forwarding flags (6F13)  */
#define CPHS_ALS_SIZE    1 /* size of alternate line service (6F9F) */
#define CPHS_ALSS_SIZE   1 /* size of alternate line service status (6F92) */
#define CPHS_CSP_SIZE   20 /* size of customer service profile (6F15) */
#define CPHS_MIN_INS_SIZE 5

typedef struct {

	T_CPHS_OPN       			opName;
	T_CPHS_MAILBOX_NUM_LIST		mbNum;
	T_CPHS_LINE_IND       		mbStatus;
	T_CPHS_LINE_IND       		dvStatus;
	T_CPHS_ALS_INFO   			alsStatus;
	T_CPHS_ALS_LINE				Line1_desc;
	T_CPHS_ALS_LINE				Line2_desc;
	T_CPHS_CSP           		csProfile;
	T_CPHS_INFO_NUM_LIST*  	numList;
	T_CPHS_INFO_NUM_ENTRY* 	infoEntry;
	T_CPHS_ROAMING_IND			roaming_ind;
	UBYTE                    mbnData[40]; // it should be allocated dynamically.

	UBYTE                    mbsData[CPHS_MBS_SIZE]; // it should be allocated dynamically.
	UBYTE                    dvData[CPHS_CFF_SIZE]; // it should be allocated dynamically.

//	T_CPHS_READ_SIM_ENTRY read_sim_entry;//MC

	UBYTE        			cphsStatus;
	UBYTE                    cphsPhase;
	UBYTE                    cphsServTab[CPHS_SERVICE_TABLE];
	UBYTE                    maxRec;

	T_CPHS_MAILBOX_NUM_ENTRY         MbnEntry;

	T_CPHS_MAILBOX_NUM_ENTRY    *vcEntry;
	T_CPHS_SIMOP_STATUS     simStatus;
	UBYTE                    alsData;
	UBYTE                    idxLevel;
	UBYTE                    startIdx;
	 UBYTE                    cphsUpdate ;
	ULONG                   cphsPrevRead;
	T_CPHS_CB_FUNC			InfoNumberListCB;
	T_CPHS_CB_FUNC			InfoNumberCB;
	T_CPHS_CB_FUNC			RefreshCB;
}T_CPHS_CACHED_DATA;


static T_CPHS_CACHED_DATA* cphs_data = NULL;

void Cphs_support_check (void);
UBYTE Cphs_ssc (UBYTE nr, UBYTE * serv_table);
void Cphs_update_info_cnf (SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_information(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_csp(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_cff(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_mbs(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_mbn(SHORT table_id);
void Cphs_read_onsf(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_read_ons(SHORT errCode, UBYTE *data, UBYTE dataLen);
void Cphs_get_csp ();
void Cphs_get_mailbox (void);
void Cphs_read_sim_dat_cb(SHORT table_id);
BOOL Cphs_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length);
T_CPHS_RET Cphs_set_divert_status  (T_CPHS_FLAG_STATUS line1,
                               T_CPHS_FLAG_STATUS line2,
                               T_CPHS_FLAG_STATUS fax,
                               T_CPHS_FLAG_STATUS data);
T_CPHS_RET Cphs_set_mailbox_status (T_CPHS_FLAG_STATUS line1,
                               T_CPHS_FLAG_STATUS line2,
                               T_CPHS_FLAG_STATUS fax,
                               T_CPHS_FLAG_STATUS data);
void Cphs_operator_name (void);
void Cphs_get_mailbox_status ();
void Cphs_get_divert_status () ;


void Cphs_write_eeprom_mailbox(T_CPHS_MAILBOX_NUM_ENTRY *entry);
void Cphs_read_eeprom_mailbox(void);
void Cphs_build_mbn_data(UBYTE *data, UBYTE len);
void Cphs_req_info_num_read(UBYTE rcd_num, UBYTE dataLen);
void Cphs_get_info_num (UBYTE level, UBYTE startIndex);
void Cphs_read_info_num(SHORT table_id);
void Cphs_read_first_info_num(SHORT table_id);
void Cphs_read_sim_rcd_cb (SHORT table_id);
BOOL Cphs_read_sim_rcd(USHORT data_id, UBYTE rcd_num, UBYTE len);
void Cphs_select_info_num (UBYTE index) ;
void Cphs_write_sim_dat_cb(SHORT table_id);
BOOL Cphs_write_sim_dat(USHORT data_id, UBYTE *data, UBYTE length);
void Cphs_write_sim_rcd_cb (SHORT table_id);
BOOL Cphs_write_sim_rcd(USHORT data_id, UBYTE rcd_num,
                        UBYTE *data,    UBYTE dataLen);
void Cphs_read_eeprom_als_desc();
void Cphs_write_eeprom_als_desc(T_CPHS_ALS_LINE* line);
T_CPHS_RET Cphs_write_eeprom_als(T_CPHS_ALS_INFO* info);
T_CPHS_RET Cphs_read_eeprom_als(T_CPHS_ALS_INFO* info);
void Cphs_get_als_info ();
T_CPHS_PHB_TON cvtTon(T_ACI_TOA_TON ton);
  /* initializes CPHS module, reads CPHS data fields from SIM and caches */
  /* the read data.  */
#ifdef _TESTING__
T_CPHS_INFO_NUM_LIST num_list;
T_CPHS_INFO_NUM_ENTRY num_entry;


int Info_Numbers_Callback(T_CPHS_INFO_NUM_LIST* list, T_CPHS_INFO_NUM_ENTRY* entry)
{	char debug[50];
	TRACE_FUNCTION("Info_Numbers_Callback()");

	if (list != NULL)
	{	sprintf(debug, "INFO_NUMLIST:%s, count:%d",(char*)list->entry[0].alpha.data, list->count);
		TRACE_EVENT(debug);

	}

	if (entry != NULL)
	{
		sprintf(debug, "INFO_NUM:%s",(char*)entry->alpha.data);
		TRACE_EVENT(debug);
	}
	if (list == NULL && entry == NULL)
		TRACE_EVENT("REFRESH DONE!!!!");


}

void Cphs_reading_test()
{	T_CPHS_ALS_INFO als_info;
	T_CPHS_ALS_LINE als_line;
	T_CPHS_INFO cphs_info;
	T_CPHS_CSP cphs_csp;
	T_CPHS_LINE_IND dv_ind;
	T_CPHS_MAILBOX_NUM_LIST mb_nums;
	T_CPHS_OPN op_name;
	T_CPHS_ROAMING_IND roam_ind;

	char debug[60];

	//cphs_Init(Info_Numbers_Callback);
	cphs_refresh(Info_Numbers_Callback);

	//cphs_getInfoNumbers(&num_list,1,1, Info_Numbers_Callback);
	/*cphs_getAlsInfo(&als_info);
	sprintf(debug,"line:%d, locked:%d", als_info.line, als_info.locked);
	TRACE_FUNCTION(debug);
	als_line.line = CPHS_LINE_INDEX_LINE2;
	cphs_getAlsLineDescr(&als_line);
	sprintf(debug,"line:%d, desc:%0.22s", als_line.line, als_line.description.data);
	TRACE_EVENT(debug);
	cphs_getVoiceMessageInd(&dv_ind);
	sprintf(debug, "VM result:%d, line1:%d, line2: %d", dv_ind.result, dv_ind.line1, dv_ind.line2);
	TRACE_EVENT(debug);
	cphs_getCPHSInfo(&cphs_info);
	sprintf(debug, "Phase:%d InfoNum:%d, shortname:%d, mb:%d", cphs_info.phase, cphs_info.info_num, cphs_info.opn_short, cphs_info.mailbox_num);
	TRACE_EVENT(debug);

	cphs_getCSP(&cphs_csp);
	sprintf(debug, "Result: %d, CSP:%x,%x,%x,%x,%x,%x", cphs_csp.result, cphs_csp.csp[0].services,  cphs_csp.csp[1].services,
		 cphs_csp.csp[2].services,  cphs_csp.csp[3].services,  cphs_csp.csp[4].services,  cphs_csp.csp[5].services);
	TRACE_EVENT(debug);
//#ifdef FRED
	cphs_getDivertCallInd(&dv_ind);
	sprintf(debug, "Divert result: %d, line1:%d, line2:%d", dv_ind.result, dv_ind.line1, dv_ind.line2);
	TRACE_EVENT(debug);

//#endif

	cphs_getOPN(&op_name);
	sprintf(debug, "res:%d long_name:%s, short_name%0.22s", op_name.result, op_name.long_name, op_name.short_name);
	TRACE_EVENT(debug);

	cphs_getRoamingInd(&roam_ind);
	sprintf(debug, "Roaming ind: %d", roam_ind);
	TRACE_EVENT(debug);

	cphs_getMailboxNumbers(&mb_nums);

	sprintf(debug, "MBN result: %d, count:%d, first:%0.22s",mb_nums.result, mb_nums.count, mb_nums.entries[0].number);
	TRACE_EVENT(debug);*/


}


void Cphs_writing_test()
{	T_CPHS_ALS_INFO als_info;
	T_CPHS_ALS_LINE als_line;
	T_CPHS_LINE_IND dv_ind;
	T_CPHS_ROAMING_IND roam_ind;
	char debug[50];



	cphs_Init(Info_Numbers_Callback);
	//cphs_refresh(Info_Numbers_Callback);

	als_line.line = CPHS_LINE_INDEX_LINE2;
	memcpy(als_line.description.data, (UBYTE*)"Second Line !!", 8);
	als_line.description.len = 8;
	cphs_setAlsLineDescr(als_line);

	als_info.line = CPHS_LINE_INDEX_LINE2;
	als_info.locked= CPHS_LINEFLAG_SET;
	cphs_setAlsInfo(&als_info);
	cphs_setDivertCallInd(CPHS_LINE_INDEX_LINE1, CPHS_LINEFLAG_NOT_SET);
	cphs_setDivertCallInd(CPHS_LINE_INDEX_LINE2, CPHS_LINEFLAG_SET);

	cphs_setVoiceMessageInd(CPHS_LINE_INDEX_LINE1, CPHS_LINEFLAG_NOT_SET);
	cphs_setVoiceMessageInd(CPHS_LINE_INDEX_LINE2, CPHS_LINEFLAG_SET);

	roam_ind = CPHS_ROAMING_OFF;
	cphs_setRoamingInd(&roam_ind);

	//cphs_selectInfoNumber(2, &num_entry, Info_Numbers_Callback);

}
#endif

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_Init |
+--------------------------------------------------------------------+

*/
T_CPHS_RET cphs_Init(T_CPHS_CB_FUNC callback)
{	//check if already initilaised?
	if (cphs_data)
		return CPHS_IS_OK;
	cphs_data = (T_CPHS_CACHED_DATA*)malloc(sizeof(T_CPHS_CACHED_DATA));
	if (cphs_data)
  	{	cphs_data->cphsStatus = CPHS_NOT_PRESENT;
  		cphs_data->simStatus  = SIMOP_UNKNOWN;
  		cphs_data->cphsUpdate = FALSE;
		cphs_data->cphsPrevRead = 0;
		cphs_data->InfoNumberListCB = NULL;
		cphs_data->InfoNumberCB = NULL;
  		Cphs_support_check();
  		cphs_refresh(callback);
  		return CPHS_IS_OK;
	}
	else
		return CPHS_FAIL;
}



 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_refresh() |
+--------------------------------------------------------------------+


*/

 /* reads CPHS data fields from SIM and updates the cached CPHS data    */
T_CPHS_RET cphs_refresh(T_CPHS_CB_FUNC callback)
 {	T_CPHS_RET res;

 	if (cphs_data EQ NULL)
 	{	TRACE_EVENT("CPHS not initialised");
		return CPHS_NOT_INIT;
 	}
 	//get call divert indicator
	Cphs_get_divert_status ();
 	cphs_data->RefreshCB = callback; //set call back function
 	//get mailbox numbers
	/*Cphs_get_mailbox ();
 	Cphs_operator_name ();
	//get voice message indicator
	Cphs_read_eeprom_als_desc();
	//get als line description
	Cphs_get_mailbox_status ();
	//get CSP
	Cphs_get_csp ();*/
 }


 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_Exit() |
+--------------------------------------------------------------------+


*/
/* de-initializes CPHS module                                          */
T_CPHS_RET cphs_Exit()
{	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	free(cphs_data);

	return CPHS_IS_OK;
}

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getOPN  |
+--------------------------------------------------------------------+


*/
  /* reads from SIM the operator long name and if available the short    */
  /* name, too  */
T_CPHS_RET cphs_getOPN            ( T_CPHS_OPN *opn )
{	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
  	if (opn EQ NULL)
  		return CPHS_FAIL;
	memcpy(opn, &cphs_data->opName, sizeof(T_CPHS_OPN));
	return CPHS_IS_OK;
}
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getRoamingInd |
+--------------------------------------------------------------------+


*/

/* checks if roaming is active                                         */
T_CPHS_RET cphs_getRoamingInd     ( T_CPHS_ROAMING_IND *indicator )
{
#ifndef NEPTUNE_BOARD
/*
  T_ACI_COPS_MOD  mode;
  T_ACI_COPS_FRMT  format;
  CHAR  oper[30];
  T_OPER_NTRY* plmn_entry;
  SHORT mccBuf, mncBuf;
  char debug[50];
  UBYTE numeric[8];
  char ** end;
  memset(oper, 0, 30);
*/
#else
	T_ACI_COPS_MOD  mode;
  	T_ACI_COPS_FRMT  format;
    CHAR  oper[30];
    T_OPER_NTRY* plmn_entry;
    SHORT mccBuf, mncBuf;
    char debug[50];
    UBYTE numeric[8];
    char ** end;
    memset(oper, 0, 30);
#endif

  if (cphs_data EQ NULL)
    return CPHS_NOT_INIT;
  if (indicator EQ NULL)
    return CPHS_FAIL;
#ifndef NEPTUNE_BOARD
  *indicator = cphs_data->roaming_ind;
#else
	memcpy(indicator, &cphs_data->roaming_ind, sizeof(T_CPHS_ROAMING_IND));
#endif
/*
		qAT_PlusCOPS (CMD_SRC_NONE,&mode,&format,oper );
		//get current MCC
		if (format == COPS_FRMT_Long OR format == COPS_FRMT_Short)
		{	sAT_PlusCOPSE(oper, format, NULL, NULL, numeric);
		//	plmn_entry = cmhMM_FindName( oper, format );
			numeric[3] = 0;//terminate string before MNC
			plmn_entry->mcc = strtol((char*)numeric,end,16 );
		}

		if (format == COPS_FRMT_Numeric)
		{	//plmn_entry = cmhMM_FindNumeric( oper );
			oper[3] = 0;
			plmn_entry->mcc = strtol((char*)oper, end, 16);
		}
		//get "Home MCC"
		cmhSIM_GetHomePLMN ( &mccBuf, &mncBuf );
		//currently qAT_PlusCOPS is not returning the correct format
		//cmhMM_FindName/Numeric rely on PCM which does not work
		sprintf(debug, "Home MCC %d, current MCC %d COPS fmt:%d", plmn_entry->mcc, mccBuf, format);
		TRACE_EVENT(debug);
		if (plmn_entry->mcc == mccBuf)
			*indicator = CPHS_ROAMING_OFF;
		else
			*indicator = CPHS_ROAMING_ON;
*/

  return CPHS_IS_OK;
}
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getVoiceMessageInd |
+--------------------------------------------------------------------+


*/

 /* reads from SIM if voice mails are waiting for the available lines   */
  /* (line1, line2, fax, data)                                           */
T_CPHS_RET cphs_getVoiceMessageInd( T_CPHS_LINE_IND *indicator )
{	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
  	if (indicator EQ NULL)
  		return CPHS_FAIL;
	memcpy(indicator, &cphs_data->mbStatus, sizeof(T_CPHS_LINE_IND));
	return CPHS_IS_OK;
}
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_setVoiceMessageInd |
+--------------------------------------------------------------------+


*/
/* sets on SIM the voice mail waiting flag for the given lines in the  */
  /* parameter line_mask. The bitmask will be created by oring the lines.*/
  /* The bits for the lines are defined in T_CPHS_LINE_INDEX.            */
T_CPHS_RET cphs_setVoiceMessageInd( UBYTE              line_mask,
                                    T_CPHS_FLAG_STATUS flag )
{
	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	if (CPHS_LINE_INDEX_LINE1 & line_mask)
	{	cphs_data->mbStatus.line1 = flag;
		TRACE_EVENT("Setting Line 1 VM");
		Cphs_set_mailbox_status(flag,CPHS_FLAG_NOT_PRESENT ,CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT);
	}

	if (CPHS_LINE_INDEX_LINE2 & line_mask)
	{	TRACE_EVENT("SEtting line 2 VM");
		cphs_data->mbStatus.line2 = flag;
		Cphs_set_mailbox_status(CPHS_FLAG_NOT_PRESENT, flag,CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT);
	}
	if (CPHS_LINE_INDEX_FAX & line_mask)
	{	cphs_data->mbStatus.fax = flag;
		Cphs_set_mailbox_status(CPHS_FLAG_NOT_PRESENT, CPHS_FLAG_NOT_PRESENT,flag,CPHS_FLAG_NOT_PRESENT);
	}
	if (CPHS_LINE_INDEX_DATA & line_mask)
	{	cphs_data->mbStatus.data = flag;
		Cphs_set_mailbox_status(CPHS_FLAG_NOT_PRESENT, CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT,flag);
	}



	return CPHS_EXEC;
}
  /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getDivertCallInd   |
+--------------------------------------------------------------------+
*/


  /* reads from SIMif calls shall be diverted for the available lines    */
  /* (line1, line2, fax, data) */
T_CPHS_RET cphs_getDivertCallInd  (T_CPHS_LINE_IND *indicator )
{
	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
	if (ind EQ NULL)
		return CPHS_FAIL;
	memcpy(indicator, &cphs_data->dvStatus, sizeof(T_CPHS_LINE_IND));
	return CPHS_IS_OK;
}
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_setDivertCallInd |
+--------------------------------------------------------------------+
*/
  /* sets on SIM the divert call flag for the given lines in the         */
  /* parameter line_mask. The bitmask will be created by oring the lines.*/
  /* The bits for the lines are defined in T_CPHS_LINE_INDEX.            */
T_CPHS_RET cphs_setDivertCallInd  ( UBYTE              line_mask,
                                    T_CPHS_FLAG_STATUS flag )
{
	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	if (CPHS_LINE_INDEX_LINE1 & line_mask)
	{	cphs_data->dvStatus.line1 = flag;
		TRACE_EVENT("Setting line 1 divert");
		Cphs_set_divert_status(flag,CPHS_FLAG_NOT_PRESENT ,CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT);
	}

	if (CPHS_LINE_INDEX_LINE2 & line_mask)
	{	cphs_data->dvStatus.line2 = flag;
		TRACE_EVENT("Setting line 2 divert");
		Cphs_set_divert_status(CPHS_FLAG_NOT_PRESENT, flag,CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT);
	}
	if (CPHS_LINE_INDEX_FAX & line_mask)
	{	cphs_data->dvStatus.fax = flag;
		Cphs_set_divert_status(CPHS_FLAG_NOT_PRESENT, CPHS_FLAG_NOT_PRESENT,flag,CPHS_FLAG_NOT_PRESENT);
	}
	if (CPHS_LINE_INDEX_DATA & line_mask)
	{	cphs_data->dvStatus.data = flag;
		Cphs_set_divert_status(CPHS_FLAG_NOT_PRESENT, CPHS_FLAG_NOT_PRESENT,CPHS_FLAG_NOT_PRESENT,flag);
	}

	return CPHS_EXEC;

}

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getAlsInfo |
+--------------------------------------------------------------------+
*/
  /* reads from SIM the information of alternate line service            */
  /* ( selected line, alternate line service locked/unlocked)            */
T_CPHS_RET cphs_getAlsInfo        ( T_CPHS_ALS_INFO *info )
{
	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
	if (info EQ NULL)
		return CPHS_FAIL;

	//memcpy(info, &cphs_data->alsStatus, sizeof( T_CPHS_ALS_INFO));
	Cphs_read_eeprom_als(info);
	return CPHS_IS_OK;

}
   /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_setAlsInfo|
+--------------------------------------------------------------------+
*/
  /* sets on SIM the informtion of alternate line service / selects the  */
  /* active line */
T_CPHS_RET cphs_setAlsInfo        ( T_CPHS_ALS_INFO *info )
 {	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
  	if (info EQ NULL)
  		return CPHS_FAIL;
	//memcpy(&cphs_data->alsStatus, info, sizeof(T_CPHS_ALS_INFO));
 	return Cphs_write_eeprom_als(info);
 	//return CPHS_EXEC;
 }
   /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getAlsLineDescr |
+--------------------------------------------------------------------+
*/
 /* reads the (alpha)numeric description for the given line             */
T_CPHS_RET cphs_getAlsLineDescr   ( T_CPHS_ALS_LINE* line )
 {	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
	if (line EQ NULL)
		return CPHS_FAIL;
	Cphs_read_eeprom_als_desc();
 	if (line->line EQ CPHS_LINE_INDEX_LINE1)
	{	memcpy(line,&cphs_data->Line1_desc,  sizeof(T_CPHS_ALS_LINE));
 		return CPHS_IS_OK;
 	}

 	if (line->line EQ CPHS_LINE_INDEX_LINE2)
	{	memcpy( line, &cphs_data->Line2_desc,sizeof(T_CPHS_ALS_LINE));
 		return CPHS_IS_OK;
 	}

	return CPHS_FAIL;
 }
  /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE :cphs_setAlsLineDescr |
+--------------------------------------------------------------------+
*/
 /* sets a (alpha)numeric description for the given line                */
T_CPHS_RET cphs_setAlsLineDescr   ( T_CPHS_ALS_LINE line )

 {	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

 	if (line.line EQ CPHS_LINE_INDEX_LINE1)
	{	memcpy(&cphs_data->Line1_desc,&line,  sizeof(T_CPHS_ALS_LINE));
 		Cphs_write_eeprom_als_desc(&cphs_data->Line1_desc);
 		return CPHS_IS_OK;
 	}

 	if (line.line EQ CPHS_LINE_INDEX_LINE2)
	{	memcpy(&cphs_data->Line2_desc, &line, sizeof(T_CPHS_ALS_LINE));
 		Cphs_write_eeprom_als_desc(&cphs_data->Line2_desc);
 		return CPHS_IS_OK;
 	}

	return CPHS_FAIL;
 }
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_setRoamingInd |
+--------------------------------------------------------------------+

*/
T_CPHS_RET cphs_setRoamingInd ( T_CPHS_ROAMING_IND* indicator )
{	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	if (*indicator EQ CPHS_ROAMING_OFF OR *indicator EQ CPHS_ROAMING_ON)
	{	cphs_data->roaming_ind  = *indicator;
		return CPHS_IS_OK;
	}
	else
		return CPHS_FAIL;
}
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_checkEmergencyCall |
+--------------------------------------------------------------------+
*/

/* check if the current call number(ASCII encoded) is an emergency number supported     */
/* by CPHS.                                                              */
T_CPHS_RET cphs_checkEmergencyCall( char* num )
{	char** end;


	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	if (num EQ NULL)
		return CPHS_FAIL;

	if (strtol(num, end, 10)EQ CPHS_EMERGENCY_NUM_112 OR
		strtol(num, end, 10)EQ CPHS_EMERGENCY_NUM_999)
		return CPHS_IS_OK;
	else
		return CPHS_FAIL;
}

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getCPHSInfo  |
+--------------------------------------------------------------------+
*/
 /* reads from SIM the phase of the SIM and which optional datafields   */
  /* are present in the SIM                                              */
  /* (operator name shortform, mailbox numbers, service string table,    */
  /*  information numbers)                                               */
T_CPHS_RET cphs_getCPHSInfo       ( T_CPHS_INFO *info )
 {	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;

	if (info !=NULL)
  {
    info->phase = cphs_data->cphsPhase;
    info->csp   = Cphs_ssc(CPHS_CSP,          cphs_data->cphsServTab);
    info->mailbox_num = Cphs_ssc(CPHS_MB_NUMBER,    cphs_data->cphsServTab);

    if (cphs_data->cphsPhase EQ 1) /* phase 1 only */
      info->sst = Cphs_ssc(CPHS_SST,          cphs_data->cphsServTab);
    else                /* not support */
      info->sst = NO_ALLOCATED;

    if (cphs_data->cphsPhase EQ 2) /* phase 2 only */
    {
      info->opn_short  = Cphs_ssc(CHPS_NAME_SHORT,   cphs_data->cphsServTab);
      info->info_num  = Cphs_ssc(CHPS_INFO_NUMBERS, cphs_data->cphsServTab);
    }
    else                /* not support */
    {
      info->opn_short  = NO_ALLOCATED;
      info->info_num  = NO_ALLOCATED;
    }
    return CPHS_IS_OK;
  }
  return CPHS_FAIL;

 }

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getCSP |
+--------------------------------------------------------------------+

*/
 /* reads all entries of the customer service profile and fills         */
T_CPHS_RET cphs_getCSP            ( T_CPHS_CSP *csp )
 {	if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
	if (csp EQ NULL)
		return CPHS_FAIL;

	memcpy(csp, &cphs_data->csProfile, sizeof(T_CPHS_CSP));
	return CPHS_IS_OK;
 }

 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getMailboxNumbers |
+--------------------------------------------------------------------+
*/
 /* reads all mailbox numbers from the SIM fills all mailbox number     */
  /* entries in the mailbox number list                                  */
T_CPHS_RET cphs_getMailboxNumbers ( T_CPHS_MAILBOX_NUM_LIST *nums )
 {if (cphs_data EQ NULL)
		return CPHS_NOT_INIT;
	if (nums EQ NULL)
		return CPHS_FAIL;

	memcpy(nums, &cphs_data->mbNum, sizeof(T_CPHS_CSP));
	return CPHS_IS_OK;
 }
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_getInfoNumbers|
+--------------------------------------------------------------------+

*/


 /* reads all information numbers from the SIM fills all information    */
  /* numbers into the array of pointers to information number lists down to the level specified  */
  //MC-Not sure about the format of this as current mfw_cphs code returns an information number list
  //with only 4 entries
T_CPHS_RET cphs_getInfoNumbers    ( T_CPHS_INFO_NUM_LIST *nums, UBYTE level, UBYTE start_index, T_CPHS_CB_FUNC callback)
{		cphs_data->InfoNumberListCB = callback;
 		cphs_data->numList=nums;
		Cphs_get_info_num(level, start_index);
 }
 /*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : cphs_selectInfoNumber |
+--------------------------------------------------------------------+

  PURPOSE : reads the information number entry given by level and index from
   the SIM

*/
T_CPHS_RET cphs_selectInfoNumber  ( USHORT                 index,
                                    T_CPHS_INFO_NUM_ENTRY *num, T_CPHS_CB_FUNC callback)
{	cphs_data->InfoNumberCB = callback;
 	cphs_data->infoEntry= num;
	Cphs_select_info_num(index);
	//num = &cphs_data->infoEntry;

}




/*
+--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : Cphs_support_check |
+--------------------------------------------------------------------+

  PURPOSE : Check whether CPHS is supported.

*/

void Cphs_support_check (void)
{
  TRACE_FUNCTION ("Cphs_support_check()");

  /* Read CPHS information filed (6F16 - 3 bytes) from SIM card */
  if (!Cphs_read_sim_dat(SIM_CPHS_CINF, NOT_PRESENT_8BIT, CPHS_INFO_SIZE))
  {
    /* Read failed */
    cphs_data->cphsStatus = CPHS_NOT_PRESENT;

  }
}



 /*
  +--------------------------------------------------------------------+
|         MODULE  : CPHS standalone module           |
| STATE   : code                        ROUTINE : Cphs_operator_name |
+--------------------------------------------------------------------+

  PURPOSE : Request the network operator name

*/

void Cphs_operator_name (void)
{
  TRACE_FUNCTION ("Cphs_operator_name()");

  /* Check CPHS support status */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return;

  /* Read operator name sring */
  if (!Cphs_read_sim_dat(SIM_CPHS_ONSTR, NOT_PRESENT_8BIT, CPHS_ONS_SIZE))
  {
    /* Read operator name sring failed */
    cphs_data->opName.long_name.len = 0;

    /* Read operator name shortform */
    if ((cphs_data->cphsPhase NEQ 2)                                                          OR
        (Cphs_ssc(CHPS_NAME_SHORT,   cphs_data->cphsServTab) NEQ ALLOCATED_AND_ACTIVATED) OR
        !Cphs_read_sim_dat(SIM_CPHS_ONSHF, NOT_PRESENT_8BIT, CPHS_ONSF_SIZE)                  )
    {
      /* Read operator name shortform failed.
           */
      cphs_data->opName.short_name.len = 0;
      cphs_data->opName.result = SIMOP_READ_ERR;
    }
  }

}

  /*
+-------------------------------------------------------------------------+
|         MODULE  : CPHS standalone module                |
| STATE   : code                        ROUTINE : Cphs_get_mailbox_status |
+-------------------------------------------------------------------------+

  PURPOSE : get the voice message waiting flag

*/

void Cphs_get_mailbox_status ()
{
  TRACE_FUNCTION ("Cphs_get_mailbox_status()");

  /* Check CPHS support status. */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return ;

  /* Read voice message waiting flag.
     When this reading failed, send event with "read error" parameter to MMI */
  if (!Cphs_read_sim_dat(SIM_CPHS_VMW, NOT_PRESENT_8BIT, CPHS_MBS_SIZE))
  {
    cphs_data->mbStatus.result = SIMOP_READ_ERR;
    TRACE_EVENT("Reading mailbox status failed");
  }
}

/*
+------------------------------------------------------------------------+
|         MODULE  : CPHS standalone module               |
| STATE   : code                        ROUTINE : Cphs_get_divert_status |
+------------------------------------------------------------------------+

  PURPOSE : Request the call forwarding flags

*/

void Cphs_get_divert_status ()
{
  TRACE_FUNCTION ("Cphs_get_divert_status()");

  /* Check CPHS support status. */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return;

  /* Read call forwarding flags.
     When this reading failed, send event with "read error" parameter to MMI */
  if (!Cphs_read_sim_dat(SIM_CPHS_CFF, NOT_PRESENT_8BIT, CPHS_CFF_SIZE))
  {
    cphs_data->dvStatus.result = SIMOP_READ_ERR;

  }

}

/*
+---------------------------------------------------------------------+
|         MODULE  : CPHS standalone module            |
| STATE   : code                        ROUTINE : Cphs_get_als_info   |
+---------------------------------------------------------------------+

  PURPOSE : Request the Status of Alternate Line Service information
            (first read selected ALS line, dann status of this line).
            When the field does not exist in SIM, read it from EEPROM.

*/
//ATM, cannot get als lock status from SIM
/*void Cphs_get_als_info ()
{
  TRACE_EVENT ("Cphs_get_als_info()");

    Cphs_read_eeprom_als();

}*/

/*
+---------------------------------------------------------------------+
|         MODULE  : CPHS standalone module            |
| STATE   : code                        ROUTINE : Cphs_get_csp        |
+---------------------------------------------------------------------+

  PURPOSE : Request the customer service profile

*/

void Cphs_get_csp ()
{
  UBYTE res;

  TRACE_FUNCTION ("Cphs_get_csp()");

  /* Check CPHS support status. */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return ;

  /* check CPHS service table */
  res = Cphs_ssc(CPHS_CSP, cphs_data->cphsServTab);
  if ( res NEQ ALLOCATED_AND_ACTIVATED)
    return;

  /* Read customer service profile.
     When this reading failed, send event with empty parameter array to MMI */
  if (!Cphs_read_sim_dat(SIM_CPHS_CSP, NOT_PRESENT_8BIT, CPHS_CSP_SIZE))
  {
    cphs_data->csProfile.result = SIMOP_READ_ERR;
    memset(cphs_data->csProfile.csp, 0, sizeof(cphs_data->csProfile.csp));
  }
}
/*
+---------------------------------------------------------------------+
|         MODULE  : CPHS standalone module            |
| STATE   : code                        ROUTINE : Cphs_get_mailbox       |
+---------------------------------------------------------------------+

  PURPOSE : Request the customer service profile

*/
void Cphs_get_mailbox (void)
{
  TRACE_FUNCTION ("Cphs_get_mailbox()");

  cphs_data->mbNum.count = 0;

  /* Check CPHS support status.
     When CPHS is not support, read mailbox numbers from EEPROM */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
  {
    Cphs_read_eeprom_mailbox();
    return;
  }

  /* Check CPHS service table.
     When CPHS is not support, read mailbox numbers from EEPROM */
  if (Cphs_ssc(CPHS_MB_NUMBER, cphs_data->cphsServTab) NEQ ALLOCATED_AND_ACTIVATED)
  {
  	TRACE_EVENT("CPHS doesn't support mailbox");
    Cphs_read_eeprom_mailbox();
    return;
  }

  /* Read mailbox numbers from SIM.
     When this reading failed, read mailbox numbers from EEPROM */
     //cphs_data->simStatus = SIMOP_UNKNOWN;
  if (!Cphs_read_sim_rcd(SIM_CPHS_MBXN, 1, 0)) /* read the first record */
  {	TRACE_EVENT("Mailbox Sim read failed");
    Cphs_read_eeprom_mailbox();
  }
}

/*
+----------------------------------------------------------------------+
|          MODULE: CPHS standalone module               |
| STATE  : code                         ROUTINE: Cphs_ssc				       |
+----------------------------------------------------------------------+


   PURPOSE :   Check CPHS service status.

*/

UBYTE Cphs_ssc (UBYTE nr, UBYTE * serv_table)
{
  UBYTE value;

  TRACE_FUNCTION ("Cphs_ssc()");

  serv_table = serv_table + (nr-1)/4;
  value      = * serv_table;

  value = value >> (((nr-1) & 3) * 2);
  value = value & 3;

  return value;
}

/*
+------------------------------------------------------------------------+
| MODULE  : CPHS standalone module               						|
| STATE   : code                        ROUTINE : Cphs_set_mailbox_status|
+------------------------------------------------------------------------+

  PURPOSE : Set the mailbox status on each line

*/

 T_CPHS_RET Cphs_set_mailbox_status (T_CPHS_FLAG_STATUS line1,
                               T_CPHS_FLAG_STATUS line2,
                               T_CPHS_FLAG_STATUS fax,
                               T_CPHS_FLAG_STATUS data)
{
  UBYTE result;
  char debug[50];

  TRACE_FUNCTION ("Cphs_set_mailbox_status()");

  /* Check CPHS support status. */
 // if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
 //   return CPHS_FAIL;
  sprintf(debug, "Original mailbox status: %x%x",cphs_data->mbsData[0],cphs_data->mbsData[1]);
  TRACE_EVENT(debug);
  /* Write status in buffer */
  if (line1 EQ CPHS_LINEFLAG_SET   OR
      line1 ==CPHS_LINEFLAG_NOT_SET  )
  {             			/* low Nibble */
  	cphs_data->mbsData[0]&=0xF0; //get rid of low nibble
  	cphs_data->mbsData[0] += (line1&0x0F);
  	}
 /* else
    cphs_data->mbsData[0] |= 0x0F;*/

  if (line2 EQ CPHS_LINEFLAG_SET   OR
      line2 EQ CPHS_LINEFLAG_NOT_SET  )
  {	cphs_data->mbsData[0]&=0x0F; //get rid of high nibble
    cphs_data->mbsData[0] += (line2 << 4)&0xF0;    /* high Nibble */
  }
/*  else
    cphs_data->mbsData[0] = 0xF0 | cphs_data->mbsData[0];*/

  if (fax EQ CPHS_LINEFLAG_SET   OR
      fax EQ CPHS_LINEFLAG_NOT_SET  )
  {cphs_data->mbsData[1]&=0xF0; //get rid of low nibble
    cphs_data->mbsData[1] += fax&0x0F;              /* low Nibble */
  }
/*  else
    cphs_data->mbsData[1] |= 0x0F;*/

  if (data EQ CPHS_LINEFLAG_SET   OR
      data EQ CPHS_LINEFLAG_NOT_SET  )
  {	cphs_data->mbsData[1]&=0x0F; //get rid of high nibble
    cphs_data->mbsData[1] += (data << 4)&0xF0;     /* high Nibble */
  }
/*  else
    cphs_data->mbsData[1] = 0xF0 | cphs_data->mbsData[1];*/

	sprintf(debug, "MBS Data:%x%x", cphs_data->mbsData[0], cphs_data->mbsData[1]);
	TRACE_EVENT(debug);

  /* Read voice message waiting flag to determine the size */
  cphs_data->simStatus = SIMOP_WRITE_OK;
  if (!Cphs_read_sim_dat(SIM_CPHS_VMW, NOT_PRESENT_8BIT, CPHS_MBS_SIZE))
  //if (!Cphs_write_sim_dat(SIM_CPHS_VMW, cphs_data->mbsData, CPHS_MBS_SIZE))
  { TRACE_EVENT("Mailbox status SIM write failed");
    return  CPHS_SIM_WRITE_ERROR;
  }
}

/*
+------------------------------------------------------------------------+
| MODULE  : CPHS standalone module               						|
| STATE   : code                        ROUTINE : Cphs_set_divert_status|
+------------------------------------------------------------------------+

  PURPOSE : Set the divert status on each line

*/

T_CPHS_RET Cphs_set_divert_status  (T_CPHS_FLAG_STATUS line1,
                               T_CPHS_FLAG_STATUS line2,
                               T_CPHS_FLAG_STATUS fax,
                               T_CPHS_FLAG_STATUS data)
{
  UBYTE result;
  char debug[50];

  TRACE_FUNCTION ("Cphs_set_divert_status()");

  /* Check CPHS support status. */
 // if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
  //  return cphs_data->cphsStatus;
sprintf(debug, "Original divert status: %x%x",cphs_data->dvData[0],cphs_data->dvData[1]);
  TRACE_EVENT(debug);
  /* Write status in buffer */
  if (line1 EQ CPHS_LINEFLAG_SET  OR
      line1 EQ CPHS_LINEFLAG_NOT_SET  )
  { cphs_data->dvData[0] &= 0xF0;			//zero low nibble
  	cphs_data->dvData[0] += line1&0x0F;            /* low Nibble */
  	}
  /*else
    cphs_data->dvData[0] |= 0x0F;*/

  if (line2 EQ CPHS_LINEFLAG_SET   OR
      line2 EQ CPHS_LINEFLAG_NOT_SET  )
  {cphs_data->dvData[0] &= 0x0F;			//zero high nibble
    cphs_data->dvData[0] += (line2 << 4)&0xF0;    /* high Nibble */
  }
  /*else
    cphs_data->dvData[0] = 0xF0 | cphs_data->dvData[0];*/

  if (fax EQ CPHS_LINEFLAG_SET   OR
      fax EQ CPHS_LINEFLAG_NOT_SET  )
  {  cphs_data->dvData[0] &= 0xF0;			//zero low nibble
    cphs_data->dvData[1] += fax&0x0F;              /* low Nibble */
  	}
 /* else
    cphs_data->dvData[1] |= 0x0F;*/

  if (data EQ CPHS_LINEFLAG_SET   OR
      data EQ CPHS_LINEFLAG_NOT_SET  )
  {	cphs_data->dvData[1] &= 0x0F;			//zero high nibble
    cphs_data->dvData[1] += (data << 4)&0xF0;     /* high Nibble */
  }
  /*else
    cphs_data->dvData[1] = 0xF0 | cphs_data->dvData[1];*/
	sprintf(debug, "Divert Data:%x%x", cphs_data->dvData[0], cphs_data->dvData[1]);
	TRACE_EVENT(debug);
  /* Read call forwarding flag to determine the size */
  cphs_data->simStatus = SIMOP_WRITE_OK;
  if (!Cphs_read_sim_dat(SIM_CPHS_CFF, NOT_PRESENT_8BIT, CPHS_CFF_SIZE))
  {	TRACE_EVENT("Mailbox SIM write failed");
    return SIMOP_WRITE_ERR;
    //cphs_sign_exec(E_CPHS_SET_DV_STAT, &result);
  }
/* PATCH VO 22.01.01 end */
  return cphs_data->cphsStatus;
}

/*CPHS_RET cphs_set_als_status (T_CPHS_ALS_INFO status)
{
  UBYTE result;
  //T_MFW_SIM_PIN_STATUS pinStatus;

  //TRACE_EVENT ("cphs_set_als_status()");

  /* check PIN 2 requirement */
  /*pinStatus.type = MFW_SIM_PIN2;
  sim_pin_status(&pinStatus);
  if (pinStatus.set NEQ MFW_SIM_NO_PIN)
    return MFW_SIM_PIN2_REQ;

  /* check given parameter */
  /*if (status NEQ MFW_LINE_LOCKED  AND
      status NEQ MFW_LINE_UNLOCKED     )
  {
    result = MFW_SIMOP_WRITE_ERR;
    //cphs_sign_exec(E_CPHS_SET_ALS_STATUS, &result);
    return CPHS_ERR;
  }*/

 /* cphs_data->alsData = (UBYTE)status.locked;*/

    /* write lock status in EEPROM */
    //MC cphs_write_eeprom_alss(&result);
    //cphs_sign_exec(E_CPHS_SET_LINE, &result);
//  }
/*  return CPHS_IS_OK;
}*/

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module               							|
| STATE  : code                         ROUTINE: Cphs_read_sim_dat     |
+----------------------------------------------------------------------+


   PURPOSE :   Request to read SIM card.

*/

BOOL Cphs_read_sim_dat(USHORT data_id, UBYTE len, UBYTE max_length)
{
  T_ACI_RETURN res;

  TRACE_FUNCTION ("Cphs_read_sim_dat()");

  res = cmhSIM_ReadTranspEF ( CMD_SRC_NONE,
                              AT_CMD_NONE,
                              data_id,
                              0,
                              max_length,
                              NULL,
                              Cphs_read_sim_dat_cb);
  if (res NEQ AT_EXCT)
    return FALSE;

  return TRUE;
}

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module               							|
| STATE  : code                         ROUTINE: Cphs_read_sim_dat_cb  	|
+----------------------------------------------------------------------+


   PURPOSE :   Call back for SIM read.

*/

void Cphs_read_sim_dat_cb(SHORT table_id)
{
  UBYTE        dataLen;
  UBYTE        result;


  switch (simShrdPrm.atb[table_id].reqDataFld)
  {
    case SIM_CPHS_CINF:	/* CPHS information */
      if (!cphs_data->cphsUpdate)
        Cphs_read_information(simShrdPrm.atb[table_id].errCode,
                              simShrdPrm.atb[table_id].exchData,
                              simShrdPrm.atb[table_id].dataLen);
/*#ifdef SIM_TOOLKIT
      else
        Cphs_update_info_cnf(simShrdPrm.atb[table_id].errCode,
                             simShrdPrm.atb[table_id].exchData,
                             simShrdPrm.atb[table_id].dataLen);
#endif*/
      break;

    case SIM_CPHS_ONSTR:  /* operator name string */

      Cphs_read_ons(simShrdPrm.atb[table_id].errCode,
                    simShrdPrm.atb[table_id].exchData,
                    simShrdPrm.atb[table_id].dataLen);
      break;

    case SIM_CPHS_ONSHF:	/* operator name short form */

      Cphs_read_onsf(simShrdPrm.atb[table_id].errCode,
                     simShrdPrm.atb[table_id].exchData,
                     simShrdPrm.atb[table_id].dataLen);
      Cphs_get_mailbox_status();//get next item
      break;

    case SIM_CPHS_VMW:	/* voice message waiting flag */

      if (cphs_data->simStatus EQ SIMOP_WRITE_OK)
      {
        /* Determine the size of this field, and write the data.
           When the writing is not possible, write this voice
           message waiting flag in EEPROM.                     */
        cphs_data->simStatus = SIMOP_UNKNOWN;
#ifdef FF_2TO1_PS
        if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
        if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
        {
          dataLen = simShrdPrm.atb[table_id].dataLen;
          /* Write voice message waiting flag.
             When this writing failed, send event with "write error" parameter to MMI */
          if (!Cphs_write_sim_dat(SIM_CPHS_VMW, cphs_data->mbsData, dataLen))
          {
            cphs_data->mbStatus.result    = SIMOP_WRITE_ERR;

            cphs_data->mbStatus.line1 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->mbStatus.line2 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->mbStatus.fax = CPHS_FLAG_NOT_PRESENT;
            cphs_data->mbStatus.data = CPHS_FLAG_NOT_PRESENT;
          }
        }
        else
        {
          cphs_data->mbStatus.result = SIMOP_WRITE_ERR;
          //cphs_sign_exec(E_CPHS_SET_VC_STAT, &result);
          cphs_data->mbStatus.line1 = CPHS_FLAG_NOT_PRESENT;
		  cphs_data->mbStatus.line2 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->mbStatus.fax = CPHS_FLAG_NOT_PRESENT;
            cphs_data->mbStatus.data = CPHS_FLAG_NOT_PRESENT;
        }
      }
      else
/* PATCH VO 22.01.01 end */
      {
      	Cphs_read_mbs (simShrdPrm.atb[table_id].errCode,
                       simShrdPrm.atb[table_id].exchData,
                       simShrdPrm.atb[table_id].dataLen);
      	Cphs_get_csp();
      }
      break;

    case SIM_CPHS_CFF:	/* call forwarding flag */
/* PATCH VO 22.01.01 */
      if (cphs_data->simStatus EQ SIMOP_WRITE_OK)
      {
        /* Determine the size of this field, and write the data.
           When the writing is not possible, write this voice
           message waiting flag in EEPROM.                     */
        cphs_data->simStatus = SIMOP_UNKNOWN;
#ifdef FF_2TO1_PS
        if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
        if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
        {
          dataLen = simShrdPrm.atb[table_id].dataLen;
          /* Write call forwarding flag.
             When this writing failed, send event with "write error" parameter to MMI */
         if (!Cphs_write_sim_dat(SIM_CPHS_CFF, cphs_data->dvData, dataLen))
          { TRACE_EVENT("Divert write failed");
            cphs_data->dvStatus.result    = SIMOP_WRITE_ERR;
             cphs_data->dvStatus.line1 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->dvStatus.line2 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->dvStatus.fax = CPHS_FLAG_NOT_PRESENT;
            cphs_data->dvStatus.data = CPHS_FLAG_NOT_PRESENT;
          }
        }
        else
        {TRACE_EVENT("Sim error while writing");
          cphs_data->dvStatus.result = SIMOP_WRITE_ERR;
            cphs_data->dvStatus.line1 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->dvStatus.line2 = CPHS_FLAG_NOT_PRESENT;
			cphs_data->dvStatus.fax = CPHS_FLAG_NOT_PRESENT;
            cphs_data->dvStatus.data = CPHS_FLAG_NOT_PRESENT;
        }
      }
      else
/* PATCH VO 22.01.01 end */
      	{Cphs_get_mailbox();
      		Cphs_read_cff (simShrdPrm.atb[table_id].errCode,
                     simShrdPrm.atb[table_id].exchData,
                     simShrdPrm.atb[table_id].dataLen);
      	}
      break;



    case SIM_CPHS_CSP:	/* customer service profile */
      Cphs_read_csp (simShrdPrm.atb[table_id].errCode,
                     simShrdPrm.atb[table_id].exchData,
                     simShrdPrm.atb[table_id].dataLen);
      //All CPHS data fields have now been read
      //so call callback function to alert client layer

      break;

    default:
      break;
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module               							|
| STATE  : code                         ROUTINE: Cphs_read_sim_rcd     	|
+----------------------------------------------------------------------+


   PURPOSE :   Request to read SIM card.

*/

BOOL Cphs_read_sim_rcd(USHORT data_id, UBYTE rcd_num, UBYTE len)
{
  T_ACI_RETURN res;
  UBYTE        dataLen;

  TRACE_FUNCTION ("Cphs_read_sim_rcd()");

  if (rcd_num EQ 1)
      dataLen  = UCHAR_MAX;
    else
      dataLen  = len;

  res = cmhSIM_ReadRecordEF ( CMD_SRC_NONE,
                              AT_CMD_NONE,
                              data_id,
                              rcd_num,
                              dataLen,
                              NULL,
                              Cphs_read_sim_rcd_cb);

  if (res NEQ AT_EXCT)
    return FALSE;

  return TRUE;
}

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module               							|
| STATE  : code                         ROUTINE: Cphs_read_sim_rcd_cb  	|
+----------------------------------------------------------------------+


   PURPOSE :   Request to read SIM card.

*/

void Cphs_read_sim_rcd_cb (SHORT table_id)
{
  UBYTE dataLen;
  char debug[25];
sprintf(debug, "SIM Error code!!!%d", simShrdPrm.atb[table_id].errCode);

  TRACE_FUNCTION ("Cphs_read_sim_rcd_cb()");
  TRACE_EVENT(debug);

  switch (simShrdPrm.atb[table_id].reqDataFld)
  {
    case SIM_CPHS_MBXN: /* mailbox numbers */
      if (cphs_data->simStatus EQ SIMOP_WRITE_OK)
      {
        /* Determine the size of record, and write a new record.
           When the writing is not possible, write this mailbox
           number in EEPROM.                                 */
        cphs_data->simStatus = SIMOP_UNKNOWN;
#ifdef FF_2TO1_PS
        if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
        if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
        {
          dataLen = simShrdPrm.atb[table_id].dataLen;
          /* allocate mbnData (sizeof(dataLen)) */
          Cphs_build_mbn_data(cphs_data->mbnData, dataLen);
          if (!Cphs_write_sim_rcd(SIM_CPHS_MBXN, cphs_data->vcEntry->index,
                                cphs_data->mbnData, dataLen))
            Cphs_write_eeprom_mailbox(cphs_data->vcEntry);
        }
        else
          Cphs_write_eeprom_mailbox(cphs_data->vcEntry);
      }
      else
        Cphs_read_mbn(table_id);

      break;

    case SIM_CPHS_INFN: /* information numbers */
      if (simShrdPrm.atb[table_id].recNr EQ 1)
      {

        if ((cphs_data->startIdx EQ 1) AND (cphs_data->simStatus EQ SIMOP_READ_OK))
          Cphs_read_info_num(table_id);
        else

          Cphs_read_first_info_num(table_id);
      }
      else
        Cphs_read_info_num(table_id);
      break;

    case SIM_CPHS_INFN2:	 /* information numbers 2 - 7F10 'EA01' selected if SIM_CPHS_INFN '6F19' isn't there*/
      if (simShrdPrm.atb[table_id].recNr EQ 1)
      {

        if ((cphs_data->startIdx EQ 1) AND (cphs_data->simStatus EQ SIMOP_READ_OK))
          Cphs_read_info_num(table_id);
        else
        Cphs_read_first_info_num(table_id);
      }
      else
        Cphs_read_info_num(table_id);
      break;

    default:
      break;
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module   							            |
| STATE  : code                         ROUTINE: Cphs_write_sim_rcd    	|
+----------------------------------------------------------------------+


   PURPOSE :   Request to write SIM card.

*/

BOOL Cphs_write_sim_rcd(USHORT data_id, UBYTE rcd_num,
                        UBYTE *data,    UBYTE dataLen)
{
  T_ACI_RETURN res;

  TRACE_FUNCTION ("Cphs_read_sim_rcd()");

  res = cmhSIM_WriteRecordEF (CMD_SRC_NONE,
                              AT_CMD_NONE,
                              data_id,
                              rcd_num,
                              dataLen,
                              data,
                              Cphs_write_sim_rcd_cb);

  if (res NEQ AT_EXCT)
    return FALSE;

  return TRUE;
}

/*
+----------------------------------------------------------------------+
| MODULE: CPHS standalone module               |
| STATE  : code                         ROUTINE: Cphs_write_sim_rcd_cb |
+----------------------------------------------------------------------+


   PURPOSE :   callback of SIM card writing.

*/

void Cphs_write_sim_rcd_cb (SHORT table_id)
{
  UBYTE result;
char debug[30];
  TRACE_FUNCTION ("Cphs_write_sim_rcd_cb()");
	sprintf(debug, "SIM Error code!!!%d", simShrdPrm.atb[table_id].errCode);
  TRACE_EVENT(debug);
  switch (simShrdPrm.atb[table_id].reqDataFld)
  {
    case SIM_CPHS_MBXN: /* mailbox numbers */
#ifdef FF_2TO1_PS
      if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
      if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
      {
        cphs_data->mbNum.result = SIMOP_WRITE_OK;
        //cphs_sign_exec(E_CPHS_SET_VC_NUM, &result);
      }
      else
      {
        Cphs_write_eeprom_mailbox(cphs_data->vcEntry);
      }
      break;

    default:
      break;
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------------+
|         MODULE  : CPHS standalone module                 |
| STATE   : code                        ROUTINE : Cphs_read_first_info_num |
+--------------------------------------------------------------------------+

  PURPOSE : Read first record of information numbers

*/

void Cphs_read_first_info_num(SHORT table_id)
{
  //UBYTE*        pData;         /* points to data buffer    */
  UBYTE         dataLen;

  TRACE_FUNCTION ("Cphs_read_first_info_num()");

#ifdef FF_2TO1_PS
  if ( simShrdPrm.atb[table_id].errCode NEQ CAUSE_SIM_NO_ERROR ) /* VO patch 040501 - remove dataLen and pData check */
#else
  if ( simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR ) /* VO patch 040501 - remove dataLen and pData check */
#endif
  {
    if (cphs_data->simStatus EQ SIMOP_READ_OK) /* Read entry of information numbers */
    {
      cphs_data->simStatus = SIMOP_UNKNOWN;
      cphs_data->infoEntry->result = SIMOP_READ_ERR;
      if (cphs_data->InfoNumberCB != NULL)
      	(cphs_data->InfoNumberCB)(NULL, cphs_data->infoEntry);

    }
    else
    {// if we are here then its possible the read of 7F20 6F19 failed.
     // so we must try reading 7F10 EA01 instead.

     if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN)
     {
      if (!Cphs_read_sim_rcd(SIM_CPHS_INFN2, 1, 0))
      {
        cphs_data->infoEntry->result = SIMOP_READ_ERR;
        if (cphs_data->InfoNumberCB != NULL)
        	(cphs_data->InfoNumberCB)(NULL, cphs_data->infoEntry);
      }
      else
      {
        cphs_data->cphsPrevRead = SIM_CPHS_INFN2;
      }
     }
    else
    { if (cphs_data->InfoNumberListCB != NULL)
     	(cphs_data->InfoNumberListCB)(cphs_data->numList, NULL);
    }
    }
  }
  else
  {
    cphs_data->maxRec = simShrdPrm.atb[table_id].recMax;
    dataLen = simShrdPrm.atb[table_id].dataLen;

    if (cphs_data->simStatus EQ SIMOP_READ_OK) /* Read entry of information numbers */
    {
      /* VO patch 040501 - add dataLen check: if (patch) else ...  */
      if (dataLen < CPHS_MIN_INS_SIZE )
      {
        cphs_data->simStatus = SIMOP_UNKNOWN;
        cphs_data->infoEntry->result = SIMOP_READ_ERR;
      }
      else
        Cphs_req_info_num_read(cphs_data->startIdx, dataLen);
    }
    else /* Read list of information numbers */
    {
      /* VO patch 040501 - add dataLen check: if (patch) else ...  */
      if (dataLen >= CPHS_MIN_INS_SIZE )
      {
        if (cphs_data->idxLevel EQ 1) /* read this entry */
          Cphs_read_info_num(table_id);
        else    /* read the startIndex record */
          Cphs_req_info_num_read(cphs_data->startIdx, dataLen);
      }
    }
  }
}
T_PHB_NPI cvtNpi(T_ACI_TOA_NPI npi)
{
    switch (npi)
	{
    case NPI_NotPresent:
    case NPI_Unknown:       return CPHS_NPI_UNKNOWN;
    case NPI_IsdnTelephony: return CPHS_NPI_ISDN;
    case NPI_Data:          return CPHS_NPI_DATA;
    case NPI_Telex:         return CPHS_NPI_TELEX;
    case NPI_Private:       return CPHS_NPI_PRIVATE;
    case NPI_National:      return CPHS_NPI_NATIONAL;
#ifdef FF_2TO1_PS
    case NPI_Ermes:         return CPHS_NPI_M_ERMES;
    case NPI_Cts:           return CPHS_NPI_M_CTS;
#else
    case NPI_ERMES:         return CPHS_NPI_M_ERMES;
    case NPI_CTS:           return CPHS_NPI_M_CTS;
#endif
    default:                return npi;
	}
}
/*
+---------------------------------------------------------------------+
|         MODULE  : CPHS standalone module            |
| STATE   : code                        ROUTINE : Cphs_read_info_num  |
+---------------------------------------------------------------------+

  PURPOSE : Read first record of information numbers

*/

void Cphs_read_info_num(SHORT table_id)
{
  UBYTE*        pData;         /* points to data buffer    */
  UBYTE         dataLen;
  UBYTE         alphaLen;
  UBYTE         recNr;
  T_ACI_TOA     type;

  TRACE_FUNCTION ("Cphs_read_info_num()");

  pData   = simShrdPrm.atb[table_id].exchData;
  dataLen = simShrdPrm.atb[table_id].dataLen;
  recNr   = simShrdPrm.atb[table_id].recNr;

#ifdef FF_2TO1_PS
  if ( simShrdPrm.atb[table_id].errCode NEQ CAUSE_SIM_NO_ERROR  OR
#else
  if ( simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR  OR
#endif
       pData EQ NULL                                      OR
       dataLen   <  CPHS_MIN_INS_SIZE                    )
  {
    if (cphs_data->simStatus EQ SIMOP_READ_OK) /* Read entry of information numbers */
    {
      cphs_data->simStatus = SIMOP_UNKNOWN;
      cphs_data->infoEntry->result = SIMOP_READ_ERR;
      TRACE_EVENT("Info num read error");
       if (cphs_data->InfoNumberCB != NULL)
      		(cphs_data->InfoNumberCB)(NULL, cphs_data->infoEntry);

    }
    else
    {// if we are here then its possible the read of 7F20 6F19 failed.
     // so we must try reading 7F10 EA01 instead.

     if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN2)
     {
      if (!Cphs_read_sim_rcd(SIM_CPHS_INFN2, 1, 0))
      {
        cphs_data->infoEntry->result = SIMOP_READ_ERR;
         if (cphs_data->InfoNumberCB != NULL)
        		(cphs_data->InfoNumberCB)(NULL, cphs_data->infoEntry);
      }
      else
      {
        cphs_data->cphsPrevRead = SIM_CPHS_INFN2;
      }
     }
     else
     { 	if (cphs_data->InfoNumberListCB != NULL)
     		(cphs_data->InfoNumberListCB)(cphs_data->numList, NULL);
     }
    }
  	(cphs_data->InfoNumberListCB)(cphs_data->numList, NULL);
  }
  else
  {
    if (cphs_data->simStatus EQ SIMOP_READ_OK)
    {
      /* Read entry of information numbers */
      alphaLen = *pData;
      if (alphaLen)
      {
        /* copy/encode entry */
        cphs_data->infoEntry->index   = recNr;
        cphs_data->infoEntry->entryStat = *(pData + 1);

        cmhPHB_getMfwTagNt(pData + 2, alphaLen,
                          cphs_data->infoEntry->alpha.data, &cphs_data->infoEntry->alpha.len);

        pData += alphaLen + 2;

        if (*pData NEQ 0xFF)
        {
          cmhPHB_getAdrStr ( (CHAR *)cphs_data->infoEntry->number,
                             3,          /* length of number */
                             pData + 2,
                             *pData );
          cmhPHB_toaDmrg ( *( pData + 1 ), &type );
          cphs_data->infoEntry->ton = cvtTon(type.ton);
          cphs_data->infoEntry->npi = cvtNpi(type.npi);
          cphs_data->infoEntry->entryStat = cphs_data->infoEntry->entryStat | 0x80;
        }
        else
        {
          cphs_data->infoEntry->number[0] = '\0';
          cphs_data->infoEntry->ton       = CPHS_TON_UNKNOWN;
          cphs_data->infoEntry->npi       = CPHS_NPI_UNKNOWN;
        }
      }
      cphs_data->infoEntry->result = SIMOP_READ_OK;
      if (cphs_data->InfoNumberCB != NULL)
      	(cphs_data->InfoNumberCB)((T_CPHS_INFO_NUM_LIST*)NULL, cphs_data->infoEntry);
      return;
    }

    else if ((*(pData + 1) & 0x0F) > cphs_data->idxLevel)
    {
      /* This is not wished index level. Read the next */
      recNr++;
      Cphs_req_info_num_read(recNr, dataLen);
    }
    else
    {
      /* This is the wished index level. Read it. */
      alphaLen = *pData;
      if (alphaLen)      /* check alpha length */
      {
        /* copy/encode this entry in list */
        cphs_data->numList->level = cphs_data->idxLevel;
        cphs_data->numList->entry[cphs_data->numList->count].index   = recNr;
        cphs_data->numList->entry[cphs_data->numList->count].entryStat = *(pData + 1) & 0x7F;   /* set bit 8 to 0 */

        cmhPHB_getMfwTagNt(pData + 2, alphaLen,
                           cphs_data->numList->entry[cphs_data->numList->count].alpha.data,
                           &cphs_data->numList->entry[cphs_data->numList->count].alpha.len);

        pData += alphaLen + 2;

        if (*pData NEQ 0xFF)
        {
          cphs_data->numList->entry[cphs_data->numList->count].entryStat = cphs_data->numList->entry[cphs_data->numList->count].entryStat | 0x80;
        }
        cphs_data->numList->count++;
      }
      recNr++;
      /* Read the next record */
      Cphs_req_info_num_read(recNr, dataLen);
    }
  }
}


/*
+------------------------------------------------------------------------+
| MODULE  : CPHS standalone module               						|
| STATE   : code                        ROUTINE : Cphs_req_info_num_read |
+------------------------------------------------------------------------+

  PURPOSE : Read customer service profile

*/

void Cphs_req_info_num_read(UBYTE rcd_num, UBYTE dataLen)
{
  TRACE_FUNCTION ("Cphs_req_info_num_read()");

  if (rcd_num > cphs_data->maxRec)
  {  if (cphs_data->InfoNumberListCB != NULL)
  		(cphs_data->InfoNumberListCB)(cphs_data->numList, (T_CPHS_INFO_NUM_ENTRY*) NULL);

  	return;
  	}
  else
  {
    if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN)
    {
      if (Cphs_read_sim_rcd(SIM_CPHS_INFN, rcd_num, dataLen))
      {

        cphs_data->cphsPrevRead = SIM_CPHS_INFN;
      }
    }
    else
    {
      if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN2)
      {
        if (!Cphs_read_sim_rcd(SIM_CPHS_INFN2, rcd_num, dataLen))
        	 if (cphs_data->InfoNumberListCB != NULL)
				(cphs_data->InfoNumberListCB)(cphs_data->numList, (T_CPHS_INFO_NUM_ENTRY*) NULL);
        else
        {
          cphs_data->cphsPrevRead = SIM_CPHS_INFN2;
        }
      }
    }
  }
}

/*
+----------------------------------------------------------------------+
|          MODULE: CPHS standalone module               |
| STATE  : code                         ROUTINE: Cphs_build_mbn_data   |
+----------------------------------------------------------------------+


   PURPOSE :   Build mailbox number data in SIM format.

*/

void Cphs_build_mbn_data(UBYTE *data, UBYTE len)
{
  UBYTE     alphaLen;
  UBYTE     numLen;
  UBYTE     *pNumber;
  UBYTE     i, j;

  TRACE_FUNCTION ("Cphs_build_mbn_data()");

  memset(data, MFW_INVALID_SIM_DATA, len);

  /* alpha data */
  if (len <= CPHS_MIN_MBN_SIZE)
    alphaLen = 0;
  else
    alphaLen = len - CPHS_MIN_MBN_SIZE;
  i = MINIMUM (alphaLen, cphs_data->vcEntry->alpha.len);

  for ( j = 0; j < i; j++ )
    data[j] = cphs_data->vcEntry->alpha.data[j];

  data += alphaLen;

  /* number data and TON/NPI data */
  if ( cphs_data->vcEntry->number[0] EQ '+' )
  {
    cphs_data->vcEntry->ton = TON_International;
    pNumber  = &cphs_data->vcEntry->number[1];
  }
  else
    pNumber  = &cphs_data->vcEntry->number[0];

  cmhPHB_getAdrBcd ( data + 2, &numLen,
                     PHB_MAX_LEN, (CHAR *)pNumber );
  *data      = numLen + 1;
  *(data + 1) = ((( cphs_data->vcEntry -> ton << 4 ) & 0xF0 ) + ( cphs_data->vcEntry -> npi & 0x0F )) | 0x80;

  data += 12;

  /* capability/configuration identifier data and EXT identifier data */
  *data      = 0xFF;
  *(data + 1) = 0xFF;
}

/*
+--------------------------------------------------------------------------+
|         MODULE  : CPHS standalone module                 |
| STATE   : code                        ROUTINE : Cphs_read_eeprom_mailbox |
+--------------------------------------------------------------------------+

  PURPOSE : Read mailbox number from EEPROM

*/

void Cphs_read_eeprom_mailbox(void)
{
  U8                  version;
  
  #ifdef PCM_2_FFS
  EF_MBN              mbn;
  #else
  T_PSPDF_MBN              mbn;
  #endif
  
  T_ACI_TOA           numTp;
  int                 i;
  USHORT              max_rcd;
TRACE_FUNCTION("Cphs_read_eeprom_mailbox()");
  for (i=0; i<MAX_CPHS_ENTRY; i++)
  {
   //switching from PCM to FFS
#ifdef PCM_2_FFS   
    if (ffs_fread("/Mailbox_no", &mbn, sizeof(mbn)) EQ EFFS_OK)
#else
    if (FFS_fread("/Mailbox_no", &mbn, sizeof(mbn)) EQ EFFS_OK)
#endif
    {
      if (mbn.len)
      {
        cphs_data->mbNum.entries[cphs_data->mbNum.count].index = i+1;
        cmhPHB_getAdrStr ( (char *)cphs_data->mbNum.entries[cphs_data->mbNum.count].number,
                           PHB_MAX_LEN - 1, mbn.mbNum, mbn.len );
        cmhPHB_getMfwTagNt ( mbn.alphId, 10,
                             cphs_data->mbNum.entries[cphs_data->mbNum.count].alpha.data,
                             &cphs_data->mbNum.entries[cphs_data->mbNum.count].alpha.len );
        cmhPHB_toaDmrg ( mbn.numTp, &numTp );
        cphs_data->mbNum.entries[cphs_data->mbNum.count].ton = cvtTon(numTp.ton);
        cphs_data->mbNum.entries[cphs_data->mbNum.count].npi = cvtNpi(numTp.npi);
        cphs_data->mbNum.entries[cphs_data->mbNum.count].service = i;
        cphs_data->mbNum.count++;
      }
    }
  }
}

/*
+---------------------------------------------------------------------------+
|         MODULE  : CPHS standalone module                  |
| STATE   : code                        ROUTINE : Cphs_write_eeprom_mailbox |
+---------------------------------------------------------------------------+

  PURPOSE : Write mailbox number in EEPROM

*/

void Cphs_write_eeprom_mailbox(T_CPHS_MAILBOX_NUM_ENTRY *entry)
{
  T_ACI_PB_TEXT text;
  UBYTE         len;
  
#ifdef PCM_2_FFS
  EF_MBN        mbn;
 #else
  T_PSPDF_MBN     mbn;
 #endif
 
  T_ACI_TOA     type;
  UBYTE         *pNumber;
  UBYTE         result;
  UBYTE         outLen;
  TRACE_FUNCTION("Cphs_write_eeprom_mailbox");

  len = MINIMUM ( MAX_PCM_MAILBOX_LEN, entry->alpha.len);
  text.len = len;
  memcpy(text.data, entry->alpha.data, len);
  text.cs = CS_Sim;
  cmhPHB_getMfwTagSim ( &text, mbn.alphId, &outLen, MAX_PCM_MAILBOX_LEN );

  if ( entry->number[0] EQ '+')
  {
    type.ton = TON_International;
    pNumber = &entry->number[1];
  }
  else
  {
    type.ton = entry->ton;
    pNumber = &entry->number[0];
  }
  type.npi = entry->npi;
  //MC- switching from PCM to FFS
  cmhPHB_toaMrg ( &type, &mbn.numTp );

  cmhPHB_getAdrBcd ((UBYTE*) mbn.mbNum, &mbn.len,
                    MAX_PCM_MAILBOX_LEN, (CHAR *)pNumber );
 mbn.len++;

  //if (pcm_WriteRecord((UBYTE *)EF_MBN_ID, (USHORT)entry->index,
  //                    SIZE_EF_MBN, (UBYTE *)&mbn) EQ PCM_OK)
 // if (flash_write() EQ EFFS_OK)
 #ifdef PCM_2_FFS
 if (ffs_fwrite("/Mailbox_no", &mbn, sizeof(mbn)) EQ EFFS_OK)
#else
 if (FFS_fwrite("/Mailbox_no", &mbn, sizeof(mbn)) EQ EFFS_OK)
#endif
    cphs_data->mbNum.result = SIMOP_WRITE_OK;
  else
    cphs_data->mbNum.result = SIMOP_WRITE_ERR;

}


/*
+----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module             |
| STATE   : code                        ROUTINE : Cphs_select_info_num |
+----------------------------------------------------------------------+

  PURPOSE : read a information number entry

*/

void Cphs_select_info_num (UBYTE index)
{
  TRACE_FUNCTION ("Cphs_select_info_num()");

  /* check CPHS service table */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return ;

  /* Read a information number entry.
     When this reading failed, send event with "read error" parameter to MMI */
  cphs_data->simStatus = SIMOP_READ_OK;
  cphs_data->startIdx  = index;

  // By now we know if 6F19 or EA01 are present for reading info. num entries from
  // So lets use this knowledge.

  if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN)
  {
    if (!Cphs_read_sim_rcd(SIM_CPHS_INFN, 1, 0))
    {
      cphs_data->infoEntry->result = SIMOP_READ_ERR;
      //cphs_sign_exec(E_CPHS_GET_INFO_NUM, &infoEntry);
       (cphs_data->InfoNumberCB)((T_CPHS_INFO_NUM_LIST*) NULL, cphs_data->infoEntry);
    }
    else
    {
      cphs_data->cphsPrevRead = SIM_CPHS_INFN;
    }
  }
  else
  {
    if (cphs_data->cphsPrevRead EQ SIM_CPHS_INFN2)
    {
      if (!Cphs_read_sim_rcd(SIM_CPHS_INFN2, 1, 0))
      {
        cphs_data->infoEntry->result = SIMOP_READ_ERR;
        //cphs_sign_exec(E_CPHS_GET_INFO_NUM, &infoEntry);
         (cphs_data->InfoNumberCB)((T_CPHS_INFO_NUM_LIST*)NULL, cphs_data->infoEntry);
      }
      else
      {
        cphs_data->cphsPrevRead = SIM_CPHS_INFN2;
      }
    }
  }
}



/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              |
| STATE   : code                        ROUTINE : Cphs_read_ons 			  |
+-----------------------------------------------------------------------+

  PURPOSE : Read operator name short form

*/

void Cphs_read_ons(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;

  TRACE_FUNCTION ("Cphs_read_ons()");

  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       // dataLen < MFW_CPHS_ONS_SIZE  )
       dataLen <= 0  ) /* PATCH VO 22.01.01: not check a certain length */
  {
    cphs_data->opName.long_name.len = 0;
  }
  else
  {
    cmhPHB_getMfwTagNt(ptr, (UBYTE)MINIMUM(LONG_NAME, dataLen),
                       cphs_data->opName.long_name.data, &cphs_data->opName.long_name.len);
    //cphs_data->opName.long_name.dcs = MFW_DCS_SIM;

    /* Read operator name shortform */
    if ((cphs_data->cphsPhase NEQ 2)                                                          OR
        (Cphs_ssc(CHPS_NAME_SHORT,   cphs_data->cphsServTab) NEQ ALLOCATED_AND_ACTIVATED) OR
        !Cphs_read_sim_dat(SIM_CPHS_ONSHF, NOT_PRESENT_8BIT, CPHS_ONSF_SIZE)                  )
    {
      cphs_data->opName.short_name.len = 0;
    }
  }
}

/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              				|
| STATE   : code                        ROUTINE : Cphs_read_onsf			  |
+-----------------------------------------------------------------------+

  PURPOSE : Read operator name short form

*/

void Cphs_read_onsf(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;

  TRACE_FUNCTION ("Cphs_read_onsf()");

  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       dataLen < CPHS_ONSF_SIZE )
  {
    cphs_data->opName.short_name.len = 0;
  }
  else
  {
    cmhPHB_getMfwTagNt(ptr, CPHS_ONSF_SIZE,
                       cphs_data->opName.short_name.data, &cphs_data->opName.short_name.len);
    //cphs_data->opName.shortName.dcs = MFW_DCS_SIM;
  }

  //cphs_sign_exec(E_CPHS_OP_NAME, &opName);
}

/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              				|
| STATE   : code                        ROUTINE : cvtTon				|
+-----------------------------------------------------------------------+

  PURPOSE : Convert Type of Number

*/


T_CPHS_PHB_TON cvtTon(T_ACI_TOA_TON ton)
{
    switch (ton)
	{
    case TON_NotPresent:
    case TON_Unknown:           return CPHS_TON_UNKNOWN;
    case TON_International:     return CPHS_TON_INTERNATIONAL;
    case TON_National:          return CPHS_TON_NATIONAL;
    case TON_NetSpecific:       return CPHS_TON_NET_SPECIFIC;
    case TON_DedAccess:         return CPHS_TON_DED_ACCESS;
    case TON_Alphanumeric:      return CPHS_TON_ALPHA_NUMERIC;
    case TON_Abbreviated:       return CPHS_TON_ABBREVIATED;
    case TON_Extended:          return CPHS_TON_EXTENDED;
		default:					          return ton;
	}
}
/*
+-----------------------------------------------------------------------+
| MODULE  : CPHS standalone module              						|
| STATE   : code                        ROUTINE : cphs_read_mbn  		|
+-----------------------------------------------------------------------+

  PURPOSE : Read mailbox number into runtime variables

*/
void Cphs_read_mbn(SHORT table_id)
{
  UBYTE*        pData;         /* points to data buffer    */
  UBYTE         alphaLen;
  UBYTE         dataLen;
  UBYTE         recNr;
  T_ACI_TOA     type;

  TRACE_FUNCTION ("Cphs_read_mbn()");

  pData   = simShrdPrm.atb[table_id].exchData;
  dataLen = simShrdPrm.atb[table_id].dataLen;
  recNr   = simShrdPrm.atb[table_id].recNr;

#ifdef FF_2TO1_PS
  if ( simShrdPrm.atb[table_id].errCode NEQ CAUSE_SIM_NO_ERROR  OR
#else
  if ( simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR  OR
#endif
       pData EQ NULL                                      OR
       dataLen   <  CPHS_MIN_MBN_SIZE )
  {//MC FFS ?
   /* if (recNr <= 1)
    {
      Cphs_read_eeprom_mailbox();
      return;
    }
    else
      cphs_sign_exec(E_CPHS_GET_VC_NUM, &mbNum);*/
      TRACE_EVENT("MB read error");
      return;
  }
  else /* no read error */
  {
    if (recNr EQ 1)
    {
      cphs_data->maxRec = simShrdPrm.atb[table_id].recMax;
    }
    alphaLen = dataLen - CPHS_MIN_MBN_SIZE;

    /* Copy/encode data */
    if (*(pData + alphaLen + 2) NEQ 0xFF)
    {
      cphs_data->mbNum.entries[cphs_data->mbNum.count].index = recNr;
      cmhPHB_getMfwTagNt(pData, alphaLen,
                         cphs_data->mbNum.entries[cphs_data->mbNum.count].alpha.data,
                         &cphs_data->mbNum.entries[cphs_data->mbNum.count].alpha.len);
      pData += alphaLen;

      cmhPHB_getAdrStr ( (CHAR *)cphs_data->mbNum.entries[cphs_data->mbNum.count].number,
                         PHB_MAX_LEN - 1,
                         pData + 2,
                         *pData );

      cmhPHB_toaDmrg ( *( pData + 1 ), &type );
      cphs_data->mbNum.entries[cphs_data->mbNum.count].ton = cvtTon(type.ton);
      cphs_data->mbNum.entries[cphs_data->mbNum.count].npi = cvtNpi(type.npi);
      pData += 12;

      if ( *pData NEQ 0xFF )
      {
        /* read bearer capability EF */
        /* return; */
      }
      cphs_data->mbNum.count++;
      cphs_data->mbNum.result = SIMOP_READ_OK;
    }
    recNr++;
     if (recNr > cphs_data->maxRec)
    {	TRACE_FUNCTION("got CPHS Mailbox nos");
     Cphs_operator_name();//get next CPHS item
      return;

    }
    if (recNr <= cphs_data->maxRec)
    {
      /* Read the next entry */
      Cphs_read_sim_rcd(SIM_CPHS_MBXN, recNr, dataLen);
    }


  }
}

/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              |
| STATE   : code                        ROUTINE : Cphs_read_mbs 			  |
+-----------------------------------------------------------------------+

  PURPOSE : Read voice message waiting flag

*/

void Cphs_read_mbs(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;
  int   i; /* PATCH VO 22.01.01 */
  char debug[50];

  TRACE_FUNCTION ("Cphs_read_mbs()");

  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       //dataLen < MFW_CPHS_MBS_SIZE  )
       dataLen <= 0  )  /* PATCH VO 22.01.01: not check a certain length */
  {
    cphs_data->mbStatus.result = SIMOP_READ_ERR;
  }
  else
  {
sprintf(debug, "Retrieved mailbox status: %x%x",ptr[0],ptr[1]);
  TRACE_EVENT(debug);
    memset(&cphs_data->mbStatus, CPHS_FLAG_NOT_PRESENT, sizeof(cphs_data->mbStatus));
    cphs_data->mbStatus.result = SIMOP_READ_OK;
    for (i=0; i<dataLen; i++)
    {
      switch (i)
      {
        case 0:
          cphs_data->mbStatus.line1  = ptr[i] & 0x0F/*0x01*/;
          cphs_data->mbStatus.line2  = ( ptr[i] >> 4 ) & 0x0F/*0x01*/;
          break;
        case 1:
          cphs_data->mbStatus.fax    = ptr[i] & 0x0F/*0x01*/;
          cphs_data->mbStatus.data   = ( ptr[i] >> 4 ) & 0x0F/*0x01*/;
          break;
        default:
          break;
      }
    }
/* PATCH VO 22.01.01 END */
//Not sure about this
//memcpy(cphs_data->mbsData, ptr, CPHS_MBS_SIZE);
  }
}

/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              |
| STATE   : code                        ROUTINE : Cphs_read_cff 			  |
+-----------------------------------------------------------------------+

  PURPOSE : Read call forwarding flag

*/

void Cphs_read_cff(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;
  int   i; /* PATCH VO 22.01.01 */
  char debug[50];

  TRACE_EVENT ("Cphs_read_cff()");

  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       //dataLen < MFW_CPHS_CFF_SIZE  )
       dataLen <= 0  )  /* PATCH VO 22.01.01: not check a certain length */
  {
    cphs_data->dvStatus.result = SIMOP_READ_ERR;
  }
  else
  {
	sprintf(debug, "Retrieved divert status: %x%x",ptr[0],ptr[1]);
  TRACE_EVENT(debug);
    memset(&cphs_data->dvStatus, CPHS_FLAG_NOT_PRESENT, sizeof(cphs_data->dvStatus));
    cphs_data->dvStatus.result = SIMOP_READ_OK;
    for (i=0; i<dataLen; i++)
    {
      switch (i)
      {
        case 0:
          cphs_data->dvStatus.line1  = ptr[i] & /*0x0F*/0x01;
          cphs_data->dvStatus.line2  = ( ptr[i] >> 4 ) & /*0x0F*/0x01;
          break;
        case 1:
          cphs_data->dvStatus.fax    = ptr[i] & /*0x0F*/0x01;
          cphs_data->dvStatus.data   = ( ptr[i] >> 4 ) & /*0x0F*/0x01;
          break;
        default:
          break;
      }
    }
/* PATCH VO 22.01.01 END */
	//not sure about this bit
	//memcpy(cphs_data->dvData, ptr, CPHS_CFF_SIZE);
  }
}




/*
+-----------------------------------------------------------------------+
|         MODULE  : CPHS standalone module              |
| STATE   : code                        ROUTINE : Cphs_read_csp 			  |
+-----------------------------------------------------------------------+

  PURPOSE : Read customer service profile

*/

void Cphs_read_csp(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;
  UBYTE flag;
  int   i;

  TRACE_FUNCTION ("Cphs_read_csp()");

  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       // dataLen < MFW_CPHS_CSP_SIZE	 )
       dataLen <= 0	 )  /* PATCH VO 22.01.01: not check a certain length */
  {
    if (cphs_data->simStatus EQ SIMOP_READ_OK) /* Used for read information numbers */
    {
      cphs_data->simStatus = SIMOP_UNKNOWN;
      //cphs_sign_exec(E_CPHS_GET_INFO_LIST, &numList);
    }
    else
    {
      cphs_data->csProfile.result = SIMOP_READ_ERR;
      memset(cphs_data->csProfile.csp, 0, sizeof(cphs_data->csProfile.csp));
      //cphs_sign_exec(E_CPHS_GET_CSP, &csProfile);
       if (cphs_data->RefreshCB != NULL)
      	(cphs_data->RefreshCB)(NULL, NULL);
    }
  }
  else
  {
    if (cphs_data->simStatus EQ SIMOP_READ_OK) /* Used for read information numbers */
    {
      cphs_data->simStatus = SIMOP_UNKNOWN;

      /* check the service group code */
      flag = 0;
      //for (i = 0; i < MFW_CPHS_CSP_SIZE; i += 2)
      for (i = 0; i < dataLen; i += 2) /* PATCH VO 22.01.01: use the actual length in the SIM card */
      {
        if (ptr[i] EQ 0xD5 AND ptr[i+1] EQ 0xFF)
          flag = 1;
      }
      if (!flag)
      {
       // cphs_sign_exec(E_CPHS_GET_INFO_LIST, &numList);
        return;
      }

      /* Read the first information numbers record */
      if (!Cphs_read_sim_rcd(SIM_CPHS_INFN, 1, 0))
       { //cphs_sign_exec(E_CPHS_GET_INFO_LIST, &numList);
		TRACE_EVENT("Can't read info num rcd");
   		return;
      	}

      else
        cphs_data->cphsPrevRead = SIM_CPHS_INFN;
    }
    else
    {
      cphs_data->csProfile.result = SIMOP_READ_OK;
      TRACE_EVENT("CPHS valid CSP");
      //memcpy(cphs_data->csProfile.csp, ptr, sizeof(cphs_data->csProfile.csp));
      for (i=0; i<(dataLen/2); i++)
      	{
      		cphs_data->csProfile.csp[i].group_code = ptr[2*i];
      		cphs_data->csProfile.csp[i].services =ptr[2*i + 1];
      	}
       if (cphs_data->RefreshCB != NULL)
      	(cphs_data->RefreshCB)(NULL, NULL);
     // cphs_sign_exec(E_CPHS_GET_CSP, &cphs_data->csProfile);
    }
  }
}

void Cphs_read_information(SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;

  UBYTE len;


  TRACE_FUNCTION ("Cphs_read_information()");

  ptr = data;

  len = dataLen;
  memset(cphs_data->cphsServTab, 0, sizeof(cphs_data->cphsServTab));
/* PATCH VO 22.01.01 END */
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       //dataLen < MFW_CPHS_INFO_SIZE)
       dataLen <= 0) /* PATCH VO 22.01.01: not check a certain length */
  {
    cphs_data->cphsStatus = CPHS_NOT_PRESENT;
    //cphs_sign_exec(E_CPHS_IND, &cphsStatus);
  }
  else
  {
    cphs_data->cphsPhase = *ptr;
    len--;
    if (len > 0)
    {
      ptr++;
      memcpy (cphs_data->cphsServTab, ptr, MINIMUM(len, CPHS_SERVICE_TABLE));
    }
/* PATCH VO 22.01.01 END */
    cphs_data->cphsStatus = CPHS_IS_OK;
	TRACE_EVENT("CPHS supported");
    //cphs_sign_exec(E_CPHS_IND, &cphsStatus);
  }
}
#ifdef FRED //commented this func out because of build problems
#ifdef SIM_TOOLKIT
/*
+---------------------------------------------------------------------+
|    MODULE  : CPHS standalone module                 |
| STATE   : code                   ROUTINE : Cphs_update_info_cnf     |
+---------------------------------------------------------------------+

  PURPOSE : call back for SIM file read

*/

void Cphs_update_info_cnf (SHORT errCode, UBYTE *data, UBYTE dataLen)
{
  UBYTE *ptr;

  TRACE_FUNCTION ("Cphs_update_info_cnf()");

  cphs_data->cphsUpdate = FALSE; /* reset flag */
  ptr = data;
#ifdef FF_2TO1_PS
  if ( errCode NEQ CAUSE_SIM_NO_ERROR    OR
#else
  if ( errCode NEQ SIM_NO_ERROR    OR
#endif
       ptr EQ NULL                 OR
       dataLen < CPHS_INFO_SIZE)
  {
    satUpdateFiles(TRUE, SIM_CPHS_CINF);
  }
  else
  {
    cphs_data->cphsPhase = *ptr;
    ptr++;
    memcpy (cphs_data->cphsServTab, ptr, CPHS_SERVICE_TABLE*sizeof(UBYTE));
    cphs_data->cphsStatus = CPHS_IS_OK;
    satUpdateFiles ( TRUE, SIM_CPHS_CINF );
  }
}
#endif
#endif
BOOL Cphs_write_sim_dat(USHORT data_id, UBYTE *data, UBYTE length)
{
  T_ACI_RETURN res;

  TRACE_FUNCTION ("Cphs_write_sim_dat()");

  res = cmhSIM_WriteTranspEF (CMD_SRC_NONE,
                              AT_CMD_NONE,
                              data_id,
                              0,
                              length,
                              data,
                              Cphs_write_sim_dat_cb);

  if (res NEQ AT_EXCT)
    return FALSE;

  return TRUE;
}

/*
+----------------------------------------------------------------------+
|          MODULE: CPHS standalone module               |
| STATE  : code                         ROUTINE: Cphs_write_sim_dat_cb |
+----------------------------------------------------------------------+


   PURPOSE :   callback of SIM card writing.

*/

void Cphs_write_sim_dat_cb(SHORT table_id)
{
  UBYTE result;
	char debug[30];
  TRACE_FUNCTION ("sim_write_sim_dat_cb()");


  sprintf(debug, "SIM Error code!!!%d", simShrdPrm.atb[table_id].errCode);
  TRACE_EVENT(debug);
  switch (simShrdPrm.atb[table_id].reqDataFld)
  {
    case SIM_CPHS_VMW:  /* voice message waiting flag */
#ifdef FF_2TO1_PS
      if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
      if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
      {
        cphs_data->mbStatus.result = SIMOP_WRITE_OK;

      }
      else
      {
        cphs_data->mbStatus.result = SIMOP_WRITE_ERR;
      }
      break;

    case SIM_CPHS_CFF:  /* call forwarding flag */
#ifdef FF_2TO1_PS
      if ( simShrdPrm.atb[table_id].errCode EQ CAUSE_SIM_NO_ERROR )
#else
      if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
#endif
      {
        cphs_data->dvStatus.result = SIMOP_WRITE_OK;
       TRACE_EVENT("Divert Write successful");
      }
      else
      {
        cphs_data->dvStatus.result = SIMOP_WRITE_ERR;
        TRACE_EVENT("Divert Write Failed");
      }
      break;

    default:
      break;
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+-----------------------------------------------------------------------+
| MODULE  : CPHS standalone module              |
| STATE   : code                        ROUTINE : cphs_read_eeprom_als  |
+-----------------------------------------------------------------------+

  PURPOSE : Read alternate line service information from EEPROM

*/

T_CPHS_RET Cphs_read_eeprom_als(T_CPHS_ALS_INFO* info)
{	char read_result;
	char debug[50];

#ifdef PCM_2_FFS
 	read_result =ffs_fread("/AlsInfo",  info, sizeof(T_CPHS_ALS_INFO));
#else
 	read_result =FFS_fread("/AlsInfo",  info, sizeof(T_CPHS_ALS_INFO));
#endif

 	if (read_result == EFFS_OK)
 	{	info->result = SIMOP_READ_OK;
		return CPHS_IS_OK;
 	}
 	else
 	{	info->result = SIMOP_READ_ERR;
 		sprintf(debug, "ALS info read error:%d", read_result);
 		TRACE_EVENT(debug);
 		return CPHS_SIM_READ_ERROR;
 	}
}

/*
+-----------------------------------------------------------------------+
| MODULE  : CPHS standalone module         						     |
| STATE   : code                        ROUTINE : cphs_write_eeprom_als |
+-----------------------------------------------------------------------+

  PURPOSE : Write selected alternate line/lock status in EEPROM

*/

T_CPHS_RET Cphs_write_eeprom_als(T_CPHS_ALS_INFO* info)
{	char write_result;
	T_ACI_ALS_MOD alsMode;
	T_CPHS_RET return_result;

#ifdef PCM_2_FFS
 	write_result =ffs_fwrite("/AlsInfo",  info, sizeof(T_CPHS_ALS_INFO));
#else
 	write_result =FFS_fwrite("/AlsInfo",  info, sizeof(T_CPHS_ALS_INFO));
#endif

 	if (write_result >= EFFS_OK)
 	{	info->result = SIMOP_WRITE_OK;
 		return_result = CPHS_IS_OK;
 		TRACE_EVENT("ALS info write OK");
 	}
 	else
 	{	info->result = SIMOP_WRITE_ERR;
		return_result = CPHS_SIM_WRITE_ERROR;
		TRACE_EVENT("ALS info write error");
 	}

 	  if (cphs_data->alsStatus.line  EQ CPHS_LINE_INDEX_LINE1)
        alsMode = ALS_MOD_SPEECH;
      if (cphs_data->alsStatus.line EQ CPHS_LINE_INDEX_LINE2)
        alsMode = ALS_MOD_AUX_SPEECH;
      sAT_PercentALS(CMD_SRC_LCL, alsMode);
    return return_result;

}
/*
+-----------------------------------------------------------------------+
| MODULE  : CPHS standalone module         						     	|
| STATE   : code                        ROUTINE : cphs_write_eeprom_als_desc |
+-----------------------------------------------------------------------+

  PURPOSE : Write ALS line description in EEPROM

*/
void Cphs_write_eeprom_als_desc(T_CPHS_ALS_LINE* line)
{	char write_result = -1;
	T_CPHS_ALS_LINE* desc;
	if (line->line EQ CPHS_LINE_INDEX_LINE1)
	{	desc = &cphs_data->Line1_desc;
	
#ifdef PCM_2_FFS	
	 	write_result =ffs_fwrite("/AlsDesc1",  &cphs_data->Line1_desc, sizeof(cphs_data->Line1_desc));
#else
	 	write_result =FFS_fwrite("/AlsDesc1",  &cphs_data->Line1_desc, sizeof(cphs_data->Line1_desc));
#endif

	}
	if (line->line EQ CPHS_LINE_INDEX_LINE2)
	{	desc = &cphs_data->Line2_desc;
#ifdef PCM_2_FFS	
	 	write_result =ffs_fwrite("/AlsDesc2",  &cphs_data->Line2_desc, sizeof(cphs_data->Line1_desc));
#else
	 	write_result =FFS_fwrite("/AlsDesc2",  &cphs_data->Line2_desc, sizeof(cphs_data->Line1_desc));
#endif
	}

	 if (write_result >= EFFS_OK)
	 		desc->result = SIMOP_WRITE_OK;
	 	else
	 		desc->result = SIMOP_WRITE_ERR;
}
/*
+-----------------------------------------------------------------------+
| MODULE  : CPHS standalone module         						     	|
| STATE   : code                        ROUTINE : cphs_read_eeprom_als_desc |
+-----------------------------------------------------------------------+

  PURPOSE : read ALS line description from EEPROM

*/
void Cphs_read_eeprom_als_desc()
{	char read_result = -1;
	T_CPHS_ALS_LINE* desc;

#ifdef PCM_2_FFS
	 	read_result =ffs_fread("/AlsDesc1",  &cphs_data->Line1_desc, sizeof(cphs_data->Line1_desc));
#else
	 	read_result =FFS_fread("/AlsDesc1",  &cphs_data->Line1_desc, sizeof(cphs_data->Line1_desc));
#endif
	 	if (read_result >= EFFS_OK)
	 		cphs_data->Line1_desc.result = SIMOP_READ_OK;
	 	else
			cphs_data->Line1_desc.result = SIMOP_READ_ERR;


#ifdef PCM_2_FFS
	 	read_result =ffs_fread("/AlsDesc2",  &cphs_data->Line2_desc, sizeof(cphs_data->Line1_desc));
#else
	 	read_result =FFS_fread("/AlsDesc2",  &cphs_data->Line2_desc, sizeof(cphs_data->Line1_desc));
#endif
	 	if (read_result EQ EFFS_OK)
	 		cphs_data->Line2_desc.result = SIMOP_READ_OK;
	 	else
			cphs_data->Line2_desc.result = SIMOP_READ_ERR;


}

void Cphs_get_info_num (UBYTE level, UBYTE startIndex)
{
  UBYTE res;

  TRACE_FUNCTION ("cphs_get_info_num()");

  /* check CPHS service table */
  if (cphs_data->cphsStatus EQ CPHS_NOT_PRESENT)
    return;

  if (level < 1       OR
      startIndex < 1    )
    return;

  /* check CPHS service table for customer service profile */
 /* res = Cphs_ssc(CPHS_CSP, cphs_data->cphsServTab);
  if ( res NEQ ALLOCATED_AND_ACTIVATED)
    return;*/

  /* check CPHS service table for information numbers */
/*  res = Cphs_ssc(CHPS_INFO_NUMBERS, cphs_data->cphsServTab);
  if ( res NEQ ALLOCATED_AND_ACTIVATED)
    return;*/

  /* Read customer service profile to check
     whether information numbers are supported.       */
  cphs_data->numList->count = 0;
  cphs_data->idxLevel      = level;
  cphs_data->startIdx      = startIndex;
  cphs_data->simStatus = SIMOP_READ_OK;
  if (!Cphs_read_sim_dat(SIM_CPHS_CSP, NOT_PRESENT_8BIT, CPHS_CSP_SIZE))
  {
    cphs_data->simStatus = SIMOP_UNKNOWN;
    TRACE_EVENT("FAiled in reading CSP for Info nums");
    return;
  }

  return;
}


/* checks the lock status of the given lock type. On successfull check   */
/* the status will be returned. If an error occured SIMLOCK_FAIL will    */
T_SIMLOCK_RET simlock_checkLock   ( T_SIMLOCK_TYPE type )
{

	return SIMLOCK_FAIL;
}