1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hota_updater.h"
17 
18 #include <stdbool.h>
19 #include <stdio.h>
20 
21 #include <securec.h>
22 
23 #include "hal_hota_board.h"
24 #include "hota_verify.h"
25 #include "parameter.h"
26 
27 #define HASH_LENGTH 32
28 #define SIGN_DATA_LEN 640
29 #define COMP_VERSION_LENGTH 10
30 #define PKG_VERSION_LENGTH 64
31 #define PRODUCT_ID_LENGTH 64
32 
33 #define OTA_MAX_PARTITION_NUM 10
34 #define COMPONENT_INFO_START 176
35 #define COMPONENT_INFO_TYPE_SIZE 2
36 #define COMPONENT_INFO_HEADER_LENGTH 4
37 
38 #define MAX_BUFFER_SIZE 1500
39 #define MAX_TRANSPORT_BUFF_SIZE (4 * 1024)
40 #ifndef ARRAY_SIZE
41 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
42 #endif
43 
44 // Currently downloading component information
45 typedef struct {
46     unsigned char isInfoComp; /* 1: information component,0: non-information component */
47     unsigned int currentSize; /* Currently downloaded size of the component */
48     unsigned int index;       /* order of this component  */
49     unsigned int remainSize;  /* remain size of this component */
50     unsigned int totalSize;   /* total size of this component */
51     unsigned int offset;      /*  offset of this component */
52 } CurrentDloadComp;
53 
54 #pragma pack(1)
55 typedef struct {
56     unsigned short type;
57     unsigned short length;
58     unsigned int infoCompSize;
59     unsigned int upgradePkgVersion;
60     char productId[PRODUCT_ID_LENGTH];
61     char version[PKG_VERSION_LENGTH];
62 } PkgBasicInfo;
63 #pragma pack()
64 
65 #pragma pack(1)
66 typedef struct {
67     unsigned char addr[PARTITION_NAME_LENGTH];  /* partition name */
68     unsigned short id;                          /* component ID */
69     unsigned char type;                         /* component type */
70     unsigned char operType;                     /* component operation type. 0: need upgrade 1: need delete */
71     unsigned char isDiff;                       /* Is Diff component */
72     unsigned char version[COMP_VERSION_LENGTH]; /* version of component */
73     unsigned int length;                        /* size of component. if it is diff component,
74                                                 this mean diff component image size. */
75     unsigned int destLength;                    /* size of component. if it is diff component,
76                                                 this mean total component image size after diff reduction. */
77     unsigned char shaData[HASH_LENGTH];
78 } ComponentInfo;
79 #pragma pack()
80 
81 typedef struct {
82     ComponentInfo table[OTA_MAX_PARTITION_NUM];
83 } ComponentInfos;
84 
85 typedef struct {
86     void (*ErrorCallBackFunc)(HotaErrorCode errorCode);
87     void (*StatusCallBackFunc)(HotaStatus status);
88 } HotaNotifier;
89 
90 static HotaStatus g_otaStatus = HOTA_NOT_INIT;
91 static unsigned short g_allComponentNum = 0;
92 static unsigned short g_allComponentSize = 0;
93 static unsigned short g_recvComponentNum = 0;
94 static unsigned short g_infoCompAndSignSize;        /* the size of Info Component */
95 static CurrentDloadComp g_currentDloadComp = { 0 }; /* Currently downloading component information */
96 static ComponentInfos g_componentInfos = { 0 };
97 static HotaNotifier g_otaNotifier = { 0 };    /* OTA Notifier, notify caller when error or status changed */
98 static unsigned int g_useDefaultPkgFlag = 1; /* Use default Pkg format flag. default use it. */
99 static unsigned char *g_infoCompBuff = NULL;        /* info component buffer */
100 static ComponentTableInfo *g_otaComponents = NULL;    /* ota partitions info */
101 static unsigned int g_signDataLen = 0;    /* sign data len */
102 static unsigned int g_signStartAddr = 0;  /* sign start address */
103 
104 
HotaResetStatus(void)105 static void HotaResetStatus(void)
106 {
107     g_otaStatus = HOTA_NOT_INIT;
108     g_allComponentNum = 0;
109     g_allComponentSize = 0;
110     g_recvComponentNum = 0;
111     g_infoCompAndSignSize = 0;
112     (void)memset_s(&g_currentDloadComp, sizeof(g_currentDloadComp), 0, sizeof(g_currentDloadComp));
113     (void)memset_s(&g_componentInfos, sizeof(g_componentInfos), 0, sizeof(g_componentInfos));
114     (void)memset_s(&g_otaNotifier, sizeof(g_otaNotifier), 0, sizeof(g_otaNotifier));
115     g_useDefaultPkgFlag = 1;
116     g_infoCompBuff = NULL;
117 }
118 
119 // refresh ota status
UpdateStatus(HotaStatus status)120 static void UpdateStatus(HotaStatus status)
121 {
122     if (status == g_otaStatus) {
123         return;
124     }
125 
126     if (status == HOTA_CANCELED || status == HOTA_FAILED ||
127         status == HOTA_TRANSPORT_ALL_DONE) {
128         if (g_infoCompBuff != NULL) {
129             free(g_infoCompBuff);
130             g_infoCompBuff = NULL;
131         }
132     }
133 
134     UpdateMetaData data = {0};
135     HotaHalGetMetaData(&data);
136     g_otaStatus = status;
137     data.otaStatus = status;
138     HotaHalSetMetaData(&data);
139     if (g_otaNotifier.StatusCallBackFunc != NULL) {
140         g_otaNotifier.StatusCallBackFunc(status);
141     }
142 }
143 
ReportErrorCode(HotaErrorCode errorCode)144 static void ReportErrorCode(HotaErrorCode errorCode)
145 {
146     if (g_otaNotifier.ErrorCallBackFunc != NULL) {
147         g_otaNotifier.ErrorCallBackFunc(errorCode);
148     }
149 }
150 
IsDigest(const char * str)151 static bool IsDigest(const char *str)
152 {
153     const unsigned int len = strlen(str);
154     for (unsigned int i = 0; i < len; i++) {
155         if (str[i] < '0' || str[i] > '9') {
156             return false;
157         }
158     }
159 
160     return true;
161 }
162 
IsLatestVersion(const char * pkgVersion,const char * currentVersion)163 static bool IsLatestVersion(const char *pkgVersion, const char *currentVersion)
164 {
165     char pkgVerCopy[PKG_VERSION_LENGTH] = {0};
166     char currentVerCopy[PKG_VERSION_LENGTH] = {0};
167     char *currentVerSplit = NULL;
168     char *pkgVerSplit = NULL;
169     char *currentVerTemp = NULL;
170     char *pkgVerTemp = NULL;
171     char split[] = ".| ";
172     int ret = strcpy_s(pkgVerCopy, PKG_VERSION_LENGTH, pkgVersion);
173     ret += strcpy_s(currentVerCopy, PKG_VERSION_LENGTH, currentVersion);
174     if (ret != 0) {
175         return false;
176     }
177 
178     bool isLatest = true;
179     currentVerSplit = strtok_s(currentVerCopy, split, &currentVerTemp);
180     pkgVerSplit = strtok_s(pkgVerCopy, split, &pkgVerTemp);
181     while (pkgVerSplit != NULL && currentVerSplit != NULL) {
182         if (IsDigest(pkgVerSplit) && IsDigest(currentVerSplit)) {
183             if (atoi(pkgVerSplit) < atoi(currentVerSplit)) {
184                 isLatest = false;
185                 break;
186             } else if (atoi(pkgVerSplit) > atoi(currentVerSplit)) {
187                 isLatest = true;
188                 break;
189             }
190         } else if (strncmp(pkgVerSplit, currentVerSplit, PKG_VERSION_LENGTH) != EOK) {
191             isLatest = false;
192             break;
193         }
194 
195         currentVerSplit = strtok_s(NULL, split, &currentVerTemp);
196         pkgVerSplit = strtok_s(NULL, split, &pkgVerTemp);
197     }
198 
199     if (isLatest && strncmp(currentVersion, pkgVersion, PKG_VERSION_LENGTH) == EOK) {
200         isLatest = false;
201     }
202 
203     if (!isLatest) {
204         isLatest = HotaHalCheckVersionValid(currentVersion, pkgVersion, PKG_VERSION_LENGTH) ? true : false;
205     }
206 
207     return isLatest;
208 }
209 
CheckPkgVersionValid(const char * pkgVersion)210 static int CheckPkgVersionValid(const char *pkgVersion)
211 {
212     if (pkgVersion == NULL) {
213         return OHOS_FAILURE;
214     }
215     const char *currentVersion = GetIncrementalVersion();
216     if (currentVersion == NULL) {
217         return OHOS_FAILURE;
218     }
219 
220     if (!IsLatestVersion(pkgVersion, currentVersion)) {
221         printf("pkgVersion is valid\r\n");
222         return OHOS_FAILURE;
223     }
224     return OHOS_SUCCESS;
225 }
226 
ParseHotaInfoComponent(unsigned char * infoCompBuffer,unsigned short bufLen)227 static int ParseHotaInfoComponent(unsigned char *infoCompBuffer, unsigned short bufLen)
228 {
229     if (infoCompBuffer == NULL || g_signDataLen == 0) {
230         return OHOS_FAILURE;
231     }
232 
233     if (bufLen <= SIGN_DATA_LEN) {
234         printf("buffLen is invalid.\r\n");
235         return OHOS_FAILURE;
236     }
237 
238     unsigned char *infoHeaderBuf = (unsigned char *)malloc(bufLen - SIGN_DATA_LEN);
239     if (infoHeaderBuf == NULL) {
240         printf("malloc infoHeaderBuf failed.\r\n");
241         return OHOS_FAILURE;
242     }
243     if (memcpy_s(infoHeaderBuf, bufLen - SIGN_DATA_LEN, infoCompBuffer, bufLen - SIGN_DATA_LEN) != EOK) {
244         free(infoHeaderBuf);
245         return OHOS_FAILURE;
246     }
247 
248     if (HotaSignVerify(infoHeaderBuf, bufLen - SIGN_DATA_LEN,
249         infoCompBuffer + (bufLen - g_signStartAddr), g_signDataLen)) {
250         UpdateStatus(HOTA_FAILED);
251         ReportErrorCode(HOTA_DATA_SIGN_CHECK_ERR);
252         printf("Verify file failed.\r\n");
253         free(infoHeaderBuf);
254         return OHOS_FAILURE;
255     }
256 
257     free(infoHeaderBuf);
258     if (memcpy_s(&g_allComponentSize, sizeof(g_allComponentSize),
259         infoCompBuffer + COMPONENT_INFO_START + COMPONENT_INFO_TYPE_SIZE, sizeof(g_allComponentSize)) != EOK) {
260         return OHOS_FAILURE;
261     }
262     g_allComponentNum = g_allComponentSize / sizeof(ComponentInfo);
263     if (g_allComponentNum > OTA_MAX_PARTITION_NUM) {
264         return OHOS_FAILURE;
265     }
266 
267     unsigned int pos = COMPONENT_INFO_START + COMPONENT_INFO_HEADER_LENGTH;
268     for (unsigned int i = 0; i < g_allComponentNum; i++) {
269         if (memcpy_s(g_componentInfos.table + i, sizeof(g_componentInfos.table[i]), infoCompBuffer + pos,
270             sizeof(g_componentInfos.table[i])) != EOK) {
271             return OHOS_FAILURE;
272         }
273         pos += sizeof(ComponentInfo);
274     }
275     if (HotaHalWrite(PARTITION_INFO_COMP, infoCompBuffer, 0, bufLen) != OHOS_SUCCESS) {
276         printf("HotaHalWrite  failed, partition = PARTITION_INFO_COMP.\r\n");
277         ReportErrorCode(HOTA_DATA_WRITE_ERR);
278         UpdateStatus(HOTA_FAILED);
279         return OHOS_FAILURE;
280     }
281     UpdateStatus(HOTA_TRANSPORT_INFO_DONE);
282     return OHOS_SUCCESS;
283 }
284 
InitDloadNextComp(unsigned int currentOffset)285 static int InitDloadNextComp(unsigned int currentOffset)
286 {
287     unsigned char tempIndex = g_currentDloadComp.index;
288     if (memset_s(&g_currentDloadComp, sizeof(g_currentDloadComp), 0, sizeof(g_currentDloadComp)) != EOK) {
289         UpdateStatus(HOTA_FAILED);
290         printf("memset_s failed.\r\n");
291         return OHOS_FAILURE;
292     }
293     g_currentDloadComp.isInfoComp = false;
294     g_currentDloadComp.currentSize = 0;
295     g_currentDloadComp.index = tempIndex + 1;
296     g_currentDloadComp.offset = currentOffset;
297 
298     if (g_currentDloadComp.index - 1 >= OTA_MAX_PARTITION_NUM) {
299         UpdateStatus(HOTA_FAILED);
300         printf("the index of g_componentInfos.table is out of range.\r\n");
301         return OHOS_FAILURE;
302     }
303 
304     g_currentDloadComp.totalSize = g_componentInfos.table[g_currentDloadComp.index - 1].length;
305     g_currentDloadComp.remainSize = g_currentDloadComp.totalSize;
306     HotaHashInit();
307     return OHOS_SUCCESS;
308 }
309 
ParseHotaComponent(void)310 static int ParseHotaComponent(void)
311 {
312     unsigned char hashOut[HASH_LENGTH] = {0};
313     HotaGetHash(hashOut, HASH_LENGTH);
314 
315     if (g_currentDloadComp.index - 1 >= OTA_MAX_PARTITION_NUM) {
316         UpdateStatus(HOTA_FAILED);
317         printf("the index of g_componentInfos.table is out of range.\r\n");
318         return OHOS_FAILURE;
319     }
320 
321     // Check hash is or not same
322     if (memcmp(hashOut, g_componentInfos.table[g_currentDloadComp.index - 1].shaData, HASH_LENGTH) != EOK) {
323         UpdateStatus(HOTA_FAILED);
324         ReportErrorCode(HOTA_DATA_VERIFY_HASH_ERR);
325         printf("Verify hash failed. package maybe be damaged!\r\n");
326         return OHOS_FAILURE;
327     }
328 
329     g_recvComponentNum++;
330     return OHOS_SUCCESS;
331 }
332 
HotaIsRejected(void)333 static bool HotaIsRejected(void)
334 {
335     return (g_otaStatus == HOTA_CANCELED || g_otaStatus == HOTA_FAILED);
336 }
337 
ProcessInfoCompHeader(const unsigned char * infoCompBuffer,unsigned int bufLen)338 static int ProcessInfoCompHeader(const unsigned char *infoCompBuffer, unsigned int bufLen)
339 {
340     if (infoCompBuffer == NULL) {
341         return OHOS_FAILURE;
342     }
343 
344     if (bufLen < sizeof(PkgBasicInfo)) {
345         UpdateStatus(HOTA_FAILED);
346         printf("buffLen is illegal.\r\n");
347         return OHOS_FAILURE;
348     }
349     PkgBasicInfo basicInfo = { 0 };
350     if (memcpy_s(&basicInfo, sizeof(PkgBasicInfo), infoCompBuffer, sizeof(PkgBasicInfo)) != EOK) {
351         UpdateStatus(HOTA_FAILED);
352         printf("memcpy_s basicInfo failed.\r\n");
353         return OHOS_FAILURE;
354     }
355 
356     if (basicInfo.infoCompSize < sizeof(PkgBasicInfo)) {
357         return OHOS_FAILURE;
358     }
359 
360     // version check, only allow upgrade with higher version.
361     if (CheckPkgVersionValid(basicInfo.version) != OHOS_SUCCESS) {
362         UpdateStatus(HOTA_FAILED);
363         ReportErrorCode(HOTA_VERSION_INVALID);
364         printf("CheckPkgVersionValid failed. Pkg version: %s\r\n", basicInfo.version);
365         return OHOS_FAILURE;
366     }
367 
368     if (basicInfo.type == SIGN_ARITHMETIC_RSA2048) {
369         g_signDataLen = SIGN_RSA2048_LEN;
370         g_signStartAddr = SIGN_DATA_LEN;
371     } else if (basicInfo.type == SIGN_ARITHMETIC_RSA3072) {
372         g_signDataLen = SIGN_RSA3072_LEN;
373         g_signStartAddr = SIGN_RSA3072_LEN;
374     }
375     g_infoCompAndSignSize = basicInfo.infoCompSize + SIGN_DATA_LEN;
376     g_currentDloadComp.isInfoComp = true;
377     g_currentDloadComp.offset = 0;
378     g_currentDloadComp.index = 0;
379     g_currentDloadComp.currentSize = sizeof(PkgBasicInfo);
380     g_currentDloadComp.totalSize = g_infoCompAndSignSize;
381     if (g_infoCompAndSignSize < sizeof(PkgBasicInfo)) {
382         return OHOS_FAILURE;
383     }
384     g_currentDloadComp.remainSize = g_infoCompAndSignSize - sizeof(PkgBasicInfo);
385     return OHOS_SUCCESS;
386 }
387 
DloadIsDone(void)388 static bool DloadIsDone(void)
389 {
390     if ((g_allComponentNum != 0) && (g_recvComponentNum >= g_allComponentNum) &&
391         (!g_currentDloadComp.isInfoComp)) {
392         printf("OTA dload file success.\r\n");
393         return true;
394     }
395 
396     return false;
397 }
398 
ProcessOneComponent(void)399 static int ProcessOneComponent(void)
400 {
401     int result;
402     if (g_currentDloadComp.isInfoComp) {
403         result = ParseHotaInfoComponent(g_infoCompBuff, g_infoCompAndSignSize);
404     } else {
405         result = ParseHotaComponent();
406     }
407 
408     if (result != OHOS_SUCCESS) {
409         return result;
410     }
411     // download OK
412     if (DloadIsDone()) {
413         // done
414         UpdateStatus(HOTA_TRANSPORT_ALL_DONE);
415         HotaResetStatus();
416     }
417 
418     return OHOS_SUCCESS;
419 }
420 
CopyToDloadCompBuffer(const unsigned char * buffer,unsigned int buffSize)421 static int CopyToDloadCompBuffer(const unsigned char *buffer, unsigned int buffSize)
422 {
423     if (g_currentDloadComp.currentSize + buffSize > MAX_BUFFER_SIZE) {
424         UpdateStatus(HOTA_FAILED);
425         printf("Size is out of range.\r\n");
426         return OHOS_FAILURE;
427     }
428     if (memcpy_s(g_infoCompBuff + g_currentDloadComp.currentSize, MAX_BUFFER_SIZE - g_currentDloadComp.currentSize,
429         buffer, buffSize) != EOK) {
430         UpdateStatus(HOTA_FAILED);
431         ReportErrorCode(HOTA_DATA_COPY_TO_BUFFER_ERR);
432         printf("memcpy_s g_infoCompBuff failed.\r\n");
433         return OHOS_FAILURE;
434     }
435 
436     return OHOS_SUCCESS;
437 }
438 
GetCurrentDloadCompPartition(int * partition)439 static void GetCurrentDloadCompPartition(int *partition)
440 {
441     if (g_currentDloadComp.index - 1 >= OTA_MAX_PARTITION_NUM) {
442         UpdateStatus(HOTA_FAILED);
443         printf("the index of g_componentInfos.table is out of range.\r\n");
444         return;
445     }
446 
447     for (unsigned int i = 0; g_otaComponents[i].imgPath != NULL; i++) {
448         if (strncmp((const char *)(g_otaComponents[i].componentName),
449             (const char *)g_componentInfos.table[g_currentDloadComp.index - 1].addr,
450             PARTITION_NAME_LENGTH) == 0) {
451             *partition = g_otaComponents[i].id;
452             return;
453         }
454     }
455 
456     return;
457 }
458 
459 // Stash buffer to memory, or storage to HAL.
StashRecvDataToBuffer(unsigned char * buffer,unsigned int startAddr,unsigned int endAddr)460 static int StashRecvDataToBuffer(unsigned char *buffer, unsigned int startAddr, unsigned int endAddr)
461 {
462     if (g_currentDloadComp.isInfoComp) {
463         if (CopyToDloadCompBuffer(buffer, (endAddr - startAddr)) != OHOS_SUCCESS) {
464             printf("StashRecvDataToBuffer HotaHalWrite failed,\r\n");
465             return OHOS_FAILURE;
466         }
467     } else {
468         int partition = PARTITION_ERROR;
469         GetCurrentDloadCompPartition(&partition);
470         if (HotaHalWrite(partition, buffer, startAddr - g_currentDloadComp.offset,
471             endAddr - startAddr) != OHOS_SUCCESS) {
472             printf("StashRecvDataToBuffer HotaHalWrite failed, partition = %d .\r\n", partition);
473             ReportErrorCode(HOTA_DATA_WRITE_ERR);
474             UpdateStatus(HOTA_FAILED);
475             return OHOS_FAILURE;
476         }
477         // calc Hash
478         HotaHashCalc(buffer, endAddr - startAddr);
479     }
480 
481     g_currentDloadComp.remainSize -= (endAddr - startAddr);
482     g_currentDloadComp.currentSize += (endAddr - startAddr);
483     return OHOS_SUCCESS;
484 }
485 
ProcessCompData(unsigned char * buffer,unsigned int startAddr,unsigned int endAddr)486 static int ProcessCompData(unsigned char *buffer, unsigned int startAddr, unsigned int endAddr)
487 {
488     if (buffer == NULL || endAddr < startAddr) {
489         return OHOS_FAILURE;
490     }
491 
492     // Current Component download is not completed, so stash to buffer.
493     if ((g_currentDloadComp.remainSize > 0) && (StashRecvDataToBuffer(buffer, startAddr, endAddr)) != OHOS_SUCCESS) {
494         return OHOS_FAILURE;
495     }
496 
497     // Download one component OK and init g_currentDloadComp order to download next component.
498     if (g_currentDloadComp.remainSize == 0) {
499         if (ProcessOneComponent() != OHOS_SUCCESS) {
500             UpdateStatus(HOTA_FAILED);
501             return OHOS_FAILURE;
502         }
503         return InitDloadNextComp(endAddr);
504     }
505 
506     return OHOS_SUCCESS;
507 }
508 
HotaDefaultWrite(unsigned char * buffer,unsigned int offset,unsigned int buffSize)509 static int HotaDefaultWrite(unsigned char *buffer, unsigned int offset, unsigned int buffSize)
510 {
511     if ((buffer == NULL) || (buffSize == 0) || (buffSize > MAX_TRANSPORT_BUFF_SIZE)) {
512         printf("Param is illegal. buffer is NULL or buffSize too big. buffsize = %u.\r\n", buffSize);
513         return OHOS_FAILURE;
514     }
515 
516     if (HotaIsRejected()) {
517         printf("Hota is canceled or verify failed.\r\n");
518         return OHOS_FAILURE;
519     }
520 
521     unsigned char *tempBuffer = buffer;
522     unsigned int tempOffset = offset;
523     unsigned int tempBuffSize = buffSize;
524     do {
525         if (tempOffset < sizeof(PkgBasicInfo) && tempOffset + tempBuffSize >= sizeof(PkgBasicInfo)) {
526             if (CopyToDloadCompBuffer(tempBuffer, (sizeof(PkgBasicInfo) - tempOffset)) != OHOS_SUCCESS) {
527                 return OHOS_FAILURE;
528             }
529             g_currentDloadComp.currentSize += (sizeof(PkgBasicInfo) - tempOffset);
530             if (ProcessInfoCompHeader(g_infoCompBuff, g_currentDloadComp.currentSize) != OHOS_SUCCESS) {
531                 return OHOS_FAILURE;
532             }
533             tempBuffer = tempBuffer + sizeof(PkgBasicInfo) - tempOffset;
534             tempBuffSize -= (sizeof(PkgBasicInfo) - tempOffset);
535             tempOffset = sizeof(PkgBasicInfo);
536         } else if (tempOffset + tempBuffSize < sizeof(PkgBasicInfo)) {
537             if (CopyToDloadCompBuffer(tempBuffer, tempBuffSize) != OHOS_SUCCESS) {
538                 return OHOS_FAILURE;
539             }
540             g_currentDloadComp.currentSize += tempBuffSize;
541             break;
542         } else {
543             unsigned int startAddr = (tempOffset > g_currentDloadComp.offset) ? tempOffset : g_currentDloadComp.offset;
544             unsigned int endAddr =
545                 (g_currentDloadComp.offset + g_currentDloadComp.totalSize) < (tempOffset + tempBuffSize) ?
546                 (g_currentDloadComp.offset + g_currentDloadComp.totalSize) :
547                 (tempOffset + tempBuffSize);
548 
549             if (ProcessCompData(tempBuffer, startAddr, endAddr) != OHOS_SUCCESS) {
550                 return OHOS_FAILURE;
551             }
552             tempBuffSize -= (endAddr - tempOffset);
553             tempBuffer = tempBuffer + endAddr - tempOffset;
554             tempOffset = endAddr;
555         }
556     } while (tempBuffSize > 0);
557     return OHOS_SUCCESS;
558 }
559 
HotaSetPackageType(unsigned int flag)560 int HotaSetPackageType(unsigned int flag)
561 {
562     if (flag != USE_DEFAULT_PKG && flag != NOT_USE_DEFAULT_PKG) {
563         printf("flag is invalid. value = %u\r\n", flag);
564         return OHOS_FAILURE;
565     }
566 
567     g_useDefaultPkgFlag = flag;
568     return OHOS_SUCCESS;
569 }
570 
HotaGetUpdateIndex(unsigned int * index)571 int HotaGetUpdateIndex(unsigned int *index)
572 {
573     if (index == NULL) {
574         printf("index == NULL\r\n");
575         return OHOS_FAILURE;
576     }
577     return HotaHalGetUpdateIndex(index);
578 }
579 
HotaInit(ErrorCallBackFunc errorCallback,StatusCallBackFunc statusCallback)580 int HotaInit(ErrorCallBackFunc errorCallback, StatusCallBackFunc statusCallback)
581 {
582     if (errorCallback != NULL) {
583         g_otaNotifier.ErrorCallBackFunc = errorCallback;
584     }
585     if (statusCallback != NULL) {
586         g_otaNotifier.StatusCallBackFunc = statusCallback;
587     }
588 
589     int result = HotaHalInit();
590     if (result != OHOS_SUCCESS) {
591         return result;
592     }
593 
594     g_infoCompBuff = (unsigned char *)malloc(MAX_BUFFER_SIZE);
595     if (g_infoCompBuff == NULL) {
596         return OHOS_FAILURE;
597     }
598 
599     g_otaComponents = (ComponentTableInfo *)HotaHalGetPartitionInfo();
600 
601     UpdateStatus(HOTA_INITED);
602     return OHOS_SUCCESS;
603 }
604 
HotaRead(unsigned int offset,unsigned int bufLen,unsigned char * buf)605 int HotaRead(unsigned int offset, unsigned int bufLen, unsigned char *buf)
606 {
607     if (buf == NULL) {
608         printf("HotaRead failed. buf == NULL\r\n");
609         return OHOS_FAILURE;
610     }
611 
612     if (g_useDefaultPkgFlag == NOT_USE_DEFAULT_PKG) {
613         return HotaHalRead(0, offset, bufLen, buf);
614     }
615 
616     printf("UseOHOSPkgFlag is not open!");
617     return OHOS_FAILURE;
618 }
619 
HotaWrite(unsigned char * buffer,unsigned int offset,unsigned int buffSize)620 int HotaWrite(unsigned char *buffer, unsigned int offset, unsigned int buffSize)
621 {
622     if (g_useDefaultPkgFlag == NOT_USE_DEFAULT_PKG) {
623         return HotaHalWrite(0, buffer, offset, buffSize);
624     }
625 
626     return HotaDefaultWrite(buffer, offset, buffSize);
627 }
628 
HotaCancel(void)629 int HotaCancel(void)
630 {
631     UpdateStatus(HOTA_CANCELED);
632     HotaResetStatus();
633     return HotaHalDeInit();
634 }
635 
HotaRestart(void)636 int HotaRestart(void)
637 {
638     if (g_useDefaultPkgFlag == NOT_USE_DEFAULT_PKG) {
639         return HotaHalRestart();
640     }
641     UpdateMetaData data = {0};
642     HotaHalGetMetaData(&data);
643     if (data.otaStatus != HOTA_TRANSPORT_ALL_DONE) {
644         printf("HotaRestart, failed. ota is canceled or verify failed.\r\n");
645         return OHOS_FAILURE;
646     }
647 
648     printf("HotaRestart run!\r\n");
649     return HotaHalRestart();
650 }
651 
HotaSetBootSettings(void)652 int HotaSetBootSettings(void)
653 {
654     if (g_useDefaultPkgFlag == NOT_USE_DEFAULT_PKG) {
655         return HotaHalSetBootSettings();
656     }
657 
658     UpdateMetaData data = {0};
659     HotaHalGetMetaData(&data);
660     if (data.otaStatus != HOTA_TRANSPORT_ALL_DONE) {
661         printf("HotaSetBootSettings, failed. ota is canceled or verify failed.\r\n");
662         return OHOS_FAILURE;
663     }
664 
665     printf("HotaSetBootSettings run!\r\n");
666     return HotaHalSetBootSettings();
667 }
HotaGetUpdateAbility(void)668 int HotaGetUpdateAbility(void)
669 {
670     return HotaHalGetUpdateAbility();
671 }
672 
HotaGetOtaPkgPath(char * path,int len)673 int HotaGetOtaPkgPath(char *path, int len)
674 {
675     return HotaHalGetOtaPkgPath(path, len);
676 }
677 
HotaIsDeviceCanReboot(void)678 int HotaIsDeviceCanReboot(void)
679 {
680     return HotaHalIsDeviceCanReboot();
681 }
682 
HotaIsDevelopMode(void)683 int HotaIsDevelopMode(void)
684 {
685     return HotaHalIsDevelopMode();
686 }
687 
HotaGetUpdateStatus(void)688 int HotaGetUpdateStatus(void)
689 {
690     UpdateMetaData data = {0};
691     HotaHalGetMetaData(&data);
692     return data.updateStatus ? 1 : 0;
693 }
694 
HotaRebootAndCleanUserData(void)695 int HotaRebootAndCleanUserData(void)
696 {
697     return HotaHalRebootAndCleanUserData();
698 }
699 
HotaRebootAndCleanCache(void)700 int HotaRebootAndCleanCache(void)
701 {
702     return HotaHalRebootAndCleanCache();
703 }
704