view src/aci2/mfw/CPHS_mod.c @ 508:61f878c011b0

pseudo-modem keepalive: poll interval reduced to 5 s on C1xx and 10 s for USB
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 25 Jun 2018 06:20:23 +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;
}