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 <log/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 *******************************************************************************/
getInstance()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 *******************************************************************************/
getJcopOsFileInfo()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 *******************************************************************************/
initialize(IChannel_t * channel)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 *******************************************************************************/
finalize()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 *******************************************************************************/
JcopOs_Download()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 *******************************************************************************/
JcopOs_update_seq_handler()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 *******************************************************************************/
TriggerApdu(JcopOs_ImageInfo_t * pVersionInfo,tJBL_STATUS status,JcopOs_TranscieveInfo_t * pTranscv_Info)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 *******************************************************************************/
GetInfo(JcopOs_ImageInfo_t * pImageInfo,tJBL_STATUS status,JcopOs_TranscieveInfo_t * pTranscv_Info)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 *******************************************************************************/
load_JcopOS_image(JcopOs_ImageInfo_t * Os_info,tJBL_STATUS status,JcopOs_TranscieveInfo_t * pTranscv_Info)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 *******************************************************************************/
GetJcopOsState(JcopOs_ImageInfo_t * Os_info,UINT8 * counter)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 *******************************************************************************/
SetJcopOsState(JcopOs_ImageInfo_t * Os_info,UINT8 state)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