# OTA Upgrade
- [Limitations and Constraints](#section691733275418)
- [Generating a Public/Private Key Pair](#section94411533155010)
- [Generating an Upgrade Package](#section632383718539)
- [Uploading the Upgrade Package](#section5772112473213)
- [Downloading the Upgrade Package](#section251732474917)
- [Integrating OTA Update Capabilities](#section298217330534)
- [API Application Scenario \(Default\)](#section7685171192916)
- [How to Develop](#section0745926153017)
- [Sample Code](#section1337111363306)
- [API Application Scenario \(Custom\)](#section1686395317306)
- [How to Develop](#section524515314317)
- [Sample Code](#section525974743120)
- [Upgrading the System](#section151997114334)
Over the Air \(OTA\) is a technology that makes it easier for you to remotely update devices, such as IP cameras. A device can be upgraded with a full or differential package. A full package contains all content of a new system, and a differential package contains the differences between the old and new systems. Currently, only the full-package upgrade is supported.
## Limitations and Constraints
- The open-source suites for devices developed based on Hi3861, Hi3518E V300 and Hi3516D V300 are supported.
- Devices developed based on Hi3518E V300 and Hi3516D V300 must support the SD card in the Virtual Festival of Aerobatic Teams \(VFAT\) format.
## Generating a Public/Private Key Pair
1. Download the OpenSSL tool from the following website and install it on a Windows PC, and configure environment variables.
[http://slproweb.com/products/Win32OpenSSL.html](http://slproweb.com/products/Win32OpenSSL.html)
2. Access the **tools\\update\_tools\\update\_pkg\_tools** directory, download the upgrade package making tool, and save it to a local directory, for example, **D:\\ota\_tools**.
3. Run **Generate\_public\_private\_key.bat** in the **ota\_tools\\key** directory to generate **Metis\_PUBLIC.key**, **private.key**, and **public\_arr.txt** that contains public values, as shown in the following figure. Keep the private key properly.
**Figure 1** Generating a Public/Private Key Pair
![](figure/en-us_image_0000001060200050.png)
4. Use the array written in **public\_arr.txt** as a substitute for **g\_pubKeyBuf** in **base\\update\\ota\_lite\\frameworks\\source\\verify\\hota\_verify.c** of the OTA module.
Example array in **public\_arr.txt**:
```
0x30,0x82,0x1,0xa,0x2,0x82,0x1,0x1,0x0,0xc7,0x8c,0xf3,0x91,0xa1,0x98,0xbf,0xb1,0x8c,
0xbe,0x22,0xde,0x32,0xb2,0xfa,0xec,0x2c,0x69,0xf6,0x8f,0x43,0xa7,0xb7,0x6f,0x1e,0x4a,0x97,
0x4b,0x27,0x5d,0x56,0x33,0x9a,0x73,0x4e,0x7c,0xf8,0xfd,0x1a,0xf0,0xe4,0x50,0xda,0x2b,0x8,
0x74,0xe6,0x28,0xcc,0xc8,0x22,0x1,0xa8,0x14,0x9,0x46,0x46,0x6a,0x10,0xcd,0x39,0xd,0xf3,
0x4a,0x7f,0x1,0x63,0x21,0x33,0x74,0xc6,0x4a,0xeb,0x68,0x40,0x55,0x3,0x80,0x1d,0xd9,0xbc,
0xd4,0xb0,0x4a,0x84,0xb7,0xac,0x43,0x1d,0x76,0x3a,0x61,0x40,0x23,0x3,0x88,0xcc,0x80,0xe,
0x75,0x10,0xe4,0xad,0xac,0xb6,0x4c,0x90,0x8,0x17,0x26,0x21,0xff,0xbe,0x1,0x82,0x16,0x76,
0x9a,0x1c,0xee,0x8e,0xd9,0xb0,0xea,0xd5,0x50,0x61,0xcc,0x9c,0x2e,0x78,0x15,0x2d,0x1f,0x8b,
0x94,0x77,0x30,0x39,0x70,0xcf,0x16,0x22,0x82,0x99,0x7c,0xe2,0x55,0x37,0xd4,0x76,0x9e,0x4b,
0xfe,0x48,0x26,0xc,0xff,0xd9,0x59,0x6f,0x77,0xc6,0x92,0xdd,0xce,0x23,0x68,0x83,0xbd,0xd4,
0xeb,0x5,0x1b,0x2a,0x7e,0xda,0x9a,0x59,0x93,0x41,0x7b,0x4d,0xef,0x19,0x89,0x4,0x8d,0x5,
0x7d,0xbc,0x3,0x1f,0x77,0xe6,0x3d,0xa5,0x32,0xf5,0x4,0xb7,0x9c,0xe9,0xfa,0x6e,0xc,0x9f,
0x4,0x62,0xfe,0x2a,0x5f,0xbf,0xeb,0x9a,0x73,0xa8,0x2a,0x72,0xe3,0xf0,0x57,0x56,0x5c,0x59,
0x14,0xdd,0x79,0x11,0x42,0x3a,0x48,0xf7,0xe8,0x80,0xb1,0xaf,0x1c,0x40,0xa2,0xc6,0xec,0xf5,
0x67,0xc1,0x88,0xf6,0x26,0x5c,0xd3,0x11,0x5,0x11,0xed,0xb1,0x45,0x2,0x3,0x1,0x0,0x1,
```
Example configuration for the public key of the OTA module:
```
#define PUBKEY_LENGTH 270
static uint8 g_pubKeyBuf[PUBKEY_LENGTH] = {
0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E,
0x63, 0x07, 0x84, 0xCF, 0x37, 0xF0, 0x45, 0xE8, 0xB9, 0x6E, 0xEF, 0x04, 0x88, 0xD3, 0x43, 0x06,
```
5. \(Optional\) For Hi3518E V300 and Hi3516D V300 suites, further replace the array written in **g\_pub\_key** with that in **public\_arr.txt**. The **g\_pub\_key** file is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\verify\\update\_public\_key.c** of the U-Boot module.
Example configuration for the public key of the U-Boot module:
```
static unsigned char g_pub_key[PUBKEY_LEN] = {
0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01,
0x00, 0xBF, 0xAA, 0xA5, 0xB3, 0xC2, 0x78, 0x5E,
```
## Generating an Upgrade Package
1. Save the files to be upgraded in the **ota\_tools\\Components** directory.
**Figure 2** Location of original image files
![](figure/en-us_image_0000001061889268.png)
**Table 1** Files to be upgraded
File
|
Description
|
u-boot.bin
|
Renamed from the u-boot-hi351XevX00.bin file generated after compilation.
|
kernel.bin
|
Renamed from the liteos.bin or kernel file generated after compilation.
|
rootfs.img
|
Renamed from the rootfs_xxxxx.img file generated after compilation.
|
config
|
Provides development board and kernel information. For details, see the SD card burning description of the corresponding open-source suite.
|
OTA.tag
|
Contains 32 bytes in the package_type:otaA1S2D3F4G5H6J7K8 format. The last 16 bytes are random, varying with the version.
|
2. Open the **packet\_harmony.xml** file in **ota\_tools\\xml** to modify **compAddr** as follows. Other items are reserved.
Example configuration for the component information:
```
.\Components\rootfs_jffs2.img
.\Components\liteos.bin
.\Components\userfs_jffs2.img
```
3. Configure the paths of private and public keys in **packet\_harmony.xml**.
Example configuration for paths of private and public keys:
```
.\key\private.key
.\key\Metis_PUBLIC.key
```
4. Configure the product name and software version in **ota\_tools\\VersionDefine.bat** for anti-rollback.
Example configuration for the product name and software version:
```
set FILE_PRODUCT_NAME=Hisi
@rem Set the software version number to a string of no more than 16 characters.
set SOFTWARE_VER=OpenHarmony 1.1
```
5. Run **Make\_Harmony\_PKG.bat** in the **ota\_tools** directory to generate the **Hisi\_OpenHarmony 1.1.bin** upgrade package. The upgrade package is signed using **SHA-256** and **RSA 2048** to ensure its integrity and validity.
**Figure 3** Upgrade package making tool
![](figure/en-us_image_0000001059334449.png)
## Uploading the Upgrade Package
Upload the **Hisi\_OpenHarmony 1.1.bin** upgrade package to the vendor's OTA server.
## Downloading the Upgrade Package
1. Download the **Hisi\_OpenHarmony 1.1.bin** upgrade package from the OTA server.
2. \(Optional\) Insert an SD card \(capacity greater than 100 MB\) if the device is developed based on Hi3518E V300 or Hi3516D V300.
## Integrating OTA Update Capabilities
- If vendors request OTA capabilities, use the dynamic library **libhota.so** and include the header files **hota\_partition.h** and **hota\_updater.h** in **base\\update\\ota\_lite\\interfaces\\kits**.
- The **libhota.so** source code is stored in **base\\update\\ota\_lite\\frameworks\\source**.
- For details about how to use APIs, see [API Application Scenario \(Default\)](#section7685171192916) and OTA APIs in _API Reference_.
- If the development board needs to be adapted, see the **base\\update\\ota\_lite\\hals\\hal\_hota\_board.h** header file.
## API Application Scenario \(Default\)
The upgrade package is generated by following the instructions provided in [Generating a Public/Private Key Pair](#section94411533155010) and [Generating an Upgrade Package](#section632383718539).
### **How to Develop**
1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module.
2. Call the **HotaWrite** function to verify, parse, and write data streams into the device.
3. Call the **HotaRestart** function to restart the system.
If you want to cancel the upgrade, call the **HotaCancel** function.
### **Sample Code**
Perform an OTA update using the upgrade package format and verification method provided by OpenHarmony.
```
int main(int argc, char **argv)
{
printf("this is update print!\r\n");
if (HotaInit(NULL, NULL) < 0) {
printf("ota update init fail!\r\n");
return -1;
}
int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
printf("file open failed, fd = %d\r\n", fd);
(void)HotaCancel();
return -1;
}
int offset = 0;
int fileLen = lseek(fd, 0, SEEK_END);
int leftLen = fileLen;
while (leftLen > 0) {
if (lseek(fd, offset, SEEK_SET) < 0) {
close(fd);
printf("lseek fail!\r\n");
(void)HotaCancel();
return -1;
}
int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen;
(void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN);
if (read(fd, g_readBuf, tmpLen) < 0) {
close(fd);
printf("read fail!\r\n");
(void)HotaCancel();
return -1;
}
if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) {
printf("ota write fail!\r\n");
close(fd);
(void)HotaCancel();
return -1;
}
offset += READ_BUF_LEN;
leftLen -= tmpLen;
}
close(fd);
printf("ota write finish!\r\n");
printf("device will reboot in 10s...\r\n");
sleep(10);
(void)HotaRestart();
return 0;
}
```
## API Application Scenario \(Custom\)
The upgrade package is generated in other ways instead of by referring to the preceding two sections.
### **How to Develop**
1. Download the upgrade package for the current device, and then call the **HotaInit** function to initialize the OTA module.
2. Call the **HotaSetPackageType** function to set the package type to **NOT\_USE\_DEFAULT\_PKG**.
3. Call the **HotaWrite** function to write data streams into the device.
4. Call the **HotaRead** function to read data. Vendors can choose to verify the data.
5. \(Optional\) Call the **HotaSetBootSettings** function to set the startup tag used for entering the U-Boot mode after restarting the system.
6. Call the **HotaRestart** function to restart the system.
If you want to cancel the upgrade, call the **HotaCancel** function.
### **Sample Code**
Perform an OTA update using the upgrade package format and verification method not provided by OpenHarmony.
```
int main(int argc, char **argv)
{
printf("this is update print!\r\n");
if (HotaInit(NULL, NULL) < 0) {
printf("ota update init fail!\r\n");
(void)HotaCancel();
return -1;
}
(void)HotaSetPackageType(NOT_USE_DEFAULT_PKG);
int fd = open(OTA_PKG_FILE, O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
printf("file open failed, fd = %d\r\n", fd);
(void)HotaCancel();
return -1;
}
int offset = 0;
int fileLen = lseek(fd, 0, SEEK_END);
int leftLen = fileLen;
while (leftLen > 0) {
if (lseek(fd, offset, SEEK_SET) < 0) {
close(fd);
printf("lseek fail!\r\n");
(void)HotaCancel();
return -1;
}
int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen;
(void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN);
if (read(fd, g_readBuf, tmpLen) < 0) {
close(fd);
printf("read fail!\r\n");
(void)HotaCancel();
return -1;
}
if (HotaWrite((unsigned char *)g_readBuf, offset, tmpLen) != 0) {
printf("ota write fail!\r\n");
close(fd);
(void)HotaCancel();
return -1;
}
offset += READ_BUF_LEN;
leftLen -= tmpLen;
}
close(fd);
printf("ota write finish!\r\n");
leftLen = fileLen;
while (leftLen > 0) {
int tmpLen = leftLen >= READ_BUF_LEN ? READ_BUF_LEN : leftLen;
(void)memset_s(g_readBuf, READ_BUF_LEN, 0, READ_BUF_LEN);
if (HotaRead(offset, READ_BUF_LEN, (unsigned char *)g_readBuf) != 0) {}
printf("ota write fail!\r\n");
(void)HotaCancel();
return -1;
}
/* do your verify and parse */
offset += READ_BUF_LEN;
leftLen -= tmpLen;
}
/* set your boot settings */
(void)HotaSetBootSettings();
printf("device will reboot in 10s...\r\n");
sleep(10);
(void)HotaRestart();
return 0;
}
```
## Upgrading the System
Vendor applications call APIs of the OTA module to perform functions such as signature verification of the upgrade package, anti-rollback, burning and data flushing-to-disk. After the upgrade is complete, the system automatically restarts.
For Hi3518E V300 and Hi3516D V300 open-source suites, the value of **LOCAL\_VERSION** needs to be modified for anti-rollback, for example, modifying **ohos default 1.0** to **ohos default 1.1**. The macro **LOCAL\_VERSION** is provided in **device\\hisilicon\\third\_party\\uboot\\u-boot-2020.01\\product\\hiupdate\\ota\_update\\ota\_local\_info.c**.
Example for modification of the local version:
```
const char *get_local_version(void)
{
#if defined(CONFIG_TARGET_HI3516EV200) || \
defined(CONFIG_TARGET_HI3516DV300) || \
defined(CONFIG_TARGET_HI3518EV300)
#define LOCAL_VERSION "ohos default 1.0" /* increase: default release version */
```