blob: 1ade6963f4caf26a04dedb1d4874ae4144b37aff [file] [log] [blame]
/*
* Copyright (C) 2015 NXP Semiconductors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <log/log.h>
#include <Ala.h>
#include <AlaLib.h>
#include <IChannel.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
pAla_Dwnld_Context_t gpAla_Dwnld_Context=NULL;
extern INT32 gTransceiveTimeout;
#ifdef JCOP3_WR
UINT8 Cmd_Buffer[64*1024];
static INT32 cmd_count = 0;
bool islastcmdLoad;
bool SendBack_cmds = false;
UINT8 *pBuffer;
#endif
BOOLEAN mIsInit;
UINT8 Select_Rsp[1024];
UINT8 Jsbl_RefKey[256];
UINT8 Jsbl_keylen;
#if(NXP_LDR_SVC_VER_2 == TRUE)
UINT8 StoreData[22];
#else
UINT8 StoreData[34];
#endif
int Select_Rsp_Len;
#if(NXP_LDR_SVC_VER_2 == TRUE)
UINT8 lsVersionArr[2];
UINT8 tag42Arr[17];
UINT8 tag45Arr[9];
UINT8 lsExecuteResp[4];
UINT8 AID_ARRAY[22];
INT32 resp_len = 0;
FILE *fAID_MEM = NULL;
FILE *fLS_STATUS = NULL;
UINT8 lsGetStatusArr[2];
tJBL_STATUS (*ls_GetStatus_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
{
ALA_OpenChannel,
ALA_SelectAla,
ALA_getAppletLsStatus,
ALA_CloseChannel,
NULL
};
#endif
tJBL_STATUS (*Applet_load_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
{
ALA_OpenChannel,
ALA_SelectAla,
ALA_StoreData,
ALA_loadapplet,
NULL
};
tJBL_STATUS (*Jsblcer_id_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
{
ALA_OpenChannel,
ALA_SelectAla,
ALA_CloseChannel,
NULL
};
/*******************************************************************************
**
** Function: initialize
**
** Description: Initialize all member variables.
** native: Native data.
**
** Returns: True if ok.
**
*******************************************************************************/
BOOLEAN initialize (IChannel_t* channel)
{
static const char fn [] = "Ala_initialize";
ALOGD ("%s: enter", fn);
gpAla_Dwnld_Context = (pAla_Dwnld_Context_t)malloc(sizeof(Ala_Dwnld_Context_t));
if(gpAla_Dwnld_Context != NULL)
{
memset((void *)gpAla_Dwnld_Context, 0, (UINT32)sizeof(Ala_Dwnld_Context_t));
}
else
{
ALOGD("%s: Memory allocation failed", fn);
return (FALSE);
}
gpAla_Dwnld_Context->mchannel = channel;
#ifdef JCOP3_WR
cmd_count = 0;
SendBack_cmds = false;
islastcmdLoad = false;
#endif
#if(NXP_LDR_SVC_VER_2 == TRUE)
fAID_MEM = fopen(AID_MEM_PATH,"r");
if(fAID_MEM == NULL)
{
ALOGD("%s: AID data file does not exists", fn);
memcpy(&ArrayOfAIDs[2][1],&SelectAla[0],sizeof(SelectAla));
ArrayOfAIDs[2][0] = sizeof(SelectAla);
}
else
{
/*Change is required aidLen = 0x00*/
UINT8 aidLen = 0x00;
INT32 wStatus = 0;
while(!(feof(fAID_MEM)))
{
/*the length is not incremented*/
wStatus = FSCANF_BYTE(fAID_MEM,"%2x",&ArrayOfAIDs[2][aidLen++]);
if(wStatus == 0)
{
ALOGE ("%s: exit: Error during read AID data", fn);
fclose(fAID_MEM);
return FALSE;
}
}
ArrayOfAIDs[2][0] = aidLen - 1;
fclose(fAID_MEM);
}
lsExecuteResp[0] = TAG_LSES_RESP;
lsExecuteResp[1] = TAG_LSES_RSPLEN;
lsExecuteResp[2] = LS_ABORT_SW1;
lsExecuteResp[3] = LS_ABORT_SW2;
#endif
#ifdef JCOP3_WR
pBuffer = Cmd_Buffer;
#endif
mIsInit = TRUE;
ALOGD ("%s: exit", fn);
return (TRUE);
}
/*******************************************************************************
**
** Function: finalize
**
** Description: Release all resources.
**
** Returns: None
**
*******************************************************************************/
void finalize ()
{
static const char fn [] = "Ala_finalize";
ALOGD ("%s: enter", fn);
mIsInit = FALSE;
if(gpAla_Dwnld_Context != NULL)
{
gpAla_Dwnld_Context->mchannel = NULL;
free(gpAla_Dwnld_Context);
gpAla_Dwnld_Context = NULL;
}
ALOGD ("%s: exit", fn);
}
/*******************************************************************************
**
** Function: Perform_ALA
**
** Description: Performs the ALA download sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS Perform_ALA(const char *name,const char *dest, const UINT8 *pdata,
UINT16 len, UINT8 *respSW)
#else
tJBL_STATUS Perform_ALA(const char *name, const UINT8 *pdata, UINT16 len)
#endif
{
static const char fn [] = "Perform_ALA";
static const char Ala_path[] = APPLET_PATH;
tJBL_STATUS status = STATUS_FAILED;
ALOGD ("%s: enter; sha-len=%d", fn, len);
if(mIsInit == false)
{
ALOGD ("%s: ALA lib is not initialized", fn);
status = STATUS_FAILED;
}
else if((pdata == NULL) ||
(len == 0x00))
{
ALOGD ("%s: Invalid SHA-data", fn);
}
else
{
StoreData[0] = STORE_DATA_TAG;
StoreData[1] = len;
memcpy(&StoreData[2], pdata, len);
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_update_seq_handler(Applet_load_seqhandler, name, dest);
if((status != STATUS_OK)&&(lsExecuteResp[2] == 0x90)&&
(lsExecuteResp[3] == 0x00))
{
lsExecuteResp[2] = LS_ABORT_SW1;
lsExecuteResp[3] = LS_ABORT_SW2;
}
memcpy(&respSW[0],&lsExecuteResp[0],4);
ALOGD ("%s: lsExecuteScript Response SW=%2x%2x",fn, lsExecuteResp[2],
lsExecuteResp[3]);
#else
status = ALA_update_seq_handler(Applet_load_seqhandler, name);
#endif
}
ALOGD("%s: exit; status=0x0%x", fn, status);
return status;
}
#if(NXP_LDR_SVC_VER_2 == FALSE)
/*******************************************************************************
**
** Function: GetJsbl_Certificate_ID
**
** Description: Performs the GetJsbl_Certificate_ID sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS GetJsbl_Certificate_Refkey(UINT8 *pKey, INT32 *pKeylen)
{
static const char fn [] = "GetJsbl_Certificate_ID";
tJBL_STATUS status = STATUS_FAILED;
ALOGD ("%s: enter", fn);
if(mIsInit == false)
{
ALOGD ("%s: ALA lib is not initialized", fn);
status = STATUS_FAILED;
}
else
{
status = JsblCerId_seq_handler(Jsblcer_id_seqhandler);
if(status == STATUS_SUCCESS)
{
if(Jsbl_keylen != 0x00)
{
*pKeylen = (INT32)Jsbl_keylen;
memcpy(pKey, Jsbl_RefKey, Jsbl_keylen);
Jsbl_keylen = 0;
}
}
}
ALOGD("%s: exit; status=0x0%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: JsblCerId_seq_handler
**
** Description: Performs get JSBL Certificate Identifier sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS JsblCerId_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
{
static const char fn[] = "JsblCerId_seq_handler";
UINT16 seq_counter = 0;
Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
tJBL_STATUS status = STATUS_FAILED;
ALOGD("%s: enter", fn);
while((seq_handler[seq_counter]) != NULL )
{
status = STATUS_FAILED;
status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
if(STATUS_SUCCESS != status)
{
ALOGE("%s: exiting; status=0x0%X", fn, status);
break;
}
seq_counter++;
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
#else
/*******************************************************************************
**
** Function: GetLs_Version
**
** Description: Performs the GetLs_Version sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS GetLs_Version(UINT8 *pVersion)
{
static const char fn [] = "GetLs_Version";
tJBL_STATUS status = STATUS_FAILED;
ALOGD ("%s: enter", fn);
if(mIsInit == false)
{
ALOGD ("%s: ALA lib is not initialized", fn);
status = STATUS_FAILED;
}
else
{
status = GetVer_seq_handler(Jsblcer_id_seqhandler);
if(status == STATUS_SUCCESS)
{
pVersion[0] = 2;
pVersion[1] = 0;
memcpy(&pVersion[2], lsVersionArr, sizeof(lsVersionArr));
ALOGD("%s: GetLsVersion is =0x0%x%x", fn, lsVersionArr[0],lsVersionArr[1]);
}
}
ALOGD("%s: exit; status=0x0%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: Get_LsAppletStatus
**
** Description: Performs the Get_LsAppletStatus sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS Get_LsAppletStatus(UINT8 *pVersion)
{
static const char fn [] = "GetLs_Version";
tJBL_STATUS status = STATUS_FAILED;
ALOGD ("%s: enter", fn);
if(mIsInit == false)
{
ALOGD ("%s: ALA lib is not initialized", fn);
status = STATUS_FAILED;
}
else
{
status = GetLsStatus_seq_handler(ls_GetStatus_seqhandler);
if(status == STATUS_SUCCESS)
{
pVersion[0] = lsGetStatusArr[0];
pVersion[1] = lsGetStatusArr[1];
ALOGD("%s: GetLsAppletStatus is =0x0%x%x", fn, lsGetStatusArr[0],lsGetStatusArr[1]);
}
}
ALOGD("%s: exit; status=0x0%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: GetVer_seq_handler
**
** Description: Performs GetVer_seq_handler sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS GetVer_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t*
pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
{
static const char fn[] = "GetVer_seq_handler";
UINT16 seq_counter = 0;
Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
tJBL_STATUS status = STATUS_FAILED;
ALOGD("%s: enter", fn);
while((seq_handler[seq_counter]) != NULL )
{
status = STATUS_FAILED;
status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
if(STATUS_SUCCESS != status)
{
ALOGE("%s: exiting; status=0x0%X", fn, status);
break;
}
seq_counter++;
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: GetLsStatus_seq_handler
**
** Description: Performs GetVer_seq_handler sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS GetLsStatus_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t*
pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
{
static const char fn[] = "ls_GetStatus_seqhandler";
UINT16 seq_counter = 0;
Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
tJBL_STATUS status = STATUS_FAILED;
ALOGD("%s: enter", fn);
while((seq_handler[seq_counter]) != NULL )
{
status = STATUS_FAILED;
status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
if(STATUS_SUCCESS != status)
{
ALOGE("%s: exiting; status=0x0%X", fn, status);
break;
}
seq_counter++;
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
#endif
/*******************************************************************************
**
** Function: ALA_update_seq_handler
**
** Description: Performs the ALA update sequence handler sequence
**
** Returns: Success if ok.
**
*******************************************************************************/
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])
(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t*
pInfo), const char *name, const char *dest)
#else
tJBL_STATUS ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo), const char *name)
#endif
{
static const char fn[] = "ALA_update_seq_handler";
static const char Ala_path[] = APPLET_PATH;
UINT16 seq_counter = 0;
Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->
Image_info;
Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context
->Transcv_Info;
tJBL_STATUS status = STATUS_FAILED;
ALOGD("%s: enter", fn);
#if(NXP_LDR_SVC_VER_2 == TRUE)
if(dest != NULL)
{
strcat(update_info.fls_RespPath, dest);
ALOGD("Loader Service response data path/destination: %s", dest);
update_info.bytes_wrote = 0xAA;
}
else
{
update_info.bytes_wrote = 0x55;
}
if((ALA_UpdateExeStatus(LS_DEFAULT_STATUS))!= TRUE)
{
return FALSE;
}
#endif
//memcpy(update_info.fls_path, (char*)Ala_path, sizeof(Ala_path));
strcat(update_info.fls_path, name);
ALOGD("Selected applet to install is: %s", update_info.fls_path);
while((seq_handler[seq_counter]) != NULL )
{
status = STATUS_FAILED;
status = (*(seq_handler[seq_counter]))(&update_info, status,
&trans_info);
if(STATUS_SUCCESS != status)
{
ALOGE("%s: exiting; status=0x0%X", fn, status);
break;
}
seq_counter++;
}
ALA_CloseChannel(&update_info, STATUS_FAILED, &trans_info);
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_OpenChannel
**
** Description: Creates the logical channel with ala
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_OpenChannel(Ala_ImageInfo_t *Os_info, tJBL_STATUS status,
Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn[] = "ALA_OpenChannel";
bool stat = false;
INT32 recvBufferActualSize = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
Os_info->channel_cnt = 0x00;
ALOGD("%s: enter", fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGD("%s: Invalid parameter", fn);
}
else
{
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sSendlength = (INT32)sizeof(OpenChannel);
pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
memcpy(pTranscv_Info->sSendData, OpenChannel, pTranscv_Info->sSendlength);
ALOGD("%s: Calling Secure Element Transceive", fn);
stat = mchannel->transceive (pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE &&
(recvBufferActualSize < 0x03))
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
if(recvBufferActualSize == 0x02)
memcpy(&lsExecuteResp[2],
&pTranscv_Info->sRecvData[recvBufferActualSize-2],2);
#endif
status = STATUS_FAILED;
ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
}
else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] != 0x00)))
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
memcpy(&lsExecuteResp[2],
&pTranscv_Info->sRecvData[recvBufferActualSize-2],2);
#endif
status = STATUS_FAILED;
ALOGE("%s: invalid response = 0x%X", fn, status);
}
else
{
UINT8 cnt = Os_info->channel_cnt;
Os_info->Channel_Info[cnt].channel_id = pTranscv_Info->sRecvData[recvBufferActualSize-3];
Os_info->Channel_Info[cnt].isOpend = true;
Os_info->channel_cnt++;
status = STATUS_OK;
}
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_SelectAla
**
** Description: Creates the logical channel with ala
** Channel_id will be used for any communication with Ala
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_SelectAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn[] = "ALA_SelectAla";
bool stat = false;
INT32 recvBufferActualSize = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
#if(NXP_LDR_SVC_VER_2 == TRUE)
UINT8 selectCnt = 3;
#endif
ALOGD("%s: enter", fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGD("%s: Invalid parameter", fn);
}
else
{
pTranscv_Info->sSendData[0] = Os_info->Channel_Info[0].channel_id;
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sSendlength = (INT32)sizeof(SelectAla);
pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
#if(NXP_LDR_SVC_VER_2 == TRUE)
while((selectCnt--) > 0)
{
memcpy(&(pTranscv_Info->sSendData[1]), &ArrayOfAIDs[selectCnt][2],
((ArrayOfAIDs[selectCnt][0])-1));
pTranscv_Info->sSendlength = (INT32)ArrayOfAIDs[selectCnt][0];
/*If NFC/SPI Deinitialize requested*/
#else
memcpy(&(pTranscv_Info->sSendData[1]), &SelectAla[1], sizeof(SelectAla)-1);
#endif
ALOGD("%s: Calling Secure Element Transceive with Loader service AID", fn);
stat = mchannel->transceive (pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE &&
(recvBufferActualSize == 0x00))
{
status = STATUS_FAILED;
ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
#if(NXP_LDR_SVC_VER_2 == TRUE)
break;
#endif
}
else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
{
status = Process_SelectRsp(pTranscv_Info->sRecvData, (recvBufferActualSize-2));
if(status != STATUS_OK)
{
ALOGE("%s: Select Ala Rsp doesnt have a valid key; status = 0x%X", fn, status);
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*If AID is found which is successfully selected break while loop*/
if(status == STATUS_OK)
{
UINT8 totalLen = ArrayOfAIDs[selectCnt][0];
UINT8 cnt = 0;
INT32 wStatus= 0;
status = STATUS_FAILED;
fAID_MEM = fopen(AID_MEM_PATH,"w+");
if(fAID_MEM == NULL)
{
ALOGE("Error opening AID data file for writing: %s",
strerror(errno));
return status;
}
while(cnt <= totalLen)
{
wStatus = fprintf(fAID_MEM, "%02x",
ArrayOfAIDs[selectCnt][cnt++]);
if(wStatus != 2)
{
ALOGE("%s: Error writing AID data to AID_MEM file: %s",
fn, strerror(errno));
break;
}
}
if(wStatus == 2)
status = STATUS_OK;
fclose(fAID_MEM);
break;
}
#endif
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90)))
{
/*Copy the response SW in failure case*/
memcpy(&lsExecuteResp[2], &(pTranscv_Info->
sRecvData[recvBufferActualSize-2]),2);
}
#endif
else
{
status = STATUS_FAILED;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
}
#endif
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_StoreData
**
** Description: It is used to provide the ALA with an Unique
** Identifier of the Application that has triggered the ALA script.
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_StoreData(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn[] = "ALA_StoreData";
bool stat = false;
INT32 recvBufferActualSize = 0;
INT32 xx=0, len = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
ALOGD("%s: enter", fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGD("%s: Invalid parameter", fn);
}
else
{
len = StoreData[1] + 2; //+2 offset is for tag value and length byte
pTranscv_Info->sSendData[xx++] = STORE_DATA_CLA | (Os_info->Channel_Info[0].channel_id);
pTranscv_Info->sSendData[xx++] = STORE_DATA_INS;
pTranscv_Info->sSendData[xx++] = 0x00; //P1
pTranscv_Info->sSendData[xx++] = 0x00; //P2
pTranscv_Info->sSendData[xx++] = len;
memcpy(&(pTranscv_Info->sSendData[xx]), StoreData, len);
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sSendlength = (INT32)(xx + sizeof(StoreData));
pTranscv_Info->sRecvlength = 1024;
ALOGD("%s: Calling Secure Element Transceive", fn);
stat = mchannel->transceive (pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if((stat != TRUE) &&
(recvBufferActualSize == 0x00))
{
status = STATUS_FAILED;
ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
}
else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
{
ALOGE("STORE CMD is successful");
status = STATUS_SUCCESS;
}
else
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*Copy the response SW in failure case*/
memcpy(&lsExecuteResp[2], &(pTranscv_Info->sRecvData
[recvBufferActualSize-2]),2);
#endif
status = STATUS_FAILED;
}
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_loadapplet
**
** Description: Reads the script from the file and sent to Ala
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_loadapplet(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn [] = "ALA_loadapplet";
BOOLEAN stat = FALSE;
int wResult, size =0;
INT32 wIndex,wCount=0;
INT32 wLen = 0;
INT32 recvBufferActualSize = 0;
UINT8 temp_buf[1024];
UINT8 len_byte=0, offset =0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
Os_info->bytes_read = 0;
#if(NXP_LDR_SVC_VER_2 == TRUE)
BOOLEAN reachEOFCheck = FALSE;
tJBL_STATUS tag40_found = STATUS_FAILED;
if(Os_info->bytes_wrote == 0xAA)
{
Os_info->fResp = fopen(Os_info->fls_RespPath, "a+");
if(Os_info->fResp == NULL)
{
ALOGE("Error opening response recording file <%s> for reading: %s",
Os_info->fls_path, strerror(errno));
return status;
}
ALOGD("%s: Response OUT FILE path is successfully created", fn);
}
else
{
ALOGD("%s: Response Out file is optional as per input", fn);
}
#endif
ALOGD("%s: enter", fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGE("%s: invalid parameter", fn);
return status;
}
Os_info->fp = fopen(Os_info->fls_path, "r");
if (Os_info->fp == NULL) {
ALOGE("Error opening OS image file <%s> for reading: %s",
Os_info->fls_path, strerror(errno));
return status;
}
wResult = fseek(Os_info->fp, 0L, SEEK_END);
if (wResult) {
ALOGE("Error seeking end OS image file %s", strerror(errno));
goto exit;
}
Os_info->fls_size = ftell(Os_info->fp);
ALOGE("fls_size=%d", Os_info->fls_size);
if (Os_info->fls_size < 0) {
ALOGE("Error ftelling file %s", strerror(errno));
goto exit;
}
wResult = fseek(Os_info->fp, 0L, SEEK_SET);
if (wResult) {
ALOGE("Error seeking start image file %s", strerror(errno));
goto exit;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info,
NULL, STATUS_FAILED, 0);
#else
status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info);
#endif
if(status != STATUS_OK)
{
goto exit;
}
while(!feof(Os_info->fp) &&
(Os_info->bytes_read < Os_info->fls_size))
{
len_byte = 0x00;
offset = 0;
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*Check if the certificate/ is verified or not*/
if(status != STATUS_OK)
{
goto exit;
}
#endif
memset(temp_buf, 0, sizeof(temp_buf));
ALOGE("%s; Start of line processing", fn);
status = ALA_ReadScript(Os_info, temp_buf);
if(status != STATUS_OK)
{
goto exit;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
else if(status == STATUS_OK)
{
/*Reset the flag in case further commands exists*/
reachEOFCheck = FALSE;
}
#endif
if(temp_buf[offset] == TAG_ALA_CMD_ID)
{
/*
* start sending the packet to Ala
* */
offset = offset+1;
len_byte = Numof_lengthbytes(&temp_buf[offset], &wLen);
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*If the len data not present or
* len is less than or equal to 32*/
if((len_byte == 0)||(wLen <= 32))
#else
if((len_byte == 0))
#endif
{
ALOGE("Invalid length zero");
#if(NXP_LDR_SVC_VER_2 == TRUE)
goto exit;
#else
return status;
#endif
}
else
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
tag40_found = STATUS_OK;
#endif
offset = offset+len_byte;
pTranscv_Info->sSendlength = wLen;
memcpy(pTranscv_Info->sSendData, &temp_buf[offset], wLen);
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
#else
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
#endif
if(status != STATUS_OK)
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*When the switching of LS 6320 case*/
if(status == STATUS_FILE_NOT_FOUND)
{
/*When 6320 occurs close the existing channels*/
ALA_CloseChannel(Os_info,status,pTranscv_Info);
status = STATUS_FAILED;
status = ALA_OpenChannel(Os_info,status,pTranscv_Info);
if(status == STATUS_OK)
{
ALOGD("SUCCESS:Post Switching LS open channel");
status = STATUS_FAILED;
status = ALA_SelectAla(Os_info,status,pTranscv_Info);
if(status == STATUS_OK)
{
ALOGD("SUCCESS:Post Switching LS select");
status = STATUS_FAILED;
status = ALA_StoreData(Os_info,status,pTranscv_Info);
if(status == STATUS_OK)
{
/*Enable certificate and signature verification*/
tag40_found = STATUS_OK;
lsExecuteResp[2] = 0x90;
lsExecuteResp[3] = 0x00;
reachEOFCheck = TRUE;
continue;
}
ALOGE("Post Switching LS store data failure");
}
ALOGE("Post Switching LS select failure");
}
ALOGE("Post Switching LS failure");
}
ALOGE("Sending packet to ala failed");
goto exit;
#else
return status;
#endif
}
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
else if((temp_buf[offset] == (0x7F))&&(temp_buf[offset+1] == (0x21)))
{
ALOGD("TAGID: Encountered again certificate tag 7F21");
if(tag40_found == STATUS_OK)
{
ALOGD("2nd Script processing starts with reselect");
status = STATUS_FAILED;
status = ALA_SelectAla(Os_info,status,pTranscv_Info);
if(status == STATUS_OK)
{
ALOGD("2nd Script select success next store data command");
status = STATUS_FAILED;
status = ALA_StoreData(Os_info,status,pTranscv_Info);
if(status == STATUS_OK)
{
ALOGD("2nd Script store data success next certificate verification");
offset = offset+2;
len_byte = Numof_lengthbytes(&temp_buf[offset], &wLen);
status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info,
temp_buf, STATUS_OK, wLen+len_byte+2);
}
}
/*If the certificate and signature is verified*/
if(status == STATUS_OK)
{
/*If the certificate is verified for 6320 then new
* script starts*/
tag40_found = STATUS_FAILED;
}
/*If the certificate or signature verification failed*/
else{
goto exit;
}
}
/*Already certificate&Sginature verified previously skip 7f21& tag 60*/
else
{
memset(temp_buf, 0, sizeof(temp_buf));
status = ALA_ReadScript(Os_info, temp_buf);
if(status != STATUS_OK)
{
ALOGE("%s; Next Tag has to TAG 60 not found", fn);
goto exit;
}
if(temp_buf[offset] == TAG_JSBL_HDR_ID)
continue;
else
goto exit;
}
}
#endif
else
{
/*
* Invalid packet received in between stop processing packet
* return failed status
* */
status = STATUS_FAILED;
break;
}
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
if(Os_info->bytes_wrote == 0xAA)
{
fclose(Os_info->fResp);
}
ALA_UpdateExeStatus(LS_SUCCESS_STATUS);
#endif
wResult = fclose(Os_info->fp);
ALOGE("%s exit;End of Load Applet; status=0x%x",fn, status);
return status;
exit:
wResult = fclose(Os_info->fp);
#if(NXP_LDR_SVC_VER_2 == TRUE)
if(Os_info->bytes_wrote == 0xAA)
{
fclose(Os_info->fResp);
}
/*Script ends with SW 6320 and reached END OF FILE*/
if(reachEOFCheck == TRUE)
{
status = STATUS_OK;
ALA_UpdateExeStatus(LS_SUCCESS_STATUS);
}
#endif
ALOGE("%s close fp and exit; status= 0x%X", fn,status);
return status;
}
/*******************************************************************************
**
** Function: ALA_ProcessResp
**
** Description: Process the response packet received from Ala
**
** Returns: Success if ok.
**
*******************************************************************************/
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status,
Ala_TranscieveInfo_t *pTranscv_Info, UINT8* temp_buf, tJBL_STATUS flag,
INT32 wNewLen)
#else
tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
#endif
{
static const char fn[] = "ALA_Check_KeyIdentifier";
#if(NXP_LDR_SVC_VER_2 == TRUE)
UINT16 offset = 0x00, len_byte=0;
#else
UINT8 offset = 0x00, len_byte=0;
#endif
tJBL_STATUS key_found = STATUS_FAILED;
status = STATUS_FAILED;
UINT8 read_buf[1024];
bool stat = false;
INT32 wLen, recvBufferActualSize=0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
#if(NXP_LDR_SVC_VER_2 == TRUE)
UINT8 certf_found = STATUS_FAILED;
UINT8 sign_found = STATUS_FAILED;
#endif
ALOGD("%s: enter", fn);
#if(NXP_LDR_SVC_VER_2 == TRUE)
while(!feof(Os_info->fp) &&
(Os_info->bytes_read < Os_info->fls_size))
{
offset = 0x00;
wLen = 0;
if(flag == STATUS_OK)
{
/*If the 7F21 TAG is already read: After TAG 40*/
memcpy(read_buf, temp_buf, wNewLen);
status = STATUS_OK;
flag = STATUS_FAILED;
}
else
{
/*If the 7F21 TAG is not read: Before TAG 40*/
status = ALA_ReadScript(Os_info, read_buf);
}
if(status != STATUS_OK)
return status;
if(STATUS_OK == Check_Complete_7F21_Tag(Os_info,pTranscv_Info,
read_buf, &offset))
{
ALOGD("%s: Certificate is verified", fn);
certf_found = STATUS_OK;
break;
}
/*The Loader Service Client ignores all subsequent commands starting by tag
* �7F21� or tag �60� until the first command starting by tag �40� is found*/
else if(((read_buf[offset] == TAG_ALA_CMD_ID)&&(certf_found != STATUS_OK)))
{
ALOGE("%s: NOT FOUND Root entity identifier's certificate", fn);
status = STATUS_FAILED;
return status;
}
}
#endif
#if(NXP_LDR_SVC_VER_2 == TRUE)
memset(read_buf, 0, sizeof(read_buf));
if(certf_found == STATUS_OK)
{
#else
while(!feof(Os_info->fp))
{
#endif
offset = 0x00;
wLen = 0;
status = ALA_ReadScript(Os_info, read_buf);
if(status != STATUS_OK)
return status;
#if(NXP_LDR_SVC_VER_2 == TRUE)
else
status = STATUS_FAILED;
if((read_buf[offset] == TAG_JSBL_HDR_ID)&&
(certf_found != STATUS_FAILED)&&(sign_found != STATUS_OK))
#else
if(read_buf[offset] == TAG_JSBL_HDR_ID &&
key_found != STATUS_OK)
#endif
{
//TODO check the SElect cmd response and return status accordingly
ALOGD("TAGID: TAG_JSBL_HDR_ID");
offset = offset+1;
len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
offset = offset + len_byte;
#if(NXP_LDR_SVC_VER_2 == FALSE)
if(read_buf[offset] == TAG_JSBL_KEY_ID)
{
ALOGE("TAGID: TAG_JSBL_KEY_ID");
offset = offset+1;
wLen = read_buf[offset];
offset = offset+1;
key_found = memcmp(&read_buf[offset], Select_Rsp,
Select_Rsp_Len);
if(key_found == STATUS_OK)
{
ALOGE("Key is matched");
offset = offset + wLen;
#endif
if(read_buf[offset] == TAG_SIGNATURE_ID)
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
offset = offset+1;
len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
offset = offset + len_byte;
#endif
ALOGE("TAGID: TAG_SIGNATURE_ID");
#if(NXP_LDR_SVC_VER_2 == TRUE)
pTranscv_Info->sSendlength = wLen+5;
pTranscv_Info->sSendData[0] = 0x00;
pTranscv_Info->sSendData[1] = 0xA0;
pTranscv_Info->sSendData[2] = 0x00;
pTranscv_Info->sSendData[3] = 0x00;
pTranscv_Info->sSendData[4] = wLen;
memcpy(&(pTranscv_Info->sSendData[5]),
&read_buf[offset], wLen);
#else
offset = offset+1;
wLen = 0;
len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
if(len_byte == 0)
{
ALOGE("Invalid length zero");
return STATUS_FAILED;
}
else
{
offset = offset+len_byte;
pTranscv_Info->sSendlength = wLen;
memcpy(pTranscv_Info->sSendData, &read_buf[offset],
wLen);
}
#endif
ALOGE("%s: start transceive for length %ld", fn,
pTranscv_Info->sSendlength);
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Sign);
#else
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
#endif
if(status != STATUS_OK)
{
return status;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
else
{
sign_found = STATUS_OK;
}
#endif
}
#if(NXP_LDR_SVC_VER_2 == FALSE)
}
else
{
/*
* Discard the packet and goto next line
* */
}
}
else
{
ALOGE("Invalid Tag ID");
status = STATUS_FAILED;
break;
}
#endif
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
else if(read_buf[offset] != TAG_JSBL_HDR_ID )
{
status = STATUS_FAILED;
}
#else
else if(read_buf[offset] == TAG_ALA_CMD_ID &&
key_found == STATUS_OK)
{
/*Key match is success and start sending the packet to Ala
* return status ok
* */
ALOGE("TAGID: TAG_ALA_CMD_ID");
offset = offset+1;
wLen = 0;
len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
if(len_byte == 0)
{
ALOGE("Invalid length zero");
return STATUS_FAILED;
}
else
{
offset = offset+len_byte;
pTranscv_Info->sSendlength = wLen;
memcpy(pTranscv_Info->sSendData, &read_buf[offset], wLen);
}
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
break;
}
else if(read_buf[offset] == TAG_JSBL_HDR_ID &&
key_found == STATUS_OK)
{
/*Key match is success
* Discard the packets untill we found header T=0x40
* */
}
else
{
/*Invalid header*/
status = STATUS_FAILED;
break;
}
#endif
#if(NXP_LDR_SVC_VER_2 == FALSE)
}
#else
}
else
{
ALOGE("%s : Exit certificate verification failed", fn);
}
#endif
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_ReadScript
**
** Description: Reads the current line if the script
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_ReadScript(Ala_ImageInfo_t *Os_info, UINT8 *read_buf)
{
static const char fn[]="ALA_ReadScript";
INT32 wCount, wLen, wIndex = 0;
UINT8 len_byte = 0;
int wResult = 0;
tJBL_STATUS status = STATUS_FAILED;
INT32 lenOff = 1;
ALOGD("%s: enter", fn);
for(wCount =0; (wCount < 2 && !feof(Os_info->fp)); wCount++, wIndex++)
{
wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
}
if(wResult == 0)
return STATUS_FAILED;
Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
#if(NXP_LDR_SVC_VER_2 == TRUE)
if((read_buf[0]==0x7f) && (read_buf[1]==0x21))
{
for(wCount =0; (wCount < 1 && !feof(Os_info->fp)); wCount++, wIndex++)
{
wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
}
if(wResult == 0)
{
ALOGE("%s: Exit Read Script failed in 7F21 ", fn);
return STATUS_FAILED;
}
/*Read_Script from wCount*2 to wCount*1 */
Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
lenOff = 2;
}
else if((read_buf[0] == 0x40)||(read_buf[0] == 0x60))
{
lenOff = 1;
}
/*If TAG is neither 7F21 nor 60 nor 40 then ABORT execution*/
else
{
ALOGE("Invalid TAG 0x%X found in the script", read_buf[0]);
return STATUS_FAILED;
}
#endif
if(read_buf[lenOff] == 0x00)
{
ALOGE("Invalid length zero");
len_byte = 0x00;
return STATUS_FAILED;
}
else if((read_buf[lenOff] & 0x80) == 0x80)
{
len_byte = read_buf[lenOff] & 0x0F;
len_byte = len_byte +1; //1 byte added for byte 0x81
ALOGD("%s: Length byte Read from 0x80 is 0x%x ", fn, len_byte);
if(len_byte == 0x02)
{
for(wCount =0; (wCount < 1 && !feof(Os_info->fp)); wCount++, wIndex++)
{
wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
}
if(wResult == 0)
{
ALOGE("%s: Exit Read Script failed in length 0x02 ", fn);
return STATUS_FAILED;
}
wLen = read_buf[lenOff+1];
Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
ALOGD("%s: Length of Read Script in len_byte= 0x02 is 0x%lx ", fn, wLen);
}
else if(len_byte == 0x03)
{
for(wCount =0; (wCount < 2 && !feof(Os_info->fp)); wCount++, wIndex++)
{
wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
}
if(wResult == 0)
{
ALOGE("%s: Exit Read Script failed in length 0x03 ", fn);
return STATUS_FAILED;
}
Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
wLen = read_buf[lenOff+1]; //Length of the packet send to ALA
wLen = ((wLen << 8) | (read_buf[lenOff+2]));
ALOGD("%s: Length of Read Script in len_byte= 0x03 is 0x%lx ", fn, wLen);
}
else
{
/*Need to provide the support if length is more than 2 bytes*/
ALOGE("Length recived is greater than 3");
return STATUS_FAILED;
}
}
else
{
len_byte = 0x01;
wLen = read_buf[lenOff];
ALOGE("%s: Length of Read Script in len_byte= 0x01 is 0x%lx ", fn, wLen);
}
for(wCount =0; (wCount < wLen && !feof(Os_info->fp)); wCount++, wIndex++)
{
wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
}
if(wResult == 0)
{
ALOGE("%s: Exit Read Script failed in fscanf function ", fn);
return status;
}
else
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
Os_info->bytes_read = Os_info->bytes_read + (wCount*2)+1; //not sure why 2 added
#else
Os_info->bytes_read = Os_info->bytes_read + (wCount*2)+2; //not sure why 2 added
#endif
status = STATUS_OK;
}
ALOGD("%s: exit: status=0x%x; Num of bytes read=%d and index=%ld",
fn, status, Os_info->bytes_read,wIndex);
return status;
}
/*******************************************************************************
**
** Function: ALA_SendtoEse
**
** Description: It is used to send the packet to p61
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_SendtoEse(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn [] = "ALA_SendtoEse";
bool stat =false, chanl_open_cmd = false;
UINT8 xx=0;
status = STATUS_FAILED;
INT32 recvBufferActualSize=0, recv_len = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
ALOGD("%s: enter", fn);
#ifdef JCOP3_WR
/*
* Bufferize_load_cmds function is implemented in JCOP
* */
status = Bufferize_load_cmds(Os_info, status, pTranscv_Info);
if(status != STATUS_FAILED)
{
#endif
if(pTranscv_Info->sSendData[1] == 0x70)
{
if(pTranscv_Info->sSendData[2] == 0x00)
{
ALOGE("Channel open");
chanl_open_cmd = true;
}
else
{
ALOGE("Channel close");
for(UINT8 cnt=0; cnt < Os_info->channel_cnt; cnt++)
{
if(Os_info->Channel_Info[cnt].channel_id == pTranscv_Info->sSendData[3])
{
ALOGE("Closed channel id = 0x0%x", Os_info->Channel_Info[cnt].channel_id);
Os_info->Channel_Info[cnt].isOpend = false;
}
}
}
}
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sRecvlength = 1024;
stat = mchannel->transceive(pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE)
{
ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
}
else
{
if(chanl_open_cmd == true)
{
if((recvBufferActualSize == 0x03) &&
((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
{
ALOGE("open channel success");
UINT8 cnt = Os_info->channel_cnt;
Os_info->Channel_Info[cnt].channel_id = pTranscv_Info->sRecvData[recvBufferActualSize-3];
Os_info->Channel_Info[cnt].isOpend = true;
Os_info->channel_cnt++;
}
else
{
ALOGE("channel open faield");
}
}
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
}
#ifdef JCOP3_WR
}
else if(SendBack_cmds == false)
{
/*
* Workaround for issue in JCOP
* Send the fake response back
* */
recvBufferActualSize = 0x03;
pTranscv_Info->sRecvData[0] = 0x00;
pTranscv_Info->sRecvData[1] = 0x90;
pTranscv_Info->sRecvData[2] = 0x00;
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
}
else
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
if(islastcmdLoad == true)
{
status = Send_Backall_Loadcmds(Os_info, status, pTranscv_Info);
SendBack_cmds = false;
}else
{
memset(Cmd_Buffer, 0, sizeof(Cmd_Buffer));
SendBack_cmds = false;
status = STATUS_FAILED;
}
#else
status = Send_Backall_Loadcmds(Os_info, status, pTranscv_Info);
SendBack_cmds = false;
#endif
}
#endif
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_SendtoAla
**
** Description: It is used to forward the packet to Ala
**
** Returns: Success if ok.
**
*******************************************************************************/
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info, Ls_TagType tType)
#else
tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
#endif
{
static const char fn [] = "ALA_SendtoAla";
bool stat =false;
status = STATUS_FAILED;
INT32 recvBufferActualSize = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
ALOGD("%s: enter", fn);
#if(NXP_LDR_SVC_VER_2 == TRUE)
pTranscv_Info->sSendData[0] = (0x80 | Os_info->Channel_Info[0].channel_id);
#else
pTranscv_Info->sSendData[0] = (pTranscv_Info->sSendData[0] | Os_info->Channel_Info[0].channel_id);
#endif
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sRecvlength = 1024;
stat = mchannel->transceive(pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE)
{
ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
}
else
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_ProcessResp(Os_info, recvBufferActualSize, pTranscv_Info, tType);
#else
status = ALA_ProcessResp(Os_info, recvBufferActualSize, pTranscv_Info);
#endif
}
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_CloseChannel
**
** Description: Closes the previously opened logical channel
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS ALA_CloseChannel(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn [] = "ALA_CloseChannel";
status = STATUS_FAILED;
bool stat = false;
UINT8 xx =0;
INT32 recvBufferActualSize = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
UINT8 cnt = 0;
ALOGD("%s: enter",fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGE("Invalid parameter");
}
else
{
for(cnt =0; (cnt < Os_info->channel_cnt); cnt++)
{
if(Os_info->Channel_Info[cnt].isOpend == false)
continue;
xx = 0;
pTranscv_Info->sSendData[xx++] = Os_info->Channel_Info[cnt].channel_id;
pTranscv_Info->sSendData[xx++] = 0x70;
pTranscv_Info->sSendData[xx++] = 0x80;
pTranscv_Info->sSendData[xx++] = Os_info->Channel_Info[cnt].channel_id;
pTranscv_Info->sSendData[xx++] = 0x00;
pTranscv_Info->sSendlength = xx;
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sRecvlength = 1024;
stat = mchannel->transceive(pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE &&
recvBufferActualSize < 2)
{
ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
}
else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
{
ALOGE("Close channel id = 0x0%x is success", Os_info->Channel_Info[cnt].channel_id);
status = STATUS_OK;
}
else
{
ALOGE("Close channel id = 0x0%x is failed", Os_info->Channel_Info[cnt].channel_id);
}
}
}
ALOGD("%s: exit; status=0x0%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_ProcessResp
**
** Description: Process the response packet received from Ala
**
** Returns: Success if ok.
**
*******************************************************************************/
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, INT32 recvlen, Ala_TranscieveInfo_t *trans_info, Ls_TagType tType)
#else
tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, INT32 recvlen, Ala_TranscieveInfo_t *trans_info)
#endif
{
static const char fn [] = "ALA_ProcessResp";
tJBL_STATUS status = STATUS_FAILED;
static INT32 temp_len = 0;
UINT8* RecvData = trans_info->sRecvData;
UINT8 xx =0;
char sw[2];
ALOGD("%s: enter", fn);
if(RecvData == NULL &&
recvlen == 0x00)
{
ALOGE("%s: Invalid parameter: status=0x%x", fn, status);
return status;
}
else if(recvlen >= 2)
{
sw[0] = RecvData[recvlen-2];
sw[1] = RecvData[recvlen-1];
}
else
{
ALOGE("%s: Invalid response; status=0x%x", fn, status);
return status;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*Update the Global variable for storing response length*/
resp_len = recvlen;
if((sw[0] != 0x63))
{
lsExecuteResp[2] = sw[0];
lsExecuteResp[3] = sw[1];
ALOGD("%s: Process Response SW; status = 0x%x", fn, sw[0]);
ALOGD("%s: Process Response SW; status = 0x%x", fn, sw[1]);
}
#endif
if((recvlen == 0x02) &&
(sw[0] == 0x90) &&
(sw[1] == 0x00))
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS wStatus = STATUS_FAILED;
ALOGE("%s: Before Write Response", fn);
wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
if(wStatus != STATUS_FAILED)
#endif
status = STATUS_OK;
}
else if((recvlen > 0x02) &&
(sw[0] == 0x90) &&
(sw[1] == 0x00))
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
tJBL_STATUS wStatus = STATUS_FAILED;
ALOGE("%s: Before Write Response", fn);
wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
if(wStatus != STATUS_FAILED)
status = STATUS_OK;
#else
if(temp_len != 0)
{
memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
trans_info->sSendlength = temp_len + (recvlen-2);
memcpy(trans_info->sSendData, trans_info->sTemp_recvbuf, trans_info->sSendlength);
temp_len = 0;
}
else
{
memcpy(trans_info->sSendData, RecvData, (recvlen-2));
trans_info->sSendlength = recvlen-2;
}
status = ALA_SendtoEse(image_info, status, trans_info);
#endif
}
#if(NXP_LDR_SVC_VER_2 == FALSE)
else if ((recvlen > 0x02) &&
(sw[0] == 0x61))
{
memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
temp_len = temp_len + recvlen-2;
trans_info->sSendData[xx++] = image_info->Channel_Info[0].channel_id;
trans_info->sSendData[xx++] = 0xC0;
trans_info->sSendData[xx++] = 0x00;
trans_info->sSendData[xx++] = 0x00;
trans_info->sSendData[xx++] = sw[1];
trans_info->sSendlength = xx;
status = ALA_SendtoAla(image_info, status, trans_info);
}
#endif
#if(NXP_LDR_SVC_VER_2 == TRUE)
else if ((recvlen > 0x02) &&
(sw[0] == 0x63) &&
(sw[1] == 0x10))
{
if(temp_len != 0)
{
memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
trans_info->sSendlength = temp_len + (recvlen-2);
memcpy(trans_info->sSendData, trans_info->sTemp_recvbuf,
trans_info->sSendlength);
temp_len = 0;
}
else
{
memcpy(trans_info->sSendData, RecvData, (recvlen-2));
trans_info->sSendlength = recvlen-2;
}
status = ALA_SendtoEse(image_info, status, trans_info);
}
else if ((recvlen > 0x02) &&
(sw[0] == 0x63) &&
(sw[1] == 0x20))
{
UINT8 respLen = 0;
INT32 wStatus = 0;
AID_ARRAY[0] = recvlen+3;
AID_ARRAY[1] = 00;
AID_ARRAY[2] = 0xA4;
AID_ARRAY[3] = 0x04;
AID_ARRAY[4] = 0x00;
AID_ARRAY[5] = recvlen-2;
memcpy(&AID_ARRAY[6], &RecvData[0],recvlen-2);
memcpy(&ArrayOfAIDs[2][0], &AID_ARRAY[0], recvlen+4);
fAID_MEM = fopen(AID_MEM_PATH,"w");
if (fAID_MEM == NULL) {
ALOGE("Error opening AID data for writing: %s",strerror(errno));
return status;
}
/*Updating the AID_MEM with new value into AID file*/
while(respLen <= (recvlen+4))
{
wStatus = fprintf(fAID_MEM, "%2x", AID_ARRAY[respLen++]);
if(wStatus != 2)
{
ALOGE("%s: Invalid Response during fprintf; status=0x%x",
fn, status);
fclose(fAID_MEM);
break;
}
}
if(wStatus == 2)
{
status = STATUS_FILE_NOT_FOUND;
}
else
{
status = STATUS_FAILED;
}
}
else if((recvlen >= 0x02) &&(
(sw[0] != 0x90) &&
(sw[0] != 0x63)&&(sw[0] != 0x61)))
{
tJBL_STATUS wStatus = STATUS_FAILED;
wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
//if(wStatus != STATUS_FAILED)
//status = STATUS_OK;
}
#endif
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: ALA_SendtoEse
**
** Description: It is used to process the received response packet from p61
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS Process_EseResponse(Ala_TranscieveInfo_t *pTranscv_Info, INT32 recv_len, Ala_ImageInfo_t *Os_info)
{
static const char fn[] = "Process_EseResponse";
tJBL_STATUS status = STATUS_OK;
UINT8 xx = 0;
ALOGD("%s: enter", fn);
pTranscv_Info->sSendData[xx++] = (CLA_BYTE | Os_info->Channel_Info[0].channel_id);
#if(NXP_LDR_SVC_VER_2 == TRUE)
pTranscv_Info->sSendData[xx++] = 0xA2;
#else
pTranscv_Info->sSendData[xx++] = 0xA0;
#endif
if(recv_len <= 0xFF)
{
#if(NXP_LDR_SVC_VER_2 == TRUE)
pTranscv_Info->sSendData[xx++] = 0x80;
#else
pTranscv_Info->sSendData[xx++] = ONLY_BLOCK;
#endif
pTranscv_Info->sSendData[xx++] = 0x00;
pTranscv_Info->sSendData[xx++] = (UINT8)recv_len;
memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,recv_len);
pTranscv_Info->sSendlength = xx+ recv_len;
#if(NXP_LDR_SVC_VER_2)
status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
#else
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
#endif
}
else
{
while(recv_len > MAX_SIZE)
{
xx = PARAM_P1_OFFSET;
#if(NXP_LDR_SVC_VER_2 == TRUE)
pTranscv_Info->sSendData[xx++] = 0x00;
#else
pTranscv_Info->sSendData[xx++] = FIRST_BLOCK;
#endif
pTranscv_Info->sSendData[xx++] = 0x00;
pTranscv_Info->sSendData[xx++] = MAX_SIZE;
recv_len = recv_len - MAX_SIZE;
memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,MAX_SIZE);
pTranscv_Info->sSendlength = xx+ MAX_SIZE;
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*Need not store Process eSE response's response in the out file so
* LS_Comm = 0*/
status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
#else
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
#endif
if(status != STATUS_OK)
{
ALOGE("Sending packet to Ala failed: status=0x%x", status);
return status;
}
}
xx = PARAM_P1_OFFSET;
pTranscv_Info->sSendData[xx++] = LAST_BLOCK;
pTranscv_Info->sSendData[xx++] = 0x01;
pTranscv_Info->sSendData[xx++] = recv_len;
memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,recv_len);
pTranscv_Info->sSendlength = xx+ recv_len;
#if(NXP_LDR_SVC_VER_2 == TRUE)
status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
#else
status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
#endif
}
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
/*******************************************************************************
**
** Function: Process_SelectRsp
**
** Description: It is used to process the received response for SELECT ALA cmd
**
** Returns: Success if ok.
**
*******************************************************************************/
tJBL_STATUS Process_SelectRsp(UINT8* Recv_data, INT32 Recv_len)
{
static const char fn[]="Process_SelectRsp";
tJBL_STATUS status = STATUS_FAILED;
int i = 0, len=0;
ALOGE("%s: enter", fn);
if(Recv_data[i] == TAG_SELECT_ID)
{
ALOGD("TAG: TAG_SELECT_ID");
i = i +1;
len = Recv_data[i];
i = i+1;
if(Recv_data[i] == TAG_ALA_ID)
{
ALOGD("TAG: TAG_ALA_ID");
i = i+1;
len = Recv_data[i];
i = i + 1 + len; //points to next tag name A5
#if(NXP_LDR_SVC_VER_2 == TRUE)
//points to TAG 9F08 for LS application version
if((Recv_data[i] == TAG_LS_VER1)&&(Recv_data[i+1] == TAG_LS_VER2))
{
UINT8 lsaVersionLen = 0;
ALOGD("TAG: TAG_LS_APPLICATION_VER");
i = i+2;
lsaVersionLen = Recv_data[i];
//points to TAG 9F08 LS application version
i = i+1;
memcpy(lsVersionArr, &Recv_data[i],lsaVersionLen);
//points to Identifier of the Root Entity key set identifier
i = i+lsaVersionLen;
if(Recv_data[i] == TAG_RE_KEYID)
{
UINT8 rootEntityLen = 0;
i = i+1;
rootEntityLen = Recv_data[i];
i = i+1;
if(Recv_data[i] == TAG_LSRE_ID)
{
UINT8 tag42Len = 0;
i = i+1;
tag42Len = Recv_data[i];
//copy the data including length
memcpy(tag42Arr, &Recv_data[i], tag42Len+1);
i = i+tag42Len+1;
if(Recv_data[i] == TAG_LSRE_SIGNID)
{
UINT8 tag45Len = Recv_data[i+1];
memcpy(tag45Arr, &Recv_data[i+1],tag45Len+1);
status = STATUS_OK;
}
else
{
ALOGE("Invalid Root entity for TAG 45 = 0x%x; "
"status=0x%x", Recv_data[i], status);
return status;
}
}
else
{
ALOGE("Invalid Root entity for TAG 42 = 0x%x; "
"status=0x%x", Recv_data[i], status);
return status;
}
}
else
{
ALOGE("Invalid Root entity key set TAG ID = 0x%x; "
"status=0x%x", Recv_data[i], status);
return status;
}
}
}
else
{
ALOGE("Invalid Loader Service AID TAG ID = 0x%x; status=0x%x",
Recv_data[i], status);
return status;
}
}
else
{
ALOGE("Invalid FCI TAG = 0x%x; status=0x%x", Recv_data[i], status);
return status;
}
#else
if(Recv_data[i] == TAG_PRO_DATA_ID)
{
ALOGE("TAG: TAG_PRO_DATA_ID");
i = i+1;
len = Recv_data[i];
i = i + 1; //points to next tag name 61
}
}
}
else
{
/*
* Invalid start of TAG Name found
* */
ALOGE("Invalid TAG ID = 0x%x; status=0x%x", Recv_data[i], status);
return status;
}
if((i < Recv_len) &&
(Recv_data[i] == TAG_JSBL_KEY_ID))
{
/*
* Valid Key is found
* Copy the data into Select_Rsp
* */
ALOGE("Valid key id is found");
i = i +1;
len = Recv_data[i];
if(len != 0x00)
{
i = i+1;
memcpy(Select_Rsp, &Recv_data[i], len);
Select_Rsp_Len = len;
status = STATUS_OK;
}
/*
* Identifier of the certificate storing
* JSBL encryption key
* */
i = i + len;
if(Recv_data[i] == TAG_JSBL_CER_ID)
{
i = i+1;
len = Recv_data[i];
if(len != 0x00)
{
i = i+1;
Jsbl_keylen = len;
memcpy(Jsbl_RefKey, &Recv_data[i], len);
}
}
}
#endif
ALOGE("%s: Exiting status = 0x%x", fn, status);
return status;
}
#ifdef JCOP3_WR
tJBL_STATUS Bufferize_load_cmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn[] = "Bufferize_load_cmds";
UINT8 Param_P2;
status = STATUS_FAILED;
if(cmd_count == 0x00)
{
if((pTranscv_Info->sSendData[1] == INSTAL_LOAD_ID) &&
(pTranscv_Info->sSendData[2] == PARAM_P1_OFFSET) &&
(pTranscv_Info->sSendData[3] == 0x00))
{
ALOGE("BUffer: install for load");
pBuffer[0] = pTranscv_Info->sSendlength;
memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
cmd_count++;
}
else
{
/*
* Do not buffer this cmd
* Send this command to eSE
* */
status = STATUS_OK;
}
}
else
{
Param_P2 = cmd_count -1;
if((pTranscv_Info->sSendData[1] == LOAD_CMD_ID) &&
(pTranscv_Info->sSendData[2] == LOAD_MORE_BLOCKS) &&
(pTranscv_Info->sSendData[3] == Param_P2))
{
ALOGE("BUffer: load");
pBuffer[0] = pTranscv_Info->sSendlength;
memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
cmd_count++;
}
else if((pTranscv_Info->sSendData[1] == LOAD_CMD_ID) &&
(pTranscv_Info->sSendData[2] == LOAD_LAST_BLOCK) &&
(pTranscv_Info->sSendData[3] == Param_P2))
{
ALOGE("BUffer: last load");
SendBack_cmds = true;
pBuffer[0] = pTranscv_Info->sSendlength;
memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
cmd_count++;
islastcmdLoad = true;
}
else
{
ALOGE("BUffer: Not a load cmd");
SendBack_cmds = true;
pBuffer[0] = pTranscv_Info->sSendlength;
memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
islastcmdLoad = false;
cmd_count++;
}
}
ALOGE("%s: exit; status=0x%x", fn, status);
return status;
}
tJBL_STATUS Send_Backall_Loadcmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn [] = "Send_Backall_Loadcmds";
bool stat =false;
UINT8 xx=0;
status = STATUS_FAILED;
INT32 recvBufferActualSize=0, recv_len = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
ALOGD("%s: enter", fn);
pBuffer = Cmd_Buffer; // Points to start of first cmd to send
if(cmd_count == 0x00)
{
ALOGE("No cmds to stored to send to eSE");
}
else
{
while(cmd_count-- > 0)
{
pTranscv_Info->sSendlength = pBuffer[0];
memcpy(pTranscv_Info->sSendData, &pBuffer[1], pTranscv_Info->sSendlength);
pBuffer = pBuffer + 1 + pTranscv_Info->sSendlength;
stat = mchannel->transceive(pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if(stat != TRUE ||
(recvBufferActualSize < 2))
{
ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
}
else if(cmd_count == 0x00) //Last command in the buffer
{
if (islastcmdLoad == false)
{
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
}
else if((recvBufferActualSize == 0x02) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
{
recvBufferActualSize = 0x03;
pTranscv_Info->sRecvData[0] = 0x00;
pTranscv_Info->sRecvData[1] = 0x90;
pTranscv_Info->sRecvData[2] = 0x00;
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
}
else
{
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
}
}
else if((recvBufferActualSize == 0x02) &&
(pTranscv_Info->sRecvData[0] == 0x90) &&
(pTranscv_Info->sRecvData[1] == 0x00))
{
/*Do not do anything
* send next command in the buffer*/
}
else if((recvBufferActualSize == 0x03) &&
(pTranscv_Info->sRecvData[0] == 0x00) &&
(pTranscv_Info->sRecvData[1] == 0x90) &&
(pTranscv_Info->sRecvData[2] == 0x00))
{
/*Do not do anything
* Send next cmd in the buffer*/
}
else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] != 0x00))
{
/*Error condition hence exiting the loop*/
status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
/*If the sending of Load fails reset the count*/
cmd_count=0;
break;
}
}
}
memset(Cmd_Buffer, 0, sizeof(Cmd_Buffer));
pBuffer = Cmd_Buffer; //point back to start of line
cmd_count = 0x00;
ALOGD("%s: exit: status=0x%x", fn, status);
return status;
}
#endif
/*******************************************************************************
**
** Function: Numof_lengthbytes
**
** Description: Checks the number of length bytes and assigns
** length value to wLen.
**
** Returns: Number of Length bytes
**
*******************************************************************************/
UINT8 Numof_lengthbytes(UINT8 *read_buf, INT32 *pLen)
{
static const char fn[]= "Numof_lengthbytes";
UINT8 len_byte=0, i=0;
INT32 wLen = 0;
ALOGE("%s:enter", fn);
if(read_buf[i] == 0x00)
{
ALOGE("Invalid length zero");
len_byte = 0x00;
}
else if((read_buf[i] & 0x80) == 0x80)
{
len_byte = read_buf[i] & 0x0F;
len_byte = len_byte +1; //1 byte added for byte 0x81
}
else
{
len_byte = 0x01;
}
/*
* To get the length of the value field
* */
switch(len_byte)
{
case 0:
wLen = read_buf[0];
break;
case 1:
/*1st byte is the length*/
wLen = read_buf[0];
break;
case 2:
/*2nd byte is the length*/
wLen = read_buf[1];
break;
case 3:
/*1st and 2nd bytes are length*/
wLen = read_buf[1];
wLen = ((wLen << 8) | (read_buf[2]));
break;
case 4:
/*3bytes are the length*/
wLen = read_buf[1];
wLen = ((wLen << 16) | (read_buf[2] << 8));
wLen = (wLen | (read_buf[3]));
break;
default:
ALOGE("default case");
break;
}
*pLen = wLen;
ALOGE("%s:exit; len_bytes=0x0%x, Length=%ld", fn, len_byte, *pLen);
return len_byte;
}
#if(NXP_LDR_SVC_VER_2 == TRUE)
/*******************************************************************************
**
** Function: Write_Response_To_OutFile
**
** Description: Write the response to Out file
** with length recvlen from buffer RecvData.
**
** Returns: Success if OK
**
*******************************************************************************/
tJBL_STATUS Write_Response_To_OutFile(Ala_ImageInfo_t *image_info, UINT8* RecvData,
INT32 recvlen, Ls_TagType tType)
{
INT32 respLen = 0;
tJBL_STATUS wStatus = STATUS_FAILED;
static const char fn [] = "Write_Response_to_OutFile";
INT32 status = 0;
UINT8 tagBuffer[12] = {0x61,0,0,0,0,0,0,0,0,0,0,0};
INT32 tag44Len = 0;
INT32 tag61Len = 0;
UINT8 tag43Len = 1;
UINT8 tag43off = 0;
UINT8 tag44off = 0;
UINT8 ucTag44[3] = {0x00,0x00,0x00};
UINT8 tagLen = 0;
UINT8 tempLen = 0;
/*If the Response out file is NULL or Other than LS commands*/
if((image_info->bytes_wrote == 0x55)||(tType == LS_Default))
{
return STATUS_OK;
}
/*Certificate TAG occupies 2 bytes*/
if(tType == LS_Cert)
{
tag43Len = 2;
}
ALOGE("%s: Enter", fn);
/* |TAG | LEN(BERTLV)| VAL |
* | 61 | XX | TAG | LEN | VAL | TAG | LEN(BERTLV) | VAL |
* | 43 | 1/2 | 7F21/60/40 | 44 | apduRespLen | apduResponse |
**/
if(recvlen < 0x80)
{
tag44Len = 1;
ucTag44[0] = recvlen;
tag61Len = recvlen + 4 + tag43Len;
if(tag61Len&0x80)
{
tagBuffer[1] = 0x81;
tagBuffer[2] = tag61Len;
tag43off = 3;
tag44off = 5+tag43Len;
tagLen = tag44off+2;
}
else
{
tagBuffer[1] = tag61Len;
tag43off = 2;
tag44off = 4+tag43Len;
tagLen = tag44off+2;
}
}
else if((recvlen >= 0x80)&&(recvlen <= 0xFF))
{
ucTag44[0] = 0x81;
ucTag44[1] = recvlen;
tag61Len = recvlen + 5 + tag43Len;
tag44Len = 2;
if((tag61Len&0xFF00) != 0)
{
tagBuffer[1] = 0x82;
tagBuffer[2] = (tag61Len & 0xFF00)>>8;
tagBuffer[3] = (tag61Len & 0xFF);
tag43off = 4;
tag44off = 6+tag43Len;
tagLen = tag44off+3;
}
else
{
tagBuffer[1] = 0x81;
tagBuffer[2] = (tag61Len & 0xFF);
tag43off = 3;
tag44off = 5+tag43Len;
tagLen = tag44off+3;
}
}
else if((recvlen > 0xFF) &&(recvlen <= 0xFFFF))
{
ucTag44[0] = 0x82;
ucTag44[1] = (recvlen&0xFF00)>>8;
ucTag44[2] = (recvlen&0xFF);
tag44Len = 3;
tag61Len = recvlen + 6 + tag43Len;
if((tag61Len&0xFF00) != 0)
{
tagBuffer[1] = 0x82;
tagBuffer[2] = (tag61Len & 0xFF00)>>8;
tagBuffer[3] = (tag61Len & 0xFF);
tag43off = 4;
tag44off = 6+tag43Len;
tagLen = tag44off+4;
}
}
tagBuffer[tag43off] = 0x43;
tagBuffer[tag43off+1] = tag43Len;
tagBuffer[tag44off] = 0x44;
memcpy(&tagBuffer[tag44off+1], &ucTag44[0],tag44Len);
if(tType == LS_Cert)
{
tagBuffer[tag43off+2] = 0x7F;
tagBuffer[tag43off+3] = 0x21;
}
else if(tType == LS_Sign)
{
tagBuffer[tag43off+2] = 0x60;
}
else if(tType == LS_Comm)
{
tagBuffer[tag43off+2] = 0x40;
}
else
{
/*Do nothing*/
}
while(tempLen < tagLen)
{
status = fprintf(image_info->fResp, "%02X", tagBuffer[tempLen++]);
if(status != 2)
{
ALOGE("%s: Invalid Response during fprintf; status=0x%lx", fn, (status));
wStatus = STATUS_FAILED;
break;
}
}
/*Updating the response data into out script*/
while(respLen < recvlen)
{
status = fprintf(image_info->fResp, "%02X", RecvData[respLen++]);
if(status != 2)
{
ALOGE("%s: Invalid Response during fprintf; status=0x%lx", fn, (status));
wStatus = STATUS_FAILED;
break;
}
}
if((status == 2))
{
fprintf(image_info->fResp, "%s\n", "");
ALOGE("%s: SUCCESS Response written to script out file; status=0x%lx", fn, (status));
wStatus = STATUS_OK;
}
return wStatus;
}
/*******************************************************************************
**
** Function: Check_Certificate_Tag
**
** Description: Check certificate Tag presence in script
** by 7F21 .
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_Certificate_Tag(UINT8 *read_buf, UINT16 *offset1)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 len_byte = 0;
INT32 wLen, recvBufferActualSize=0;
UINT16 offset = *offset1;
if(((read_buf[offset]<<8|read_buf[offset+1]) == TAG_CERTIFICATE))
{
ALOGD("TAGID: TAG_CERTIFICATE");
offset = offset+2;
len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
offset = offset + len_byte;
*offset1 = offset;
if(wLen <= MAX_CERT_LEN)
status = STATUS_OK;
}
return status;
}
/*******************************************************************************
**
** Function: Check_SerialNo_Tag
**
** Description: Check Serial number Tag presence in script
** by 0x93 .
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_SerialNo_Tag(UINT8 *read_buf, UINT16 *offset1)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 offset = *offset1;
static const char fn[] = "Check_SerialNo_Tag";
if((read_buf[offset] == TAG_SERIAL_NO))
{
ALOGD("TAGID: TAG_SERIAL_NO");
UINT8 serNoLen = read_buf[offset+1];
offset = offset + serNoLen + 2;
*offset1 = offset;
ALOGD("%s: TAG_LSROOT_ENTITY is %x", fn, read_buf[offset]);
status = STATUS_OK;
}
return status;
}
/*******************************************************************************
**
** Function: Check_LSRootID_Tag
**
** Description: Check LS root ID tag presence in script and compare with
** select response root ID value.
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_LSRootID_Tag(UINT8 *read_buf, UINT16 *offset1)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 offset = *offset1;
if(read_buf[offset] == TAG_LSRE_ID)
{
ALOGD("TAGID: TAG_LSROOT_ENTITY");
if(tag42Arr[0] == read_buf[offset+1])
{
UINT8 tag42Len = read_buf[offset+1];
offset = offset+2;
status = memcmp(&read_buf[offset],&tag42Arr[1],tag42Arr[0]);
ALOGD("ALA_Check_KeyIdentifier : TAG 42 verified");
if(status == STATUS_OK)
{
ALOGD("ALA_Check_KeyIdentifier : Loader service root entity "
"ID is matched");
offset = offset+tag42Len;
*offset1 = offset;
}
}
}
return status;
}
/*******************************************************************************
**
** Function: Check_CertHoldID_Tag
**
** Description: Check certificate holder ID tag presence in script.
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_CertHoldID_Tag(UINT8 *read_buf, UINT16 *offset1)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 offset = *offset1;
if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_CERTFHOLD_ID)
{
UINT8 certfHoldIDLen = 0;
ALOGD("TAGID: TAG_CERTFHOLD_ID");
certfHoldIDLen = read_buf[offset+2];
offset = offset+certfHoldIDLen+3;
if(read_buf[offset] == TAG_KEY_USAGE)
{
UINT8 keyusgLen = 0;
ALOGD("TAGID: TAG_KEY_USAGE");
keyusgLen = read_buf[offset+1];
offset = offset+keyusgLen+2;
*offset1 = offset;
status = STATUS_OK;
}
}
return status;
}
/*******************************************************************************
**
** Function: Check_Date_Tag
**
** Description: Check date tags presence in script.
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_Date_Tag(UINT8 *read_buf, UINT16 *offset1)
{
tJBL_STATUS status = STATUS_OK;
UINT16 offset = *offset1;
if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EFF_DATE)
{
UINT8 effDateLen = read_buf[offset+2];
offset = offset+3+effDateLen;
ALOGD("TAGID: TAG_EFF_DATE");
if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EXP_DATE)
{
UINT8 effExpLen = read_buf[offset+2];
offset = offset+3+effExpLen;
ALOGD("TAGID: TAG_EXP_DATE");
status = STATUS_OK;
}else if(read_buf[offset] == TAG_LSRE_SIGNID)
{
status = STATUS_OK;
}
}
else if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EXP_DATE)
{
UINT8 effExpLen = read_buf[offset+2];
offset = offset+3+effExpLen;
ALOGD("TAGID: TAG_EXP_DATE");
status = STATUS_OK;
}else if(read_buf[offset] == TAG_LSRE_SIGNID)
{
status = STATUS_OK;
}
else
{
/*STATUS_FAILED*/
}
*offset1 = offset;
return status;
}
/*******************************************************************************
**
** Function: Check_45_Tag
**
** Description: Check 45 tags presence in script and compare the value
** with select response tag 45 value
**
** Returns: Success if Tag found
**
*******************************************************************************/
tJBL_STATUS Check_45_Tag(UINT8 *read_buf, UINT16 *offset1, UINT8 *tag45Len)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 offset = *offset1;
if(read_buf[offset] == TAG_LSRE_SIGNID)
{
*tag45Len = read_buf[offset+1];
offset = offset+2;
if(tag45Arr[0] == *tag45Len)
{
status = memcmp(&read_buf[offset],&tag45Arr[1],tag45Arr[0]);
if(status == STATUS_OK)
{
ALOGD("ALA_Check_KeyIdentifier : TAG 45 verified");
*offset1 = offset;
}
}
}
return status;
}
/*******************************************************************************
**
** Function: Certificate_Verification
**
** Description: Perform the certificate verification by forwarding it to
** LS applet.
**
** Returns: Success if certificate is verified
**
*******************************************************************************/
tJBL_STATUS Certificate_Verification(Ala_ImageInfo_t *Os_info,
Ala_TranscieveInfo_t *pTranscv_Info, UINT8 *read_buf, UINT16 *offset1,
UINT8 *tag45Len)
{
tJBL_STATUS status = STATUS_FAILED;
UINT16 offset = *offset1;
INT32 wCertfLen = (read_buf[2]<<8|read_buf[3]);
tJBL_STATUS certf_found = STATUS_FAILED;
static const char fn[] = "Certificate_Verification";
UINT8 tag_len_byte = Numof_lengthbytes(&read_buf[2], &wCertfLen);
pTranscv_Info->sSendData[0] = 0x80;
pTranscv_Info->sSendData[1] = 0xA0;
pTranscv_Info->sSendData[2] = 0x01;
pTranscv_Info->sSendData[3] = 0x00;
/*If the certificate is less than 255 bytes*/
if(wCertfLen <= 251)
{
UINT8 tag7f49Off = 0;
UINT8 u7f49Len = 0;
UINT8 tag5f37Len = 0;
ALOGD("Certificate is greater than 255");
offset = offset+*tag45Len;
ALOGD("%s: Before TAG_CCM_PERMISSION = %x",fn, read_buf[offset]);
if(read_buf[offset] == TAG_CCM_PERMISSION)
{
INT32 tag53Len = 0;
UINT8 len_byte = 0;
offset =offset+1;
len_byte = Numof_lengthbytes(&read_buf[offset], &tag53Len);
offset = offset+tag53Len+len_byte;
ALOGD("%s: Verified TAG TAG_CCM_PERMISSION = 0x53",fn);
if((UINT16)(read_buf[offset]<<8|read_buf[offset+1]) == TAG_SIG_RNS_COMP)
{
tag7f49Off = offset;
u7f49Len = read_buf[offset+2];
offset = offset+3+u7f49Len;
if(u7f49Len != 64)
{
return STATUS_FAILED;
}
if((UINT16)(read_buf[offset]<<8|read_buf[offset+1]) == 0x7f49)
{
tag5f37Len = read_buf[offset+2];
if(read_buf[offset+3] != 0x86 || (read_buf[offset+4] != 65))
{
return STATUS_FAILED;
}
}
else
{
return STATUS_FAILED;
}
}
else
{
return STATUS_FAILED;
}
}
else
{
return STATUS_FAILED;
}
pTranscv_Info->sSendData[4] = wCertfLen+2+tag_len_byte;
pTranscv_Info->sSendlength = wCertfLen+7+tag_len_byte;
memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[0], wCertfLen+2+tag_len_byte);
ALOGD("%s: start transceive for length %ld", fn, pTranscv_Info->
sSendlength);
status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Cert);
if(status != STATUS_OK)
{
return status;
}
else
{
certf_found = STATUS_OK;
ALOGD("Certificate is verified");
return status;
}
}
/*If the certificate is more than 255 bytes*/
else
{
UINT8 tag7f49Off = 0;
UINT8 u7f49Len = 0;
UINT8 tag5f37Len = 0;
ALOGD("Certificate is greater than 255");
offset = offset+*tag45Len;
ALOGD("%s: Before TAG_CCM_PERMISSION = %x",fn, read_buf[offset]);
if(read_buf[offset] == TAG_CCM_PERMISSION)
{
INT32 tag53Len = 0;
UINT8 len_byte = 0;
offset =offset+1;
len_byte = Numof_lengthbytes(&read_buf[offset], &tag53Len);
offset = offset+tag53Len+len_byte;
ALOGD("%s: Verified TAG TAG_CCM_PERMISSION = 0x53",fn);
if((UINT16)(read_buf[offset]<<8|read_buf[offset+1]) == TAG_SIG_RNS_COMP)
{
tag7f49Off = offset;
u7f49Len = read_buf[offset+2];
offset = offset+3+u7f49Len;
if(u7f49Len != 64)
{
return STATUS_FAILED;
}
if((UINT16)(read_buf[offset]<<8|read_buf[offset+1]) == 0x7f49)
{
tag5f37Len = read_buf[offset+2];
if(read_buf[offset+3] != 0x86 || (read_buf[offset+4] != 65))
{
return STATUS_FAILED;
}
}
else
{
return STATUS_FAILED;
}
pTranscv_Info->sSendData[4] = tag7f49Off;
memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[0], tag7f49Off);
pTranscv_Info->sSendlength = tag7f49Off+5;
ALOGD("%s: start transceive for length %ld", fn,
pTranscv_Info->sSendlength);
status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Default);
if(status != STATUS_OK)
{
UINT8* RecvData = pTranscv_Info->sRecvData;
Write_Response_To_OutFile(Os_info, RecvData,
resp_len, LS_Cert);
return status;
}
pTranscv_Info->sSendData[2] = 0x00;
pTranscv_Info->sSendData[4] = u7f49Len+tag5f37Len+6;
memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[tag7f49Off],
u7f49Len+tag5f37Len+6);
pTranscv_Info->sSendlength = u7f49Len+tag5f37Len+11;
ALOGD("%s: start transceive for length %ld", fn,
pTranscv_Info->sSendlength);
status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Cert);
if(status != STATUS_OK)
{
return status;
}
else
{
ALOGD("Certificate is verified");
certf_found = STATUS_OK;
return status;
}
}
else
{
return STATUS_FAILED;
}
}
else
{
return STATUS_FAILED;
}
}
return status;
}
/*******************************************************************************
**
** Function: Check_Complete_7F21_Tag
**
** Description: Traverses the 7F21 tag for verification of each sub tag with
** in the 7F21 tag.
**
** Returns: Success if all tags are verified
**
*******************************************************************************/
tJBL_STATUS Check_Complete_7F21_Tag(Ala_ImageInfo_t *Os_info,
Ala_TranscieveInfo_t *pTranscv_Info, UINT8 *read_buf, UINT16 *offset)
{
static const char fn[] = "Check_Complete_7F21_Tag";
UINT8 tag45Len = 0;
if(STATUS_OK == Check_Certificate_Tag(read_buf, offset))
{
if(STATUS_OK == Check_SerialNo_Tag(read_buf, offset))
{
if(STATUS_OK == Check_LSRootID_Tag(read_buf, offset))
{
if(STATUS_OK == Check_CertHoldID_Tag(read_buf, offset))
{
if(STATUS_OK == Check_Date_Tag(read_buf, offset))
{
UINT8 tag45Len = 0;
if(STATUS_OK == Check_45_Tag(read_buf, offset,
&tag45Len))
{
if(STATUS_OK == Certificate_Verification(
Os_info, pTranscv_Info, read_buf, offset,
&tag45Len))
{
return STATUS_OK;
}
}else{
ALOGE("%s: FAILED in Check_45_Tag", fn);}
}else{
ALOGE("%s: FAILED in Check_Date_Tag", fn);}
}else{
ALOGE("%s: FAILED in Check_CertHoldID_Tag", fn);}
}else{
ALOGE("%s: FAILED in Check_LSRootID_Tag", fn);}
}else{
ALOGE("%s: FAILED in Check_SerialNo_Tag", fn);}
}
else
{
ALOGE("%s: FAILED in Check_Certificate_Tag", fn);
}
return STATUS_FAILED;
}
BOOLEAN ALA_UpdateExeStatus(UINT16 status)
{
fLS_STATUS = fopen(LS_STATUS_PATH, "w+");
ALOGD("enter: ALA_UpdateExeStatus");
if(fLS_STATUS == NULL)
{
ALOGE("Error opening LS Status file for backup: %s",strerror(errno));
return FALSE;
}
if((fprintf(fLS_STATUS, "%04x",status)) != 4)
{
ALOGE("Error updating LS Status backup: %s",strerror(errno));
fclose(fLS_STATUS);
return FALSE;
}
ALOGD("exit: ALA_UpdateExeStatus");
fclose(fLS_STATUS);
return TRUE;
}
/*******************************************************************************
**
** Function: ALA_getAppletLsStatus
**
** Description: Interface to fetch Loader service Applet status to JNI, Services
**
** Returns: SUCCESS/FAILURE
**
*******************************************************************************/
tJBL_STATUS ALA_getAppletLsStatus(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
{
static const char fn[] = "ALA_getAppletLsStatus";
bool stat = false;
INT32 recvBufferActualSize = 0;
IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
ALOGD("%s: enter", fn);
if(Os_info == NULL ||
pTranscv_Info == NULL)
{
ALOGD("%s: Invalid parameter", fn);
}
else
{
pTranscv_Info->sSendData[0] = STORE_DATA_CLA | Os_info->Channel_Info[0].channel_id;
pTranscv_Info->timeout = gTransceiveTimeout;
pTranscv_Info->sSendlength = (INT32)sizeof(GetData);
pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
memcpy(&(pTranscv_Info->sSendData[1]), &GetData[1],
((sizeof(GetData))-1));
ALOGD("%s: Calling Secure Element Transceive with GET DATA apdu", fn);
stat = mchannel->transceive (pTranscv_Info->sSendData,
pTranscv_Info->sSendlength,
pTranscv_Info->sRecvData,
pTranscv_Info->sRecvlength,
recvBufferActualSize,
pTranscv_Info->timeout);
if((stat != TRUE) &&
(recvBufferActualSize == 0x00))
{
status = STATUS_FAILED;
ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
}
else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
(pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
{
ALOGE("STORE CMD is successful");
if((pTranscv_Info->sRecvData[0] == 0x46 )&& (pTranscv_Info->sRecvData[1] == 0x01 ))
{
if((pTranscv_Info->sRecvData[2] == 0x01))
{
lsGetStatusArr[0]=0x63;lsGetStatusArr[1]=0x40;
ALOGE("%s: Script execution status FAILED", fn);
}
else if((pTranscv_Info->sRecvData[2] == 0x00))
{
lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
ALOGE("%s: Script execution status SUCCESS", fn);
}
else
{
lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
ALOGE("%s: Script execution status UNKNOWN", fn);
}
}
else
{
lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
ALOGE("%s: Script execution status UNKNOWN", fn);
}
status = STATUS_SUCCESS;
}
else
{
status = STATUS_FAILED;
}
ALOGE("%s: exit; status=0x%x", fn, status);
}
return status;
}
/*******************************************************************************
**
** Function: Get_LsStatus
**
** Description: Interface to fetch Loader service client status to JNI, Services
**
** Returns: SUCCESS/FAILURE
**
*******************************************************************************/
tJBL_STATUS Get_LsStatus(UINT8 *pStatus)
{
tJBL_STATUS status = STATUS_FAILED;
UINT8 lsStatus[2] = {0x63,0x40};
UINT8 loopcnt = 0;
fLS_STATUS = fopen(LS_STATUS_PATH, "r");
if(fLS_STATUS == NULL)
{
ALOGE("Error opening LS Status file for backup: %s",strerror(errno));
return status;
}
for(loopcnt=0;loopcnt<2;loopcnt++)
{
if((FSCANF_BYTE(fLS_STATUS, "%2x", &lsStatus[loopcnt])) == 0)
{
ALOGE("Error updating LS Status backup: %s",strerror(errno));
fclose(fLS_STATUS);
return status;
}
}
ALOGD("enter: ALA_getLsStatus 0x%X 0x%X",lsStatus[0],lsStatus[1] );
memcpy(pStatus, lsStatus, 2);
fclose(fLS_STATUS);
return STATUS_OK;
}
#endif