| /* |
| * 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 <cutils/log.h> |
| #include <semaphore.h> |
| #include <AlaLib.h> |
| #include <JcopOsDownload.h> |
| #include <IChannel.h> |
| #include <errno.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <sys/stat.h> |
| |
| JcopOsDwnld JcopOsDwnld::sJcopDwnld; |
| INT32 gTransceiveTimeout = 120000; |
| |
| tJBL_STATUS (JcopOsDwnld::*JcopOs_dwnld_seqhandler[])( |
| JcopOs_ImageInfo_t* pContext, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pInfo)={ |
| &JcopOsDwnld::TriggerApdu, |
| &JcopOsDwnld::GetInfo, |
| &JcopOsDwnld::load_JcopOS_image, |
| &JcopOsDwnld::GetInfo, |
| &JcopOsDwnld::load_JcopOS_image, |
| &JcopOsDwnld::GetInfo, |
| &JcopOsDwnld::load_JcopOS_image, |
| NULL |
| }; |
| |
| pJcopOs_Dwnld_Context_t gpJcopOs_Dwnld_Context = NULL; |
| static const char *path[3] = {"/data/vendor/ese/JcopOs_Update1.apdu", |
| "/data/vendor/ese/JcopOs_Update2.apdu", |
| "/data/vendor/ese/JcopOs_Update3.apdu"}; |
| |
| /******************************************************************************* |
| ** |
| ** Function: getInstance |
| ** |
| ** Description: Get the JcopOsDwnld singleton object. |
| ** |
| ** Returns: JcopOsDwnld object. |
| ** |
| *******************************************************************************/ |
| JcopOsDwnld* JcopOsDwnld::getInstance() |
| { |
| JcopOsDwnld *jd = new JcopOsDwnld(); |
| return jd; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: getJcopOsFileInfo |
| ** |
| ** Description: Verify all the updater files required for download |
| ** are present or not |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| bool JcopOsDwnld::getJcopOsFileInfo() |
| { |
| static const char fn [] = "JcopOsDwnld::getJcopOsFileInfo"; |
| bool status = true; |
| struct stat st; |
| |
| for (int num = 0; num < 3; num++) |
| { |
| if (stat(path[num], &st)) |
| { |
| status = false; |
| } |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: initialize |
| ** |
| ** Description: Initialize all member variables. |
| ** native: Native data. |
| ** |
| ** Returns: True if ok. |
| ** |
| *******************************************************************************/ |
| bool JcopOsDwnld::initialize (IChannel_t *channel) |
| { |
| static const char fn [] = "JcopOsDwnld::initialize"; |
| |
| ALOGD ("%s: enter", fn); |
| |
| if (!getJcopOsFileInfo()) |
| { |
| ALOGD("%s: insufficient resources, file not present", fn); |
| return (false); |
| } |
| gpJcopOs_Dwnld_Context = (pJcopOs_Dwnld_Context_t)malloc(sizeof(JcopOs_Dwnld_Context_t)); |
| if(gpJcopOs_Dwnld_Context != NULL) |
| { |
| memset((void *)gpJcopOs_Dwnld_Context, 0, (UINT32)sizeof(JcopOs_Dwnld_Context_t)); |
| gpJcopOs_Dwnld_Context->channel = (IChannel_t*)malloc(sizeof(IChannel_t)); |
| if(gpJcopOs_Dwnld_Context->channel != NULL) |
| { |
| memset(gpJcopOs_Dwnld_Context->channel, 0, sizeof(IChannel_t)); |
| } |
| else |
| { |
| ALOGD("%s: Memory allocation for IChannel is failed", fn); |
| return (false); |
| } |
| gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = (UINT8*)malloc(sizeof(UINT8)*JCOP_MAX_BUF_SIZE); |
| if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL) |
| { |
| memset(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData, 0, JCOP_MAX_BUF_SIZE); |
| } |
| else |
| { |
| ALOGD("%s: Memory allocation for SendBuf is failed", fn); |
| return (false); |
| } |
| } |
| else |
| { |
| ALOGD("%s: Memory allocation failed", fn); |
| return (false); |
| } |
| mIsInit = true; |
| memcpy(gpJcopOs_Dwnld_Context->channel, channel, sizeof(IChannel_t)); |
| ALOGD ("%s: exit", fn); |
| return (true); |
| } |
| /******************************************************************************* |
| ** |
| ** Function: finalize |
| ** |
| ** Description: Release all resources. |
| ** |
| ** Returns: None |
| ** |
| *******************************************************************************/ |
| void JcopOsDwnld::finalize () |
| { |
| static const char fn [] = "JcopOsDwnld::finalize"; |
| ALOGD ("%s: enter", fn); |
| mIsInit = false; |
| if(gpJcopOs_Dwnld_Context != NULL) |
| { |
| if(gpJcopOs_Dwnld_Context->channel != NULL) |
| { |
| free(gpJcopOs_Dwnld_Context->channel); |
| gpJcopOs_Dwnld_Context->channel = NULL; |
| } |
| if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL) |
| { |
| free(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData); |
| gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = NULL; |
| } |
| free(gpJcopOs_Dwnld_Context); |
| gpJcopOs_Dwnld_Context = NULL; |
| } |
| ALOGD ("%s: exit", fn); |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: JcopOs_Download |
| ** |
| ** Description: Starts the OS download sequence |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::JcopOs_Download() |
| { |
| static const char fn [] = "JcopOsDwnld::JcopOs_Download"; |
| tJBL_STATUS wstatus = STATUS_FAILED; |
| JcopOs_TranscieveInfo_t pTranscv_Info; |
| JcopOs_ImageInfo_t ImageInfo; |
| UINT8 retry_cnt = 0x00; |
| ALOGD("%s: enter:", fn); |
| if(mIsInit == false) |
| { |
| ALOGD ("%s: JcopOs Dwnld is not initialized", fn); |
| wstatus = STATUS_FAILED; |
| } |
| else |
| { |
| do |
| { |
| wstatus = JcopOsDwnld::JcopOs_update_seq_handler(); |
| if(wstatus == STATUS_FAILED) |
| retry_cnt++; |
| else |
| break; |
| }while(retry_cnt < JCOP_MAX_RETRY_CNT); |
| } |
| ALOGD("%s: exit; status = 0x%x", fn, wstatus); |
| return wstatus; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: JcopOs_update_seq_handler |
| ** |
| ** Description: Performs the JcopOS download sequence |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::JcopOs_update_seq_handler() |
| { |
| static const char fn[] = "JcopOsDwnld::JcopOs_update_seq_handler"; |
| UINT8 seq_counter = 0; |
| JcopOs_ImageInfo_t update_info = (JcopOs_ImageInfo_t )gpJcopOs_Dwnld_Context->Image_info; |
| JcopOs_TranscieveInfo_t trans_info = (JcopOs_TranscieveInfo_t )gpJcopOs_Dwnld_Context->pJcopOs_TransInfo; |
| update_info.index = 0x00; |
| update_info.cur_state = 0x00; |
| tJBL_STATUS status = STATUS_FAILED; |
| |
| ALOGD("%s: enter", fn); |
| status = GetJcopOsState(&update_info, &seq_counter); |
| if(status != STATUS_SUCCESS) |
| { |
| ALOGE("Error in getting JcopOsState info"); |
| } |
| else |
| { |
| ALOGE("seq_counter %d", seq_counter); |
| while((JcopOs_dwnld_seqhandler[seq_counter]) != NULL ) |
| { |
| status = STATUS_FAILED; |
| status = (*this.*(JcopOs_dwnld_seqhandler[seq_counter]))(&update_info, status, &trans_info ); |
| if(STATUS_SUCCESS != status) |
| { |
| ALOGE("%s: exiting; status=0x0%X", fn, status); |
| break; |
| } |
| seq_counter++; |
| } |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: TriggerApdu |
| ** |
| ** Description: Switch to updater OS |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::TriggerApdu(JcopOs_ImageInfo_t* pVersionInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info) |
| { |
| static const char fn [] = "JcopOsDwnld::TriggerApdu"; |
| bool stat = false; |
| IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel; |
| INT32 recvBufferActualSize = 0; |
| |
| ALOGD("%s: enter;", fn); |
| |
| if(pTranscv_Info == NULL || |
| pVersionInfo == NULL) |
| { |
| ALOGD("%s: Invalid parameter", fn); |
| status = STATUS_FAILED; |
| } |
| else |
| { |
| pTranscv_Info->timeout = gTransceiveTimeout; |
| pTranscv_Info->sSendlength = (INT32)sizeof(Trigger_APDU); |
| pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32); |
| memcpy(pTranscv_Info->sSendData, Trigger_APDU, 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) |
| { |
| status = STATUS_FAILED; |
| ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update |
| } |
| else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x68) && |
| (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x81))|| |
| ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) && |
| (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))|| |
| ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F) && |
| (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))) |
| { |
| mchannel->doeSE_JcopDownLoadReset(); |
| status = STATUS_OK; |
| ALOGD("%s: Trigger APDU Transceive status = 0x%X", fn, status); |
| } |
| else |
| { |
| /* status {90, 00} */ |
| status = STATUS_OK; |
| } |
| } |
| ALOGD("%s: exit; status = 0x%X", fn, status); |
| return status; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: GetInfo |
| ** |
| ** Description: Get the JCOP OS info |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::GetInfo(JcopOs_ImageInfo_t* pImageInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info) |
| { |
| static const char fn [] = "JcopOsDwnld::GetInfo"; |
| |
| bool stat = false; |
| IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel; |
| INT32 recvBufferActualSize = 0; |
| |
| ALOGD("%s: enter;", fn); |
| |
| if(pTranscv_Info == NULL || |
| pImageInfo == NULL) |
| { |
| ALOGD("%s: Invalid parameter", fn); |
| status = STATUS_FAILED; |
| } |
| else |
| { |
| memcpy(pImageInfo->fls_path, (char *)path[pImageInfo->index], strlen(path[pImageInfo->index])); |
| |
| memset(pTranscv_Info->sSendData, 0, JCOP_MAX_BUF_SIZE); |
| pTranscv_Info->timeout = gTransceiveTimeout; |
| pTranscv_Info->sSendlength = (UINT32)sizeof(GetInfo_APDU); |
| pTranscv_Info->sRecvlength = 1024; |
| memcpy(pTranscv_Info->sSendData, GetInfo_APDU, 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) |
| { |
| status = STATUS_FAILED; |
| pImageInfo->index =0; |
| ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update |
| } |
| else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) && |
| (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)) |
| { |
| pImageInfo->version_info.osid = pTranscv_Info->sRecvData[recvBufferActualSize-6]; |
| pImageInfo->version_info.ver1 = pTranscv_Info->sRecvData[recvBufferActualSize-5]; |
| pImageInfo->version_info.ver0 = pTranscv_Info->sRecvData[recvBufferActualSize-4]; |
| pImageInfo->version_info.OtherValid = pTranscv_Info->sRecvData[recvBufferActualSize-3]; |
| #if 0 |
| if((pImageInfo->index != 0) && |
| (pImageInfo->version_info.osid == 0x01) && |
| (pImageInfo->version_info.OtherValid == 0x11)) |
| { |
| ALOGE("3-Step update is not required"); |
| memset(pImageInfo->fls_path,0,sizeof(pImageInfo->fls_path)); |
| pImageInfo->index=0; |
| } |
| else |
| #endif |
| { |
| ALOGE("Starting 3-Step update"); |
| memcpy(pImageInfo->fls_path, path[pImageInfo->index], sizeof(path[pImageInfo->index])); |
| pImageInfo->index++; |
| } |
| status = STATUS_OK; |
| ALOGD("%s: GetInfo Transceive status = 0x%X", fn, status); |
| } |
| else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6A) && |
| (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x82) && |
| pImageInfo->version_info.ver_status == STATUS_UPTO_DATE) |
| { |
| status = STATUS_UPTO_DATE; |
| } |
| else |
| { |
| status = STATUS_FAILED; |
| ALOGD("%s; Invalid response for GetInfo", fn); |
| } |
| } |
| |
| if (status == STATUS_FAILED) |
| { |
| ALOGD("%s; status failed, doing reset...", fn); |
| mchannel->doeSE_JcopDownLoadReset(); |
| } |
| ALOGD("%s: exit; status = 0x%X", fn, status); |
| return status; |
| } |
| /******************************************************************************* |
| ** |
| ** Function: load_JcopOS_image |
| ** |
| ** Description: Used to update the JCOP OS |
| ** Get Info function has to be called before this |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::load_JcopOS_image(JcopOs_ImageInfo_t *Os_info, tJBL_STATUS status, JcopOs_TranscieveInfo_t *pTranscv_Info) |
| { |
| static const char fn [] = "JcopOsDwnld::load_JcopOS_image"; |
| bool stat = false; |
| int wResult, size =0; |
| INT32 wIndex,wCount=0; |
| INT32 wLen; |
| |
| IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel; |
| INT32 recvBufferActualSize = 0; |
| 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_FILE_NOT_FOUND; |
| } |
| 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); |
| 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; |
| } |
| while(!feof(Os_info->fp)) |
| { |
| ALOGE("%s; Start of line processing", fn); |
| |
| wIndex=0; |
| wLen=0; |
| wCount=0; |
| memset(pTranscv_Info->sSendData,0x00,JCOP_MAX_BUF_SIZE); |
| pTranscv_Info->sSendlength=0; |
| |
| ALOGE("%s; wIndex = 0", fn); |
| for(wCount =0; (wCount < 5 && !feof(Os_info->fp)); wCount++, wIndex++) |
| { |
| wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]); |
| } |
| if(wResult != 0) |
| { |
| wLen = pTranscv_Info->sSendData[4]; |
| ALOGE("%s; Read 5byes success & len=%d", fn,wLen); |
| if(wLen == 0x00) |
| { |
| ALOGE("%s: Extended APDU", fn); |
| wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]); |
| wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]); |
| wLen = ((pTranscv_Info->sSendData[5] << 8) | (pTranscv_Info->sSendData[6])); |
| } |
| for(wCount =0; (wCount < wLen && !feof(Os_info->fp)); wCount++, wIndex++) |
| { |
| wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]); |
| } |
| } |
| else |
| { |
| ALOGE("%s: JcopOs image Read failed", fn); |
| goto exit; |
| } |
| |
| pTranscv_Info->sSendlength = wIndex; |
| ALOGE("%s: start transceive for length %d", fn, pTranscv_Info->sSendlength); |
| if((pTranscv_Info->sSendlength != 0x03) && |
| (pTranscv_Info->sSendData[0] != 0x00) && |
| (pTranscv_Info->sSendData[1] != 0x00)) |
| { |
| |
| stat = mchannel->transceive(pTranscv_Info->sSendData, |
| pTranscv_Info->sSendlength, |
| pTranscv_Info->sRecvData, |
| pTranscv_Info->sRecvlength, |
| recvBufferActualSize, |
| pTranscv_Info->timeout); |
| } |
| else |
| { |
| ALOGE("%s: Invalid packet", fn); |
| continue; |
| } |
| if(stat != true) |
| { |
| ALOGE("%s: Transceive failed; status=0x%X", fn, stat); |
| status = STATUS_FAILED; |
| goto exit; |
| } |
| else if(recvBufferActualSize != 0 && |
| pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90 && |
| pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00) |
| { |
| //ALOGE("%s: END transceive for length %d", fn, pTranscv_Info->sSendlength); |
| status = STATUS_SUCCESS; |
| } |
| else if(pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F && |
| pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00) |
| { |
| ALOGE("%s: JcopOs is already upto date-No update required exiting", fn); |
| Os_info->version_info.ver_status = STATUS_UPTO_DATE; |
| status = STATUS_FAILED; |
| break; |
| } |
| else |
| { |
| status = STATUS_FAILED; |
| ALOGE("%s: Invalid response", fn); |
| goto exit; |
| } |
| ALOGE("%s: Going for next line", fn); |
| } |
| |
| if(status == STATUS_SUCCESS) |
| { |
| Os_info->cur_state++; |
| SetJcopOsState(Os_info, Os_info->cur_state); |
| } |
| |
| exit: |
| mchannel->doeSE_JcopDownLoadReset(); |
| ALOGE("%s close fp and exit; status= 0x%X", fn,status); |
| wResult = fclose(Os_info->fp); |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: GetJcopOsState |
| ** |
| ** Description: Used to update the JCOP OS state |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::GetJcopOsState(JcopOs_ImageInfo_t *Os_info, UINT8 *counter) |
| { |
| static const char fn [] = "JcopOsDwnld::GetJcopOsState"; |
| tJBL_STATUS status = STATUS_SUCCESS; |
| FILE *fp; |
| UINT8 xx=0; |
| ALOGD("%s: enter", fn); |
| if(Os_info == NULL) |
| { |
| ALOGE("%s: invalid parameter", fn); |
| return STATUS_FAILED; |
| } |
| fp = fopen(JCOP_INFO_PATH, "r"); |
| |
| if (fp == NULL) { |
| ALOGE("file <%s> not exits for reading- creating new file: %s", |
| JCOP_INFO_PATH, strerror(errno)); |
| fp = fopen(JCOP_INFO_PATH, "w+"); |
| if (fp == NULL) |
| { |
| ALOGE("Error opening OS image file <%s> for reading: %s", |
| JCOP_INFO_PATH, strerror(errno)); |
| return STATUS_FAILED; |
| } |
| fprintf(fp, "%u", xx); |
| fclose(fp); |
| } |
| else |
| { |
| FSCANF_BYTE(fp, "%u", &xx); |
| ALOGE("JcopOsState %d", xx); |
| fclose(fp); |
| } |
| |
| switch(xx) |
| { |
| case JCOP_UPDATE_STATE0: |
| case JCOP_UPDATE_STATE3: |
| ALOGE("Starting update from step1"); |
| Os_info->index = JCOP_UPDATE_STATE0; |
| Os_info->cur_state = JCOP_UPDATE_STATE0; |
| *counter = 0; |
| break; |
| case JCOP_UPDATE_STATE1: |
| ALOGE("Starting update from step2"); |
| Os_info->index = JCOP_UPDATE_STATE1; |
| Os_info->cur_state = JCOP_UPDATE_STATE1; |
| *counter = 3; |
| break; |
| case JCOP_UPDATE_STATE2: |
| ALOGE("Starting update from step3"); |
| Os_info->index = JCOP_UPDATE_STATE2; |
| Os_info->cur_state = JCOP_UPDATE_STATE2; |
| *counter = 5; |
| break; |
| default: |
| ALOGE("invalid state"); |
| status = STATUS_FAILED; |
| break; |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function: SetJcopOsState |
| ** |
| ** Description: Used to set the JCOP OS state |
| ** |
| ** Returns: Success if ok. |
| ** |
| *******************************************************************************/ |
| tJBL_STATUS JcopOsDwnld::SetJcopOsState(JcopOs_ImageInfo_t *Os_info, UINT8 state) |
| { |
| static const char fn [] = "JcopOsDwnld::SetJcopOsState"; |
| tJBL_STATUS status = STATUS_FAILED; |
| FILE *fp; |
| ALOGD("%s: enter", fn); |
| if(Os_info == NULL) |
| { |
| ALOGE("%s: invalid parameter", fn); |
| return status; |
| } |
| fp = fopen(JCOP_INFO_PATH, "w"); |
| |
| if (fp == NULL) { |
| ALOGE("Error opening OS image file <%s> for reading: %s", |
| JCOP_INFO_PATH, strerror(errno)); |
| } |
| else |
| { |
| fprintf(fp, "%u", state); |
| fflush(fp); |
| ALOGE("Current JcopOsState: %d", state); |
| status = STATUS_SUCCESS; |
| int fd=fileno(fp); |
| int ret = fdatasync(fd); |
| ALOGE("ret value: %d", ret); |
| fclose(fp); |
| } |
| return status; |
| } |
| |
| #if 0 |
| void *JcopOsDwnld::GetMemory(UINT32 size) |
| { |
| void *pMem; |
| static const char fn [] = "JcopOsDwnld::GetMemory"; |
| pMem = (void *)malloc(size); |
| |
| if(pMem != NULL) |
| { |
| memset(pMem, 0, size); |
| } |
| else |
| { |
| ALOGD("%s: memory allocation failed", fn); |
| } |
| return pMem; |
| } |
| |
| void JcopOsDwnld::FreeMemory(void *pMem) |
| { |
| if(pMem != NULL) |
| { |
| free(pMem); |
| pMem = NULL; |
| } |
| } |
| |
| #endif |