Home | History | Annotate | Download | only in src
      1  /*
      2   * Copyright (C) 2015 NXP Semiconductors
      3   *
      4   * Licensed under the Apache License, Version 2.0 (the "License");
      5   * you may not use this file except in compliance with the License.
      6   * You may obtain a copy of the License at
      7   *
      8   *      http://www.apache.org/licenses/LICENSE-2.0
      9   *
     10   * Unless required by applicable law or agreed to in writing, software
     11   * distributed under the License is distributed on an "AS IS" BASIS,
     12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13   * See the License for the specific language governing permissions and
     14   * limitations under the License.
     15   */
     16 #include <cutils/log.h>
     17 #include <semaphore.h>
     18 #include <AlaLib.h>
     19 #include <JcopOsDownload.h>
     20 #include <IChannel.h>
     21 #include <errno.h>
     22 #include <string.h>
     23 #include <unistd.h>
     24 #include <stdlib.h>
     25 #include <sys/stat.h>
     26 
     27 JcopOsDwnld JcopOsDwnld::sJcopDwnld;
     28 INT32 gTransceiveTimeout = 120000;
     29 
     30 tJBL_STATUS (JcopOsDwnld::*JcopOs_dwnld_seqhandler[])(
     31             JcopOs_ImageInfo_t* pContext, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pInfo)={
     32        &JcopOsDwnld::TriggerApdu,
     33        &JcopOsDwnld::GetInfo,
     34        &JcopOsDwnld::load_JcopOS_image,
     35        &JcopOsDwnld::GetInfo,
     36        &JcopOsDwnld::load_JcopOS_image,
     37        &JcopOsDwnld::GetInfo,
     38        &JcopOsDwnld::load_JcopOS_image,
     39        NULL
     40    };
     41 
     42 pJcopOs_Dwnld_Context_t gpJcopOs_Dwnld_Context = NULL;
     43 static const char *path[3] = {"/data/vendor/ese/JcopOs_Update1.apdu",
     44                              "/data/vendor/ese/JcopOs_Update2.apdu",
     45                              "/data/vendor/ese/JcopOs_Update3.apdu"};
     46 
     47 /*******************************************************************************
     48 **
     49 ** Function:        getInstance
     50 **
     51 ** Description:     Get the JcopOsDwnld singleton object.
     52 **
     53 ** Returns:         JcopOsDwnld object.
     54 **
     55 *******************************************************************************/
     56 JcopOsDwnld* JcopOsDwnld::getInstance()
     57 {
     58     JcopOsDwnld *jd = new JcopOsDwnld();
     59     return jd;
     60 }
     61 
     62 /*******************************************************************************
     63 **
     64 ** Function:        getJcopOsFileInfo
     65 **
     66 ** Description:     Verify all the updater files required for download
     67 **                  are present or not
     68 **
     69 ** Returns:         True if ok.
     70 **
     71 *******************************************************************************/
     72 bool JcopOsDwnld::getJcopOsFileInfo()
     73 {
     74     static const char fn [] = "JcopOsDwnld::getJcopOsFileInfo";
     75     bool status = true;
     76     struct stat st;
     77 
     78     for (int num = 0; num < 3; num++)
     79     {
     80         if (stat(path[num], &st))
     81         {
     82             status = false;
     83         }
     84     }
     85     return status;
     86 }
     87 
     88 /*******************************************************************************
     89 **
     90 ** Function:        initialize
     91 **
     92 ** Description:     Initialize all member variables.
     93 **                  native: Native data.
     94 **
     95 ** Returns:         True if ok.
     96 **
     97 *******************************************************************************/
     98 bool JcopOsDwnld::initialize (IChannel_t *channel)
     99 {
    100     static const char fn [] = "JcopOsDwnld::initialize";
    101 
    102     ALOGD ("%s: enter", fn);
    103 
    104     if (!getJcopOsFileInfo())
    105     {
    106         ALOGD("%s: insufficient resources, file not present", fn);
    107         return (false);
    108     }
    109     gpJcopOs_Dwnld_Context = (pJcopOs_Dwnld_Context_t)malloc(sizeof(JcopOs_Dwnld_Context_t));
    110     if(gpJcopOs_Dwnld_Context != NULL)
    111     {
    112         memset((void *)gpJcopOs_Dwnld_Context, 0, (UINT32)sizeof(JcopOs_Dwnld_Context_t));
    113         gpJcopOs_Dwnld_Context->channel = (IChannel_t*)malloc(sizeof(IChannel_t));
    114         if(gpJcopOs_Dwnld_Context->channel != NULL)
    115         {
    116             memset(gpJcopOs_Dwnld_Context->channel, 0, sizeof(IChannel_t));
    117         }
    118         else
    119         {
    120             ALOGD("%s: Memory allocation for IChannel is failed", fn);
    121             return (false);
    122         }
    123         gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = (UINT8*)malloc(sizeof(UINT8)*JCOP_MAX_BUF_SIZE);
    124         if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL)
    125         {
    126             memset(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData, 0, JCOP_MAX_BUF_SIZE);
    127         }
    128         else
    129         {
    130             ALOGD("%s: Memory allocation for SendBuf is failed", fn);
    131             return (false);
    132         }
    133     }
    134     else
    135     {
    136         ALOGD("%s: Memory allocation failed", fn);
    137         return (false);
    138     }
    139     mIsInit = true;
    140     memcpy(gpJcopOs_Dwnld_Context->channel, channel, sizeof(IChannel_t));
    141     ALOGD ("%s: exit", fn);
    142     return (true);
    143 }
    144 /*******************************************************************************
    145 **
    146 ** Function:        finalize
    147 **
    148 ** Description:     Release all resources.
    149 **
    150 ** Returns:         None
    151 **
    152 *******************************************************************************/
    153 void JcopOsDwnld::finalize ()
    154 {
    155     static const char fn [] = "JcopOsDwnld::finalize";
    156     ALOGD ("%s: enter", fn);
    157     mIsInit       = false;
    158     if(gpJcopOs_Dwnld_Context != NULL)
    159     {
    160         if(gpJcopOs_Dwnld_Context->channel != NULL)
    161         {
    162             free(gpJcopOs_Dwnld_Context->channel);
    163             gpJcopOs_Dwnld_Context->channel = NULL;
    164         }
    165         if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL)
    166         {
    167             free(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData);
    168             gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = NULL;
    169         }
    170         free(gpJcopOs_Dwnld_Context);
    171         gpJcopOs_Dwnld_Context = NULL;
    172     }
    173     ALOGD ("%s: exit", fn);
    174 }
    175 
    176 /*******************************************************************************
    177 **
    178 ** Function:        JcopOs_Download
    179 **
    180 ** Description:     Starts the OS download sequence
    181 **
    182 ** Returns:         Success if ok.
    183 **
    184 *******************************************************************************/
    185 tJBL_STATUS JcopOsDwnld::JcopOs_Download()
    186 {
    187     static const char fn [] = "JcopOsDwnld::JcopOs_Download";
    188     tJBL_STATUS wstatus = STATUS_FAILED;
    189     JcopOs_TranscieveInfo_t pTranscv_Info;
    190     JcopOs_ImageInfo_t ImageInfo;
    191     UINT8 retry_cnt = 0x00;
    192     ALOGD("%s: enter:", fn);
    193     if(mIsInit == false)
    194     {
    195         ALOGD ("%s: JcopOs Dwnld is not initialized", fn);
    196         wstatus = STATUS_FAILED;
    197     }
    198     else
    199     {
    200         do
    201         {
    202             wstatus = JcopOsDwnld::JcopOs_update_seq_handler();
    203             if(wstatus == STATUS_FAILED)
    204                 retry_cnt++;
    205             else
    206                 break;
    207         }while(retry_cnt < JCOP_MAX_RETRY_CNT);
    208     }
    209     ALOGD("%s: exit; status = 0x%x", fn, wstatus);
    210     return wstatus;
    211 }
    212 /*******************************************************************************
    213 **
    214 ** Function:        JcopOs_update_seq_handler
    215 **
    216 ** Description:     Performs the JcopOS download sequence
    217 **
    218 ** Returns:         Success if ok.
    219 **
    220 *******************************************************************************/
    221 tJBL_STATUS JcopOsDwnld::JcopOs_update_seq_handler()
    222 {
    223     static const char fn[] = "JcopOsDwnld::JcopOs_update_seq_handler";
    224     UINT8 seq_counter = 0;
    225     JcopOs_ImageInfo_t update_info = (JcopOs_ImageInfo_t )gpJcopOs_Dwnld_Context->Image_info;
    226     JcopOs_TranscieveInfo_t trans_info = (JcopOs_TranscieveInfo_t )gpJcopOs_Dwnld_Context->pJcopOs_TransInfo;
    227     update_info.index = 0x00;
    228     update_info.cur_state = 0x00;
    229     tJBL_STATUS status = STATUS_FAILED;
    230 
    231     ALOGD("%s: enter", fn);
    232     status = GetJcopOsState(&update_info, &seq_counter);
    233     if(status != STATUS_SUCCESS)
    234     {
    235         ALOGE("Error in getting JcopOsState info");
    236     }
    237     else
    238     {
    239         ALOGE("seq_counter %d", seq_counter);
    240         while((JcopOs_dwnld_seqhandler[seq_counter]) != NULL )
    241         {
    242             status = STATUS_FAILED;
    243             status = (*this.*(JcopOs_dwnld_seqhandler[seq_counter]))(&update_info, status, &trans_info );
    244             if(STATUS_SUCCESS != status)
    245             {
    246                 ALOGE("%s: exiting; status=0x0%X", fn, status);
    247                 break;
    248             }
    249             seq_counter++;
    250         }
    251     }
    252     return status;
    253 }
    254 
    255 /*******************************************************************************
    256 **
    257 ** Function:        TriggerApdu
    258 **
    259 ** Description:     Switch to updater OS
    260 **
    261 ** Returns:         Success if ok.
    262 **
    263 *******************************************************************************/
    264 tJBL_STATUS JcopOsDwnld::TriggerApdu(JcopOs_ImageInfo_t* pVersionInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info)
    265 {
    266     static const char fn [] = "JcopOsDwnld::TriggerApdu";
    267     bool stat = false;
    268     IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
    269     INT32 recvBufferActualSize = 0;
    270 
    271     ALOGD("%s: enter;", fn);
    272 
    273     if(pTranscv_Info == NULL ||
    274        pVersionInfo == NULL)
    275     {
    276         ALOGD("%s: Invalid parameter", fn);
    277         status = STATUS_FAILED;
    278     }
    279     else
    280     {
    281         pTranscv_Info->timeout = gTransceiveTimeout;
    282         pTranscv_Info->sSendlength = (INT32)sizeof(Trigger_APDU);
    283         pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
    284         memcpy(pTranscv_Info->sSendData, Trigger_APDU, pTranscv_Info->sSendlength);
    285 
    286         ALOGD("%s: Calling Secure Element Transceive", fn);
    287         stat = mchannel->transceive (pTranscv_Info->sSendData,
    288                                 pTranscv_Info->sSendlength,
    289                                 pTranscv_Info->sRecvData,
    290                                 pTranscv_Info->sRecvlength,
    291                                 recvBufferActualSize,
    292                                 pTranscv_Info->timeout);
    293         if (stat != true)
    294         {
    295             status = STATUS_FAILED;
    296             ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update
    297         }
    298         else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x68) &&
    299                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x81))||
    300                ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
    301                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))||
    302                ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F) &&
    303                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
    304         {
    305             mchannel->doeSE_JcopDownLoadReset();
    306             status = STATUS_OK;
    307             ALOGD("%s: Trigger APDU Transceive status = 0x%X", fn, status);
    308         }
    309         else
    310         {
    311             /* status {90, 00} */
    312             status = STATUS_OK;
    313         }
    314     }
    315     ALOGD("%s: exit; status = 0x%X", fn, status);
    316     return status;
    317 }
    318 /*******************************************************************************
    319 **
    320 ** Function:        GetInfo
    321 **
    322 ** Description:     Get the JCOP OS info
    323 **
    324 ** Returns:         Success if ok.
    325 **
    326 *******************************************************************************/
    327 tJBL_STATUS JcopOsDwnld::GetInfo(JcopOs_ImageInfo_t* pImageInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info)
    328 {
    329     static const char fn [] = "JcopOsDwnld::GetInfo";
    330 
    331     bool stat = false;
    332     IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
    333     INT32 recvBufferActualSize = 0;
    334 
    335     ALOGD("%s: enter;", fn);
    336 
    337     if(pTranscv_Info == NULL ||
    338        pImageInfo == NULL)
    339     {
    340         ALOGD("%s: Invalid parameter", fn);
    341         status = STATUS_FAILED;
    342     }
    343     else
    344     {
    345         memcpy(pImageInfo->fls_path, (char *)path[pImageInfo->index], strlen(path[pImageInfo->index]));
    346 
    347         memset(pTranscv_Info->sSendData, 0, JCOP_MAX_BUF_SIZE);
    348         pTranscv_Info->timeout = gTransceiveTimeout;
    349         pTranscv_Info->sSendlength = (UINT32)sizeof(GetInfo_APDU);
    350         pTranscv_Info->sRecvlength = 1024;
    351         memcpy(pTranscv_Info->sSendData, GetInfo_APDU, pTranscv_Info->sSendlength);
    352 
    353         ALOGD("%s: Calling Secure Element Transceive", fn);
    354         stat = mchannel->transceive (pTranscv_Info->sSendData,
    355                                 pTranscv_Info->sSendlength,
    356                                 pTranscv_Info->sRecvData,
    357                                 pTranscv_Info->sRecvlength,
    358                                 recvBufferActualSize,
    359                                 pTranscv_Info->timeout);
    360         if (stat != true)
    361         {
    362             status = STATUS_FAILED;
    363             pImageInfo->index =0;
    364             ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update
    365         }
    366         else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
    367                 (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
    368         {
    369             pImageInfo->version_info.osid = pTranscv_Info->sRecvData[recvBufferActualSize-6];
    370             pImageInfo->version_info.ver1 = pTranscv_Info->sRecvData[recvBufferActualSize-5];
    371             pImageInfo->version_info.ver0 = pTranscv_Info->sRecvData[recvBufferActualSize-4];
    372             pImageInfo->version_info.OtherValid = pTranscv_Info->sRecvData[recvBufferActualSize-3];
    373 #if 0
    374             if((pImageInfo->index != 0) &&
    375                (pImageInfo->version_info.osid == 0x01) &&
    376                (pImageInfo->version_info.OtherValid == 0x11))
    377             {
    378                 ALOGE("3-Step update is not required");
    379                 memset(pImageInfo->fls_path,0,sizeof(pImageInfo->fls_path));
    380                 pImageInfo->index=0;
    381             }
    382             else
    383 #endif
    384             {
    385                 ALOGE("Starting 3-Step update");
    386                 memcpy(pImageInfo->fls_path, (char *)path[pImageInfo->index], sizeof(path[pImageInfo->index]));
    387                 pImageInfo->index++;
    388             }
    389             status = STATUS_OK;
    390             ALOGD("%s: GetInfo Transceive status = 0x%X", fn, status);
    391         }
    392         else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6A) &&
    393                 (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x82) &&
    394                  pImageInfo->version_info.ver_status == STATUS_UPTO_DATE)
    395         {
    396             status = STATUS_UPTO_DATE;
    397         }
    398         else
    399         {
    400             status = STATUS_FAILED;
    401             ALOGD("%s; Invalid response for GetInfo", fn);
    402         }
    403     }
    404 
    405     if (status == STATUS_FAILED)
    406     {
    407         ALOGD("%s; status failed, doing reset...", fn);
    408         mchannel->doeSE_JcopDownLoadReset();
    409     }
    410     ALOGD("%s: exit; status = 0x%X", fn, status);
    411     return status;
    412 }
    413 /*******************************************************************************
    414 **
    415 ** Function:        load_JcopOS_image
    416 **
    417 ** Description:     Used to update the JCOP OS
    418 **                  Get Info function has to be called before this
    419 **
    420 ** Returns:         Success if ok.
    421 **
    422 *******************************************************************************/
    423 tJBL_STATUS JcopOsDwnld::load_JcopOS_image(JcopOs_ImageInfo_t *Os_info, tJBL_STATUS status, JcopOs_TranscieveInfo_t *pTranscv_Info)
    424 {
    425     static const char fn [] = "JcopOsDwnld::load_JcopOS_image";
    426     bool stat = false;
    427     int wResult, size =0;
    428     INT32 wIndex,wCount=0;
    429     INT32 wLen;
    430 
    431     IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
    432     INT32 recvBufferActualSize = 0;
    433     ALOGD("%s: enter", fn);
    434     if(Os_info == NULL ||
    435        pTranscv_Info == NULL)
    436     {
    437         ALOGE("%s: invalid parameter", fn);
    438         return status;
    439     }
    440     Os_info->fp = fopen(Os_info->fls_path, "r+");
    441 
    442     if (Os_info->fp == NULL) {
    443         ALOGE("Error opening OS image file <%s> for reading: %s",
    444                     Os_info->fls_path, strerror(errno));
    445         return STATUS_FILE_NOT_FOUND;
    446     }
    447     wResult = fseek(Os_info->fp, 0L, SEEK_END);
    448     if (wResult) {
    449         ALOGE("Error seeking end OS image file %s", strerror(errno));
    450         goto exit;
    451     }
    452     Os_info->fls_size = ftell(Os_info->fp);
    453     if (Os_info->fls_size < 0) {
    454         ALOGE("Error ftelling file %s", strerror(errno));
    455         goto exit;
    456     }
    457     wResult = fseek(Os_info->fp, 0L, SEEK_SET);
    458     if (wResult) {
    459         ALOGE("Error seeking start image file %s", strerror(errno));
    460         goto exit;
    461     }
    462     while(!feof(Os_info->fp))
    463     {
    464         ALOGE("%s; Start of line processing", fn);
    465 
    466         wIndex=0;
    467         wLen=0;
    468         wCount=0;
    469         memset(pTranscv_Info->sSendData,0x00,JCOP_MAX_BUF_SIZE);
    470         pTranscv_Info->sSendlength=0;
    471 
    472         ALOGE("%s; wIndex = 0", fn);
    473         for(wCount =0; (wCount < 5 && !feof(Os_info->fp)); wCount++, wIndex++)
    474         {
    475             wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]);
    476         }
    477         if(wResult != 0)
    478         {
    479             wLen = pTranscv_Info->sSendData[4];
    480             ALOGE("%s; Read 5byes success & len=%d", fn,wLen);
    481             if(wLen == 0x00)
    482             {
    483                 ALOGE("%s: Extended APDU", fn);
    484                 wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]);
    485                 wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]);
    486                 wLen = ((pTranscv_Info->sSendData[5] << 8) | (pTranscv_Info->sSendData[6]));
    487             }
    488             for(wCount =0; (wCount < wLen && !feof(Os_info->fp)); wCount++, wIndex++)
    489             {
    490                 wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]);
    491             }
    492         }
    493         else
    494         {
    495             ALOGE("%s: JcopOs image Read failed", fn);
    496             goto exit;
    497         }
    498 
    499         pTranscv_Info->sSendlength = wIndex;
    500         ALOGE("%s: start transceive for length %d", fn, pTranscv_Info->sSendlength);
    501         if((pTranscv_Info->sSendlength != 0x03) &&
    502            (pTranscv_Info->sSendData[0] != 0x00) &&
    503            (pTranscv_Info->sSendData[1] != 0x00))
    504         {
    505 
    506             stat = mchannel->transceive(pTranscv_Info->sSendData,
    507                                     pTranscv_Info->sSendlength,
    508                                     pTranscv_Info->sRecvData,
    509                                     pTranscv_Info->sRecvlength,
    510                                     recvBufferActualSize,
    511                                     pTranscv_Info->timeout);
    512         }
    513         else
    514         {
    515             ALOGE("%s: Invalid packet", fn);
    516             continue;
    517         }
    518         if(stat != true)
    519         {
    520             ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
    521             status = STATUS_FAILED;
    522             goto exit;
    523         }
    524         else if(recvBufferActualSize != 0 &&
    525                 pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90 &&
    526                 pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)
    527         {
    528             //ALOGE("%s: END transceive for length %d", fn, pTranscv_Info->sSendlength);
    529             status = STATUS_SUCCESS;
    530         }
    531         else if(pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F &&
    532                 pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)
    533         {
    534             ALOGE("%s: JcopOs is already upto date-No update required exiting", fn);
    535             Os_info->version_info.ver_status = STATUS_UPTO_DATE;
    536             status = STATUS_FAILED;
    537             break;
    538         }
    539         else
    540         {
    541             status = STATUS_FAILED;
    542             ALOGE("%s: Invalid response", fn);
    543             goto exit;
    544         }
    545         ALOGE("%s: Going for next line", fn);
    546     }
    547 
    548     if(status == STATUS_SUCCESS)
    549     {
    550         Os_info->cur_state++;
    551         SetJcopOsState(Os_info, Os_info->cur_state);
    552     }
    553 
    554 exit:
    555     mchannel->doeSE_JcopDownLoadReset();
    556     ALOGE("%s close fp and exit; status= 0x%X", fn,status);
    557     wResult = fclose(Os_info->fp);
    558     return status;
    559 }
    560 
    561 /*******************************************************************************
    562 **
    563 ** Function:        GetJcopOsState
    564 **
    565 ** Description:     Used to update the JCOP OS state
    566 **
    567 ** Returns:         Success if ok.
    568 **
    569 *******************************************************************************/
    570 tJBL_STATUS JcopOsDwnld::GetJcopOsState(JcopOs_ImageInfo_t *Os_info, UINT8 *counter)
    571 {
    572     static const char fn [] = "JcopOsDwnld::GetJcopOsState";
    573     tJBL_STATUS status = STATUS_SUCCESS;
    574     FILE *fp;
    575     UINT8 xx=0;
    576     ALOGD("%s: enter", fn);
    577     if(Os_info == NULL)
    578     {
    579         ALOGE("%s: invalid parameter", fn);
    580         return STATUS_FAILED;
    581     }
    582     fp = fopen(JCOP_INFO_PATH, "r");
    583 
    584     if (fp == NULL) {
    585         ALOGE("file <%s> not exits for reading- creating new file: %s",
    586                 JCOP_INFO_PATH, strerror(errno));
    587         fp = fopen(JCOP_INFO_PATH, "w+");
    588         if (fp == NULL)
    589         {
    590             ALOGE("Error opening OS image file <%s> for reading: %s",
    591                     JCOP_INFO_PATH, strerror(errno));
    592             return STATUS_FAILED;
    593         }
    594         fprintf(fp, "%u", xx);
    595         fclose(fp);
    596     }
    597     else
    598     {
    599         FSCANF_BYTE(fp, "%u", &xx);
    600         ALOGE("JcopOsState %d", xx);
    601         fclose(fp);
    602     }
    603 
    604     switch(xx)
    605     {
    606     case JCOP_UPDATE_STATE0:
    607     case JCOP_UPDATE_STATE3:
    608         ALOGE("Starting update from step1");
    609         Os_info->index = JCOP_UPDATE_STATE0;
    610         Os_info->cur_state = JCOP_UPDATE_STATE0;
    611         *counter = 0;
    612         break;
    613     case JCOP_UPDATE_STATE1:
    614         ALOGE("Starting update from step2");
    615         Os_info->index = JCOP_UPDATE_STATE1;
    616         Os_info->cur_state = JCOP_UPDATE_STATE1;
    617         *counter = 3;
    618         break;
    619     case JCOP_UPDATE_STATE2:
    620         ALOGE("Starting update from step3");
    621         Os_info->index = JCOP_UPDATE_STATE2;
    622         Os_info->cur_state = JCOP_UPDATE_STATE2;
    623         *counter = 5;
    624         break;
    625     default:
    626         ALOGE("invalid state");
    627         status = STATUS_FAILED;
    628         break;
    629     }
    630     return status;
    631 }
    632 
    633 /*******************************************************************************
    634 **
    635 ** Function:        SetJcopOsState
    636 **
    637 ** Description:     Used to set the JCOP OS state
    638 **
    639 ** Returns:         Success if ok.
    640 **
    641 *******************************************************************************/
    642 tJBL_STATUS JcopOsDwnld::SetJcopOsState(JcopOs_ImageInfo_t *Os_info, UINT8 state)
    643 {
    644     static const char fn [] = "JcopOsDwnld::SetJcopOsState";
    645     tJBL_STATUS status = STATUS_FAILED;
    646     FILE *fp;
    647     ALOGD("%s: enter", fn);
    648     if(Os_info == NULL)
    649     {
    650         ALOGE("%s: invalid parameter", fn);
    651         return status;
    652     }
    653     fp = fopen(JCOP_INFO_PATH, "w");
    654 
    655     if (fp == NULL) {
    656         ALOGE("Error opening OS image file <%s> for reading: %s",
    657                 JCOP_INFO_PATH, strerror(errno));
    658     }
    659     else
    660     {
    661         fprintf(fp, "%u", state);
    662         fflush(fp);
    663         ALOGE("Current JcopOsState: %d", state);
    664         status = STATUS_SUCCESS;
    665     int fd=fileno(fp);
    666     int ret = fdatasync(fd);
    667         ALOGE("ret value: %d", ret);
    668         fclose(fp);
    669     }
    670     return status;
    671 }
    672 
    673 #if 0
    674 void *JcopOsDwnld::GetMemory(UINT32 size)
    675 {
    676     void *pMem;
    677     static const char fn [] = "JcopOsDwnld::GetMemory";
    678     pMem = (void *)malloc(size);
    679 
    680     if(pMem != NULL)
    681     {
    682         memset(pMem, 0, size);
    683     }
    684     else
    685     {
    686         ALOGD("%s: memory allocation failed", fn);
    687     }
    688     return pMem;
    689 }
    690 
    691 void JcopOsDwnld::FreeMemory(void *pMem)
    692 {
    693     if(pMem != NULL)
    694     {
    695         free(pMem);
    696         pMem = NULL;
    697     }
    698 }
    699 
    700 #endif
    701