C++程序  |  3066行  |  98.2 KB

 /*
  * 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