Introduction
==================================
Over-the-Air firmware updates (referred to as OTA updates from here forward) are a way to dynamically update the various firmware and software components of an embedded solution using the device's active wireless connection. In this training session we will describe in detail a method to perform over-the-air updates using the MSP432P4 host microcontroller connected to a CC3120 WiFi network processor. It's important to note that a [similar training module for CC3220 exists](../wifi_ota/wifi_ota.html), however this tutorial will be focusing more on the two chip plugin solution that is part of the SimpleLink SDK WiFi Plugin.
Prerequisites
==================================
Suggested SimpleLink Academy Labs
---------
* [SimpleLink SDK Plugins Overview](http://dev.ti.com/tirex/#/?link=Software%2FSimpleLink%20MSP432P4%20SDK%2FSimpleLink%20Academy%2FLectures%2FSDK%20Plugins%2FSimpleLink%20SDK%20Plugins%20Overview)
* [WiFi Plugin Project Zero](http://dev.ti.com/tirex/#/?link=Software%2FSimpleLink%20MSP432P4%20SDK%2FSimpleLink%20Academy%2FLabs%2FConnectivity%2FWi-Fi%20Plugin%2FWi-Fi%20Plugin%20Project%20Zero)
It's important to note that many of the concepts from the [CC3220 WiFi OTA lab](http://dev.ti.com/tirex/#/?link=Software%2FSimpleLink%20CC3220%20SDK%2FSimpleLink%20Academy%2FLabs%2FWi-Fi%2FWi-Fi%20OTA) are reused and rehashed in this training module. While the core elements between the one chip CC3220 and two chip MSP432 + CC3120 OTA mechanisms will remain the same, several components will inevitably vary on account of the underlying hardware differences.
Notably, the following differences will be observed:
- The CC3220 has a hardware SHA-256 accelerator while the MSP432 depends on the [third-party mBedTLS software package](https://github.com/ARMmbed/mbedtls) for SHA-256 hash calculation
- The mechanism for updating the firmware running on the MSP432 varies from updating the firmware on the CC3220 given the underlying differences in the flash architecture
- Importing the OTA libraries has been simplified in the CC3120 plugin to cater towards ease-of-use
Software
---------
* **IDE of choice including:**
* [Code Composer Studio v7.3.0 and newer](https://www.ti.com/tool/CCSTUDIO)
* [IAR Embedded Workbench 8.11.2 and newer](https://www.ti.com/tool/CCSTUDIO)
* [Code Composer Studio v7.3.0 and newer](https://www.ti.com/tool/CCSTUDIO)
* [SimpleLink SDK WiFi Plugin 1.50.xx or newer](https://www.ti.com/tool/SIMPLELINK-WIFI-CC3120-SDK-PLUGIN)
* [SimpleLink MSP432P4 SDK 1.50.xx or newer](https://www.ti.com/tool/SIMPLELINK-WIFI-CC3120-SDK-PLUGIN)
* [UniFlash Firmware Updater 4.2.1 or newer](https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash)
* **RTOS Configuration of choice including:**
* [TI-RTOS (included within SDK)](https://www.ti.com/tool/TI-RTOS)
* [FreeRTOS 9.0.0](http://www.freertos.org/)
Note that for simplicity we use a configuration of **Code Composer Studio** and **TI-RTOS** using the **TI ARM compiler**, however the functionality of the end application described in this tutorial will be identical for all permutations of the IDEs/RTOSs supported by the MSP432P4 SDK.
Hardware
---------
* [MSP-EXP432P401R LaunchPad](https://www.ti.com/tool/MSP-EXP432P401R) OR [MSP-EXP432P4111 LaunchPad](https://www.ti.com/tool/MSP-EXP432P4111)
* [CC3120 WiFi BoosterPack](https://www.ti.com/tool/CC3120BOOST)
* [CC31XXEMU BoosterPack](https://www.ti.com/tool/CC31XXEMUBOOST)
[[r! MSP432E4
Note that over-the-air updates for the MSP432E4 are not supported, but scoped for a future release.
]]
Mechanics of Over-the-Air Update
==================================
OTA updates are useful in updating all components of an embedded system throughout its extended lifecycle. After an application is deployed to the field it may become unrealistic to update the firmware on the device via a hardwired connection such as UART or USB. For this reason TI has built out a software solution that allows programmers to not only update the firmware running on the MSP432 host microcontroller, but also the user files stored on the CC3120's flash storage.
In an OTA enabled application for MSP432 (either MSP432P401 or MSP432P111) the first 32KB of flash memory is reserved for a customized bootloader. This bootloader will start up a small NoRTOS implementation of the CC3120 host driver, open the image programmed at **/sys/hostmcuimg.bin** on the CC3120's file system, and dynamically program that image to the MSP432's flash memory at a starting base address of **0x8000**. The memory map of a typical MSP432 OTA enabled device can be seen below.
![](images/bsl_1.png)
[[b! MSP432P4111
Note that this example is for an MSP432P401, however on an MSP432P4111 the structure will be the similar but adjusted for the MSP432P111's larger memory footprint.
]]
Initially, when the Uniflash tar file is being programmed to the CC3120 over the active WiFi connection, the firmware running on the MSP432 will detect if a new MSP432 firmware image exists in the package at the location **/sys/hostmcuimg.bin**. If so, the MSP432's firmware will set a flag (a variable named `appTransferKey` at a specific area of SRAM and initiate a hard reset of the device (causing execution to be handed over to the custom bootloader).
**Which software components can be updated using the Over-the-Air firmware updates included in the SimpleLink SDK WiFi Plugin?**
[quiz]
x The MSP432's Firmware
x The service pack on the CC3120
x The files located on the CC3120's flash
v All of the above --> **Correct!** Both the CC3120's user files and the actual firmware running on the MSP432P4 can be updated!
[quiz]
Building an MSP432P4 Firmware Image
---------
The format for the MSP432P4's firmware for OTA WiFi updates is a simple compiled binary **.bin** file. This file is a contiguous binary chunk of memory that is programmed to a known base address on the MSP432 that represents byte-for-byte the firmware to be run on the MSP432. In our case, the known base address resides at **0x8000**- right below the code for the MSP432's custom bootloader.
In both of the MSP432P4 OTA code examples included with the SimpleLink SDK WiFi Plugin one of the two following files exists (depending on which MSP432P4 device you are using):
- **msp432p401_bootloader.c**
- **msp432p4111_bootloader.c**
When opening these files you can see that they contain large C byte arrays that are placed at a specific area of memory:
```c
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(ota_bootloader, "OAD_BSL")
#pragma RETAIN (ota_bootloader)
const unsigned char ota_bootloader[] =
#elif defined(__GNUC__)
const unsigned char __attribute__((section (".oad_bsl"))) ota_bootloader[] =
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma location="OTA_BSL"
__root const unsigned char ota_bootloader[] =
#endif
{
0x00, 0x00, 0x01, 0x20, 0x7D, 0x68, 0x00, 0x00, 0x3B, 0x6C, 0x00, 0x00,
0x39, 0x6C, 0x00, 0x00, 0x37, 0x6C, 0x00, 0x00, 0x33, 0x6C, 0x00, 0x00,
0x37, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x6C, 0x00, 0x00,
0x37, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x6C, 0x00, 0x00,
0x37, 0x6C, 0x00, 0x00, 0x37, 0x6C, 0x00, 0x00, 0x37, 0x6C, 0x00, 0x00,
...
}
```**msp432p401_bootloader.c**
This C array represents the compiled custom bootloader that resides in the top 32KB of the MSP432's memory. The collection of pragmas and compiler keywords on top of the definition along with custom linker files make sure that this firmware array gets programmed at physical address **0x00000000**. Including this firmware image with the OTA projects as a C-Array gives the ease-of-use benefit of the user not having to explicitly program a separate project for the bootloader.
When compiling a firmware image to be included in an OTA firmware update package it is important to not include the bootloader in the generated binary image. The absolute address of where to program the firmware image is specified by the **APP_SW_START_ADDRESS** define in the **ota_extended.h** file included in the OTA code examples:
```c
#define APPLICATION_PERFORM_BSL (0xABCD55AA)
#define APP_SW_START_ADDRESS (0x00008000)
#define SHARED_MEMORY_LOCATION (0x20002000)
#define OTA_BUFFER_SIZE (256)
#define OTA_FIRMWARE_NAME "hostmcuimg.bin"
#define OTA_FIRMWARE_PATH "/sys/hostmcuimg.bin"
```**ota_extended.h**
If the bootloader was included in the binary file for the OTA package, a redundant bootloader would be programmed at 0x8000 and the application would fail to operate correctly. To prevent the bootloader from being integrated into the firmware image being generated for OTA, simply comment out the contents of the **msp432p401_bootloader.c** file. When programming the MSP432 via an IDE leave the contents of **msp432p401_bootloader.c** in the build to enable the programming of the bootloader.
To have Code Composer Studio explicitly generate a binary file in its output directory a custom **post build step** must be added to the project configuration. Right click your project settings and select **Properties**. From there, select the **Build** menu item on the left and then select the **Steps** tab. Copy and paste the following into the **Post-build steps** text area:
```c
"${CCS_INSTALL_ROOT}/utils/tiobj2bin/tiobj2bin" "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin" "${CG_TOOL_ROOT}/bin/armofd" "${CG_TOOL_ROOT}/bin/armhex" "${CCS_INSTALL_ROOT}/utils/tiobj2bin/mkhex4bin"
```
![](images/build_steps.png)
Select OK and build your project. In the output build directory of your project a **.bin** file should now be generated:
![](images/binary_file.png)
[[b! MSP432 Bootloader
Note that when running/flashing your program for the first time through CCS the bootloader must be included. Subsequently when sending firmware updates through OTA the firmware must be omitted from the binary image.
]]
**What information is included in the compiled binary format that is used for MSP432P4 OTA updates?**
[quiz]
x Debug symbols
v Binary representation of firmware --> **Correct!** The **.bin** format is as primitive as firmware formats get. It is just a byte-by-byte representation of the MSP432's firmware.
x Address information
x Porkchop Sandwiches
[quiz]
MSP432 Firmware Bootloader
---------
The bootloader that resides at the start of the MSP432's memory is a custom bootloader specially developed to work with the OTA firmware mechanism running in the main application. This bootloader is provided as a precompiled C file (see the section above) as well as a full source implementation. The projects for the bootloaders can be found under the following two folders:
- **examples/nortos/MSP_EXP432P401R/demos/msp432p401_bootloader**
- **examples/nortos/MSP_EXP432P4111/demos/msp432p4111_bootloader**
[[y! Different Flash Drivers
The MSP432P401 and MSP432P4111 have slightly different flash drivers requiring two separate projects for the bootloader.
]]
It's important to note that the bootloader running on the MSP432 does have a bare bones WiFi host driver running on it. While no WiFi communication is taking place, the bootloader does make use of the filesystem APIs to dynamically read chunks of data from the **hostmcuimg.bin** on the CC3120's file system.
[[y! NoRTOS is really an RTOS
No-RTOS refers to the "No RTOS" implementation provided by the platform SDK. The name is a bit misleading as the underlying software does have a mandatory elementary scheduler that consumes the SysTick of the core.
]]
At the start of every boot of the MSP432 (regardless if an OTA package was received) the custom bootloader will do a quick check to see if a "flag" has been set in a shared SRAM address. This shared SRAM address is specified as a precompiler macro in the `ota_extended.h` header file:
```c
#define APPLICATION_PERFORM_BSL (0xABCD55AA)
#define APP_SW_START_ADDRESS (0x00008000)
#define SHARED_MEMORY_LOCATION (0x20002000)
#define OTA_BUFFER_SIZE (256)
#define OTA_FIRMWARE_NAME "hostmcuimg.bin"
#define OTA_FIRMWARE_PATH "/sys/hostmcuimg.bin"
```**ota_extended.h**
In both the source for the bootloader and the application source, this shared area of SRAM is defined as such:
```c
#if defined(__TI_COMPILER_VERSION__)
#pragma RETAIN(appTransferKey)
#pragma LOCATION(appTransferKey, SHARED_MEMORY_LOCATION)
volatile uint32_t appTransferKey;
#elif defined(__GNUC__)
volatile uint32_t __attribute__((section (".shared_memory"))) appTransferKey;
#elif defined(__IAR_SYSTEMS_ICC__)
__no_init volatile uint32_t appTransferKey @ SHARED_MEMORY_LOCATION;
#endif
```**platform.c**
The macros around the variable declaration work with the IDE specific linker files to explicitly place the variable in the memory address specified by `SHARED_MEMORY_LOCATION`. If the value at `appTransferKey` is equal to the flagged value of `APPLICATION_PERFORM_BSL`, the bootloader will assume that a valid **hostmcuimg.bin** exists on the CC3120's flash memory and proceed with the bootloader logic. If the value of `appTransferKey` is anything other than `APPLICATION_PERFORM_BSL`, the bootloader will jump to the reset vector of the main application.
The logic for the actual bootloader itself is somewhat standard. Essentially what the program will do is read the file information of **hostmcuimg.bin**, erase the necessary segments, and the program in chunks specified by `OTA_BUFFER_SIZE`. If any error occurs during operation the bootloader will spin in an infinite LED toggle loop. In the error state a reset will cause the application to jump to the main application code (as the `appTransferKey` gets cleared with each bootload attempt).
A flow chart of the custom OTA bootloader in the presence of a MSP432 firmware image can be seen below:
![](images/bsl_2.png)
Creating a Firmware Update Package
---------
The first step of any firmware update will be for the user to create the firmware update package that will be sent to the device. In the SimpleLink SDK WiFi Plugin world this package takes the shape of a generated **Tar** archive that contains all relevant user files as well as additional firmware update metadata.
This metadata is used for security, verification, and various system tasks relating to the firmware update process on the embedded firmware side. Firmware update packages are created using the Image Creator utility of the [Uniflash programming tool](https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash).
To get started first download the latest Uniflash package from the the link below:
[https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash](https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash)
Open up the UniFlash application. In the device list, scroll down (to the very bottom) and select **CC3120 / CC3220**:
![](images/uniflash_1.png)
Once selected, click **Start Image Creator** to start the image creator application. This will start the SimpleLink WiFi Image Creator that is used to create OTA Tar packages. On this screen you can manage various project settings as well as program external images. To get started, click on the **New Project** button as seen below.
![](images/uniflash_2.png)
On the next screen fill out a project name of your choice. Make sure that you choose **CC3120** as the **Device Type** and make sure that the **Device Mode** is set to **Develop**. Develop mode allows the user to open up the file system and make changes via Uniflash during the development phase. When you wish to secure your device and program it for production the **Production** mode should be used.
![](images/uniflash_3.png)
On the next screen you will see the new project page as it exists for Development Mode. In Development Mode you can change and manipulate all aspects of the CC3120 device. At a minimum when creating an image to flash on the CC3120 it is recommended to start with specifying a service pack. The service pack provides various patches and security fixes for the NWP image running on the CC3120. To specify a service pack select the **Service Pack** menu item on the left.
![](images/uniflash_4.png)
On the next page click browse next to the file name field and navigate to the service pack release that is included with the SimpleLink SDK WiFi plugin release. This can be found in the **/tools/cc31xx_tools/servicepack-cc3x20**. The file name generally starts with **sp\_** and ends with **.bin**.
![](images/uniflash_5.png)
[[b! Files Persist
Note that when you select this file it persists within Uniflash- meaning if you save the project and reopen it the service pack file will exist within Uniflash's internal memory.
]]
The next portion of the project that is common to update is the user files section. The user files are all files that are user accessible that are stored on the flash memory of the CC3120. These can include anything from application files such as html pages to certificates used for validation and security. To manage the user files contained within your image select the User Files menu item from the left.
On the next screen the file manager view will be displayed. Since this is a new project there are no files currently populated. Let's add some files. Click on the small file icon located on the top of the file view.
![](images/uniflash_6.png)
A common file to add to the user files is a root ca certificate. This certificate is responsible for securing a client connection and provides a level of security that ensures that users are legitimately connected to a trusted source. As part of the plugin release a "dummy" certificate is provided. To add this certificate to your project navigate to the **/tools/cc31xx_tools/certificate-playground** folder and select the **dummy-trusted-ca-cert** file to add to the project. On the file options window select **Failsafe** (this adds a certain level of redundancy for safety) and select **Write.**
![](images/uniflash_7.png)
The commonly updated certificates that are associated with firmware updates can be seen in the image below:
![](images/exp_14.png)
[[b! Everything Persists
As with the service pack, once a file is added to the Uniflash project it will persist in the Uniflash project (even if the file is deleted from the file system on your PC).
]]
The next important file to add to the device is the certificate used to validate that the OTA package that you send to the SimpleLink device is verifiable and from a trusted source (the exact mechanics for this are described in the [security section in this guide](#sha-256-signature-digest-verification)). A dummy certificate for demonstration purposes is located at **/tools/cc31xx\_tools/ota-example-cert/dummy\_ota\_vendor\_cert.der**. Place this file in the root directory.
Lastly the firmware image of the MSP432 must be added to the file system. Follow the steps described in the [building a firmware image section](#building-an-msp432p4-firmware-image) of this document to create your bin file and place it in **/sys/hostmcuimg.bin**. When all is done your firmware image should look similar to the image below.
![](images/bsl_3.png)
[[y Failsafe
Make sure that the **hostmcuimg.bin** file is specified as **Failsafe**.
]]
[[y File Size Limit
The file size limit of the MSP432 firmware is currently limited to 256K.
]]
Now that all relevant files have been added to the OTA image is is now time to generate the Tar file. To do this, click the **Generate Image** button located on the right.
![](images/uniflash_13.png)
From here, click on the **Create OTA** button.
![](images/uniflash_14.png)
This will prompt you for the private key used for the SHA-256 signature definition. This is the key detailed in the [SHA-256 digest verification section](#sha-256-signature-digest-verification). As mentioned, a dummy key can be found at **/tools/cc31xx\_tools/ota-example-cert/dummy\_ota\_vendor\_key.der**. Navigate to the location of your key and click **Create OTA**. This generate the the Tar file and prompt for a location to save. Save the Tar file to a known location. Notice that the saved Tar file has a filename such as:
`20171023153905_CC3100_LOCAL_OTA.tar`
The first part of the file name (20171023153905 in this case) corresponds to the version number. The embedded OTA code running on the MSP432 uses this information to determine if the firmware that was sent over OTA is an older or newer revision of the current firmware on the system. Whenever a firmware update over OTA occurs, a file named **ota.dat** is stored in the root of the file system with the version of firmware that was programmed. When a new OTA firmware image comes in over WiFi a decimal comparison of the new image is done with the version number in **ota.dat** to determine if the application should proceed with the firmware update.
**What is the filesize limit of the MSP432's firmware?**
[quiz]
v 256KB --> **Correct!** Since the firmware image of the MSP432 is stored on the flash of the CC3120, a 256KB filesize limit is imposed.
x No Limit
x 2MB
x 64K
[quiz]
SHA-256 Signature/Digest Verification
---------
In addition to the actual files being updated, additional security precautions must also be inacted to the firmware package in order to foster security and prevent any malicious updates of unwanted code on the embedded system. The WiFi stack running on the CC3120 and the application firmware running on the MSP432 have a couple of mechanisms for doing this; one of the most prominent of which is the use of SHA-256 cryptographic hashing mechanism.
[[b Software SHA-256
The MSP432 depends on the [third-party mBedTLS software package](https://github.com/ARMmbed/mbedtls) for SHA-256 hash calculation
]]
**Quiz - Does the SHA-256 functionality encrypt your firmware image and user files?**
[quiz]
v No --> **Correct!** SHA-256 is used as a means of verification and a way to ensure that a firmware image is not corrupt and comes from a trusted authority. It does not perform any encryption commands directly on the firmware image itself.
x Yes
[quiz]
When an OTA firmware image is created by Uniflash (see the [section about creating a firmware package](#creating-a-firmware-update-package) two specific pieces of metadata are created:
- **ota.cmd**
- **ota.sign**
The **ota.cmd** file contains a list of all the firmware files that are included in the firmware package as well as additional file information such as size and a **SHA-256** digest. These digests are used to verify the integrity of each individual file and that there has been no corruption in transit.
The **ota.sign** file is a chunk of data that is referred to the **SHA-256 signature**. This signature is generated against the bytes of the **ota.cmd** file using the **private key** that you navigated to during the generation of the Tar file (**dummy\_ota\_vendor\_cert.der**). This private key should be kept secret in a production environment as it is the main mechanism that the firmware author has to prevent any malicious code updates of the firmware device.
A block diagram of each individual step regarding the SHA-256 hash calculation can be seen below:
![](images/ota_steps.png)
While the individual file hash calculation is performed using software SHA-256 locally on the MSP432, the signature verification of the **ota.sign** file is offloaded to the crypto engine on the CC3120. Once a SHA-256 digest has been calculated against **ota.cmd**, both the bytes contained in **ota.sign** and the calculated **SHA-256 digest** are passed using a host command to the CC3120 using the following code:
```c
/* Verify the signature using the installed certificate */
memcpy(verifyBuf, pDigest, SHA256_DIGEST_SIZE);
memcpy(verifyBuf + SHA256_DIGEST_SIZE, pSig, SigFileSize);
verAttrib.Flags = 0;
verAttrib.ObjId = OTA_CERTIFICATE_INDEX;
verAttrib.SigType = SL_NETUTIL_CRYPTO_SIG_DIGESTwECDSA;
verAttrib.MsgLen = SHA256_DIGEST_SIZE;
verAttrib.SigLen = SigFileSize;
resultLen = 4;
Status = sl_NetUtilCmd(SL_NETUTIL_CRYPTO_CMD_VERIFY_MSG, (_u8 *) &verAttrib,
sizeof(SlNetUtilCryptoCmdVerifyAttrib_t), verifyBuf,
SHA256_DIGEST_SIZE + SigFileSize,
(_u8 *) &verifyResult, &resultLen);
/* In case the signature is not valid, return a special error code */
if((Status == 0) && (verifyResult < 0))
{
free(verifyBuf);
/* The process succeeded (Status == 0) and the verification
* failed - Security Alert
*/
return (ARCHIVE_STATUS_BUNDLE_CMD_SIGNATURE_NOT_VALID);
}
```**ota_archive.c **
OTA Library
---------
In both the Cloud OTA and Local OTA examples included in the plugin an additional `ota` library ships and is automatically imported when either one of the code examples is imported. This library contains various tools and utilities for controlling all aspects of the OTA update. This library needs to be built (and is usually built automatically) for use with either the OTA code examples.
[[y! Difference with CC32xx SDK
Note in the SimpleLink CC32XX SDK the OTA project does not auto import and you have to explicitly import and build it in your project.
]]
The main user APIs for the OTA library are included in the `ota.h` file. This file contains all of the necessary OTA accessing APIs that are used in the normal flow for a typical OTA update. These are the APIs that are used as a primary mechanism for the OTA update by the Cloud OTA project.
Separate auxillary APIs for managing the SHA-256 hash generation and file parsing are included in the `ota_archive.h` file. The Local OTA example accesses these functions directly and bypasses the use of the main `ota.h` APIs. Within `ota_archive.h`, the following parameters exist:
```c
#define TAR_HDR_SIZE 512
#define MAX_SIGNATURE_SIZE 256
#define MAX_FILE_NAME_SIZE 128
#define MAX_SHA256_DIGEST_SIZE 65
#define MAX_BUNDLE_CMD_FILES 8
```
Specifically, the `MAX_BUNDLE_CMD_FILES` define is of interest here. This file specifies the max number of files that can be included in an OTA update. Specifically, this number correlates to the size of the following main control structure in **ota_lib.h**:
```c
typedef struct
{
OtaState_e State;
uint32_t Options;
/* Keep OTA parameters */
uint8_t VendorDir[MAX_VENDIR_DIR_SIZE];
Ota_optServerInfo OtaServerInfo;
/* OTA objects */
CdnClient_t CdnClient;
OtaArchive_t OtaArchive;
/* OtaDir and FileUrl info */
uint8_t *pOtaFileName;
int32_t OtaFileSize;
uint8_t FileUrlBuf[MAX_URL_SIZE];
/* file content buffer */
uint8_t *pRecvChunk;
int16_t RecvChunkSize;
int16_t RecvChunkOffset;
int16_t RecvChunkForceReadMode;
int16_t RecvChunkReserved;
/* send/recv buffer - must be 4 bytes alignment */
uint8_t NetBuf[NET_BUF_SIZE + 1];
/* Retries */
int8_t ConsecutiveOtaErrors;
} OtaLib_t;
```ota_lib.h
The larger the value of `MAX_BUNDLE_CMD_FILES` is the larger the memory structure becomes (and the largers the SRAM footprint becomes). This is only an issue when using the main program flow (such as `cloud_ota`) with the APIs included in **ota.h**. For examples that directly access the utility APIs (like `local_ota`) this is no longer an issue.
[[b JSON Library
A library for parsing and processing JSON files is also linked against for the OTA examples. This project is not automatically imported, however is provided as a static library so as long as the user is not making changes to the JSON library it does not have to be imported.
]]
For a more detailed explanation of the individual APIs that make up the OTA library, please refer [to the OTA library section in the CC3220 OTA module.](http://dev.ti.com/tirex/#/?link=Software%2FSimpleLink%20CC3220%20SDK%2FSimpleLink%20Academy%2FLabs%2FWi-Fi%2FWi-Fi%20OTA#simplelink-ota-library-ota-)
Lab Preparation
==================================
Setting up the Hardware
---------
The code examples in this lab use a standard [MSP-EXP432P401R LaunchPad](https://www.ti.com/tool/MSP-EXP432P401R) connected to a [CC3120 BoosterPack](https://www.ti.com/tool/CC3120BOOST). To prepare for the labs connect the BoosterPack to the LaunchPad as seen below.
![](images/401booster.jpg)
Note for an MSP-EXP432P4111 LaunchPad the setup will look like the picture below.
![](images/4111booster.jpg)
Setting up the terminal
---------
Note that for logging/debugging messages the back channel serial port of the LaunchPad is used. In order to read these messages, use your favorite serial terminal program (such as [Tera Term](https://ttssh2.osdn.jp/index.html.en) or [PuTTY](http://www.putty.org/)). The COM port number will be different depending on the system configuration, however it should show up as *XDS110 Class Application/User UART*.
![Device Manager](images/dev_manager.jpg)
Make sure to use the Application/User UART and not the Auxiliary Data Port. Along with the COM port of the XDS110 UART, the back channel UART defaults to the following serial port values:
![Serial port values](images/serial_port.jpg)
Lab 1: Local Over-the-Air Update
==================================
The `local_ota` example is a code example that sets up a full fledged HTTP web server on the SimpleLink device. This web server presents a landing page for the user to upload their Tar file (described in [building a firmware image section](#building-an-msp432p4-firmware-image) of this document) and have the firmware update happens directly without the need for any cloud interaction.
[[r!Cloud use Not Recommended
This code example explicitly requires manipulation and accessing of files that are located in the install directory of the WiFi plugin. For this reason it is recommended to use a local IDE installation (CCS, IAR, or GCC) versus CCS Cloud Tools.
]]
Programming Local OTA Files with Uniflash
---------
To get started, we first need to program the CC3120 with the initial user files, certificates, and web files that will be used to prompt the user and accept the Tar file for the firmware update. The initial programming of the CC3120 is performed by using the [CC31XXEMUBOOST](https://www.ti.com/tool/CC31XXEMUBOOST) module in conjunction with the Image Creator utility of [UniFlash](https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash). As a first step, connect the CC31XXEMUBOOST to the CC3120 BoosterPack as seen below while being careful not to mount the pins upside down:
![](images/uniflash_2.jpg)
[[y! Dual Connections
Note that while connected to the CC31XXEMUBOOST, the normal programming of the MSP432 LaunchPad will not work correctly. Also note that it is not required for the CC3120 to be connected to the MSP432 when programming with the CC31XXEMUBOOST.
]]
Plug the USB cable from your computer into the right USB port of the CC31XXEMUBOOST (as seen above). Once connected, open up the UniFlash application. In the device list, scroll down (to the very bottom) and select **CC3120 / CC3220**:
![](images/uniflash_1.png)
Once selected, click **Start Image Creator** to start the image creator application. On the following screen we need to import the example project for `local_ota` that is included with the plugin release. Select the **Manage Projects** buton.
![](images/uniflash_15.png)
Next select the **Import** button to prompt for a location of a zip file to import into Uniflash.
![](images/uniflash_16.png)
Navigate to the example zip file located at **SimpleLink SDK WiFi Plugin → Examples → examples → rtos → MSP_EXP431401R → demos → local_ota → uniflash_p401 → LOCAL_OTA_RS_171022141750.zip**
![](images/uniflash_18.png)
Double click on the imported project to open it in Uniflash. Once open, press the **Connect** button on the right of the screen.
![](images/uniflash_17.png)
Once connected various information such as the MAC address and hardware version is displayed on the right. To program the image, first select the **Generate Image** icon on the right.
![](images/uniflash_19.png)
[[r! Formatting
Note that when programming through Uniflash all files that are not included in the user files are erased and the new files are persisted. The exceptions are system files (such as the factory reset image).
]]
On the next screen select the **Program Image (Create & Program)**.
This will proceed to program the new image (both the service pack and the user file that you added) to the flash memory on the CC3120 BoosterPack.
![](images/uniflash_10.png)
After programming is finished, disconnect the CC31XXEMUMBOOST module from your LaunchPad and connect the LaunchPad to your PC via the normal USB connection.
Importing the Code Example
---------
Next we need to import the `local_ota` code example into your workspace. The code example is located at **SimpleLink SDK WiFi Plugin → Examples → examples → rtos → MSP_EXP431401R → demos → local_ota**. In Code Composer studio the easy way to do this is to select **Projects → Import CCS Projects** from the menu bar:
![](images/ccs_import1.png)
... and then navigate to the `C:\ti\simplelink_sdk_wifi_plugin_1_50_00_42\examples\rtos\MSP_EXP432P401R\demos\local_ota\tirtos\ccs` directory (or the relevant path for your RTOS/toolchain configuration).
![](images/ccs_import2.png)
[[b! Automatic Imports
When importing the `local_ota` or `cloud_ota` examples for TI-RTOS, an additional special build of the TI-RTOS kernel will be imported that was designed to work well with the custom MSP432 bootloader.
]]
Provisioning the Device
---------
The `local_ota` code example is provisioned by hard coding the relevant router/access point information into the `local_ota.h` source file using the following defines:
```c
/* Values for below defines shall be modified for setting the AP connection properties */
#define SECURITY_KEY ""
#define SECURITY_TYPE SL_WLAN_SEC_TYPE_OPEN
#define SSID_NAME "cc3120demo"
#define SSL_SERVER_KEY "ca-priv-key.der"
#define SSL_SERVER_CERT "ca_in_cert_store"
```**local_ota.h**
Change this configuration to match your router/network. Realistically speaking, most routers are going to have a secured network with a WPA2 security key. The following, for example, would setup the code example to connect to the network with the SSID of **sushi** and a WPA key of **lupiniii**
```c
/* Values for below defines shall be modified for setting the AP connection properties */
#define SECURITY_KEY "lupiniii"
#define SECURITY_TYPE SL_WLAN_SEC_TYPE_WPA_WPA2
#define SSID_NAME "sushi"
#define SSL_SERVER_KEY "ca-priv-key.der"
#define SSL_SERVER_CERT "ca_in_cert_store"
```**local_ota.h**
Running the Code Example
---------
Once you have configured your local network information in **local_ota.h** build your program and download it to your LaunchPad. After running the program you should see the code example start up and information such as the IP and network diagnostic being displayed on the terminal output:
![](images/local1.png)
In this case the application was assigned an IP of **192.168.86.39**. From a PC, open up a web browser and open of the address `https://192.168.86.39/ota.html`, replacing the IP address with the one assigned to you specifically.
[[y! Invalid Certificate
Note that you will most likely get an "invalid certificate" warning as we are using a dummy development certificate. This can be safely ignored during development.
]]
![](images/local2.png)
As part of the `local_ota` code example, an example Tar file of a firmware update package is provided at **SimpleLink SDK WiFi Plugin → Examples → examples → rtos → MSP_EXP431401R → demos → local_ota → 20171022150827_CC3100_MSP432P401R_OTA_EXAMPLE.tar**. This file can be used or you can create your own via the instructions detailed in the [building a firmware image section](#building-an-msp432p4-firmware-image) of this document.
[[y! Provisioning Information
Note that if you use the example Tar above the firmware image is expecting to connect to an open WiFi network with an SSID of **cc3120test**
]]
Click the **Upload** button on the web interface and the the **Choose File** button. Navigate to your Tar file package and the press **Upload File**.
![](images/local3.png)
This will initiate the firmware update. Note that the terminal screen will output the progress of the firmware update as well as provide miscellaneous information such as hash calculation.
![](images/local4.png)
Once the firmware has been downloaded and verified on the device, the MSP432 will reboot and the LED on LED2 will turn solid blue to signify the MSP432's firmware is being updated.
![](images/local6.jpg)
Note that in our example the firmware image changed titles. When we downloaded the code from CCS and ran it initially the title of the firmware image in the terminal output was **Local OTA Example**, however after the update it was **Local OTA EX0 Example**.
![](images/local5.png)
In the firmware update image we changed this title so that there would be a tangible way to illustrate that the firmware did in fact actually update. The title and version string are stored in the **local_ota.h** file:
```c
/* Application Version and Naming*/
#define APPLICATION_NAME "Local OTA"
#define APPLICATION_VERSION "1.50.00.00"
```
Also note that once the firmware update occurs and the firmware is updated on the MSP432, the device will reset and connect to the same WiFi network as before. Once connected, the web interface will probe the version number from the device (remember, this is stored in **ota.dat**) and then verify that the Tar file sent to the device actually persisted.
If the version check passes, the **Finalize** button will become available. Click this button to persist the firmware update to the local device.
![](images/local6.png)
Lab 2: Cloud Over-the-Air Update
==================================
The `cloud_ota` example achieves the same end functionality as the `local_ota` example, however with the `cloud_ota` example the firmware for the update comes from a cloud service provider. The SimpleLink SDK WiFi Plugin currently supports to two following cloud content providers for OTA updates:
- [GitHub](https://www.github.com)
- [DropBox](https://www.dropbox.com/)
Start by importing the `cloud_ota` project into your CCS workspace. The `cloud_ota` project can be found at t **SimpleLink SDK WiFi Plugin → examples → rtos → MSP_EXP431401R → demos → cloud_ota**
In the SimpleLink SDK world, cloud services that provide a vessel for the SimpleLink WiFi device to download firmware packages from are called Content Delivery Networks (CDNs). The configuration parameters in the user code to communicate with these cloud services can be found in the **otauser.h** file in the `ota` project that gets automatically imported into your workspace when you import any OTA project.
![](images/cloud1.jpg)
The parameters defined in this file will be used for the `cloud_ota` labs in the following sections.
DropBox
---------
The first cloud service that will be examined is [DropBox](https://www.dropbox.com/). To get started with DropBox first login to the Applications page on the developer website at the following URL:
[https://www.dropbox.com/developers/apps](https://www.dropbox.com/developers/apps)
From here click the Create app button and create a custom application similar to the parameters below.
![](images/cloud2.png)
On the next page scroll down to the **Generate access token** field under the **OAuth 2** section. Click the **Generate** button. This will generate an access token that your `cloud_ota` example will use to connect and authenticate to your DropBox application.
![](images/cloud3.png)
Copy the generated access token to your clipboard. Back in Code Composer Studio, open the **otauser.h** file and scroll down to the following section:
```c
/* Dropbox V2 server info */
#define OTA_SERVER_NAME "api.dropboxapi.com"
#define OTA_SERVER_IP_ADDRESS 0x00000000
#define OTA_SERVER_SECURED 1
/* Dropbox V2 vendor info */
#define OTA_VENDOR_TOKEN ""
#define OTA_SERVER_ROOT_CA_CERT "cloud_certificate.cer"
#define OTA_SERVER_AUTH_IGNORE_DATA_TIME_ERROR
#define OTA_SERVER_AUTH_DISABLE_CERT_STORE
```**otauser.h**
Paste the generated access token into the `OTA_VENDOR_TOKEN` define. Scroll up to the top of the file to the following section:
```c
/* USER SHOULD DEFINE HERE WHICH CLOUD TO USE */
/* -------------------------------------------*/
//#define OTA_SERVER_TYPE OTA_SERVER_GITHUB
#define OTA_SERVER_TYPE OTA_SERVER_DROPBOX_V2
/* OTA server info */
/* --------------- */
#define OTA_VENDOR_DIR ""
```**otauser.h**
Make sure that `OTA_SERVER_DROPBOX_V2` is defined as the `OTA_SERVER_TYPE`. For the `OTA_VENDOR_DIR` specify the string that of a folder that you want to store firmware images in on your DropBox application (in this lab we name it **FirmwareImages**).
Save all open files and compile/run the `cloud_ota` application. Not that because the header file changed in the `ota` project you may need to right click the `ota` library project and select **Clean** to make sure the latest changes are built.
When the application is run it will automatically start and wait to be provisioned. Provisioning in the `cloud_ota` application is done by use of a mobile application. You can either user [SimpleLink SDK Explorer](https://itunes.apple.com/us/app/simplelink-sdk-explorer/id1237329921?mt=8) (for iOS) or [SimpleLink Starter Pro](https://www.ti.com/tool/wifistarterpro) (for iOS and Android). Please refer to the links in the [support section of this document](#where-to-find-support) to find detailed user's guides on how to provision via a mobile application.
![](images/cloud6.png)
After provisioned, you should see the device starting to ping the remove server as seen below:
![](images/cloud7.png)
Next, go back to the [Apps Homepage in DropBox](https://www.dropbox.com/home/Apps). You should now see a new folder with the name of the application that you created (in our case CC3120OTATest).
![](images/cloud4.png)
Click on this folder. Inside this folder is the root directory as it is seen by your `cloud_ota` application. From here make a new folder with the name of **FirmwareImages** and open the folder. This is the folder where you will upload the firmware package that you created in the [building a firmware image section](#building-an-msp432p4-firmware-image) of this document.
Select **Upload files** from the menu box. Navigate to the directory of your Tar file and upload your file to DropBox.
![](images/cloud5.png)
At this point if you press the **S1 Button** (this initates the firmware update) on the left side of your LaunchPad you will likely be greeted with the following error in the terminal output:
```
OTA_run: call CdnClient_ConnectServer OTA server=api.dropboxapi.com
CdnClient_ConnectServer: HttpClient_Connect api.dropboxapi.com
HttpClient_Connect: IP_ADDR=162.125.8.7
HttpClient_Connect: ERROR Socket Connect, status=-456
CdnClient_ConnectServer: ERROR HttpClient_Connect, Status=-20304
OTA_run: ERROR CdnClient_ConnectServer, Status=-20304
_OtaCheckConsecutiveErrors: ConsecutiveOtaErrors=5/5, MAX_CONSECUTIVE_OTA_ERRORS!!!
OtaRunStep: FATAL ERROR from Ota_run -21003 !!!!!!!!!!!!!!!!!!!!!!!!!!!
Test failed: State = 6, Event = 17
Event handler failed..!!
```
This error occurs when the certificate used for verification with the cloud server (DropBox in this case) does not exist on the CC3120's filesystem or is not valid. In order for the cloud communication to work we must program the correct certificate to the flash storage of the CC3120.
One of the common certificates used by DropBox is titled `DigiCert High Assurance EV Root CA`. If you've visited DropBox via the web then chances are that this certificate is installed locally on your computer. You can also search any popular search engine and freely download this certificate.
To see a list of certificates currently installed on your system using [Google Chrome](https://www.google.com/chrome/browser/desktop/index.html), go to the **Settings** pane and search for **Certificates**:
![](images/cloud10.png)
From here click **Manage certificates** to open up the certificate manager. Select the **Trusted Root Certification Authorities** and scroll down to `DigiCert High Assurance EV Root CA`.
![](images/cloud11.png)
Click on Export. When prompted for the certificate type, select **DER encoded binary x.509 (.CER)**.
![](images/cloud16.png)
Follow the following prompts and save the certificate to a known location with a file name of **cloud_certificate.cer**. Next, open the Uniflash application and create a new project the same way that is described in the [building a firmware image section](#building-an-msp432p4-firmware-image).
![](images/cloud12.png)
Next, mount the CC31XXEMUBOOST module on your CC3120 BoosterPack and connect the USB cable from your PC to the right USB port on the CC31XX module as seen below:
![](images/uniflash_2.jpg)
Click **Connect** on the right side of the Uniflash window to open an active connection to the CC3120. From here, click on the small file icon next to the **Disconnect** button to the right.
![](images/cloud17.png)
This will probe the CC3120 and display a listing of all of the user files currently programmed to the CC3120's flash storage.
![](images/cloud14.png)
Press the add button in the root directory and add the **cloud_certificate.cer** that you exported from the earlier step.
![](images/cloud15.png)
It is also important to ensure that the OTA certificate used for SHA-256 hash generation exists in the file system (see the [Local OTA section](#lab-1-local-over-the-air-update)).
![](images/cloud18.png)
Disconnect from the device using the **Disconnect** button to the right, remove the CC31XXEMUBOOST module, and plug in the LaunchPad to your PC. Open the serial terminal and initiate the firmware update by pressing the S1 button (the button on the left of the MSP432 LaunchPad).
The `cloud_ota` program will now proceed to connect to DropBox, detect that a new firmware package has been uploaded, and then download/flash the firmware file from DropBox.
![](images/cloud19.png)
[[r Invalid Certificate
If the certificate is still invalid the name of the certificate will be displayed. Repeat the steps to download/program the CC3120 with the correct certificate.
]]
Note that the name of the certificate used by the OTA library to authenticate with DropBox can be manually specified using the following define in **otauser.h**
```c
#define OTA_SERVER_ROOT_CA_CERT "cloud_certificate.cer"
#define OTA_SERVER_AUTH_IGNORE_DATA_TIME_ERROR
#define OTA_SERVER_AUTH_DISABLE_CERT_STORE
```**otauser.h**
As with the `local_ota` application, the microcontroller will reboot itself after the firmware has been updated, the LED on LED2 will turn blue, and the new firmware will be flashed/run.
GitHub
---------
Note that the GitHub portion of the `cloud_ota` code example is very similar to the DropBox portion. Many of the same concepts (such as installing the right certificates) apply exactly to the GitHub portion as they do the DropBox portion.
To get started with cloud updates through GitHub first open the **otauser.h** file located in the **ota** project. Scroll to the following lines of code:
```
#define OTA_SERVER_GITHUB 1
#define OTA_SERVER_DROPBOX_V2 2
#define OTA_SERVER_CUSTOM 99
/* USER SHOULD DEFINE HERE WHICH CLOUD TO USE */
/* -------------------------------------------*/
#define OTA_SERVER_TYPE OTA_SERVER_GITHUB
//#define OTA_SERVER_TYPE OTA_SERVER_DROPBOX_V2
```**otauser.h**
Ensure that `OTA_SERVER_TYPE` is set to `OTA_SERVER_GITHUB` and then scroll down to the following definitions:
```
/* Github server info */
#define OTA_SERVER_NAME "api.github.com"
#define OTA_SERVER_IP_ADDRESS 0x00000000
#define OTA_SERVER_SECURED 1
/* Github vendor info */
#define OTA_VENDOR_ROOT_DIR \
"/repos//"
#define OTA_VENDOR_TOKEN ""
#define OTA_SERVER_ROOT_CA_CERT "cloud_certificate.cer"
#define OTA_SERVER_AUTH_IGNORE_DATA_TIME_ERROR
#define OTA_SERVER_AUTH_DISABLE_CERT_STORE
```**otauser.h**
No special access token needs to be generated for GitHub as we did on DropBox. For the **<user\_account\>** put your GitHub user account and for the **<user_directory>** put the name of the repository where you want to store firmware images. Make sure that the **cloud_certificate.cer** is programmed in the correct location as described in the DropBox section.
The **OTA_VENDOR_TOKEN** for GitHub should be set to the user account that contains the relevant repository that you are probing.
Also make sure that a valid value is specified for the following line on top of **otauser.h**
```c
/* OTA server info */
/* --------------- */
#define OTA_VENDOR_DIR "FirmwareImages"
```**otauser.h**
This will be the folder within the specified git repository that the `cloud_ota` project will be probing for firmware images. After all of the relevant information is filled out, build/run the `cloud_ota` application. Once run, the program will connect to the provisioned access point and start pinging the resolved gateway.
![](images/cloud7.png)
Through a git client of your choice (command line git is shown below), clone your configured repository, add your new firmware image to the **FirmwareImages** directory, and then push your local changes to GitHub. An example of this can be seen below.
![](images/cloud20.png)
Once pushed, press the S1 button on the LaunchPad to initiate the firmware update. Once initiated, the device will connect to GitHub, detect a new version of the firmware, and then download/flash the firmware to the MSP432 and CC3120.
![](images/cloud21.png)
[[y Invalid Certificate
Note that if an invalid certificate or HTTP connection error is thrown please refer to the section of exporting/flashing a custom certificate in the DropBox example.
]]
Where to Find Support
==================================
For provisioning mobile applications please refer to the relevant documentation in the [provisioning SimpleLink Academy page](http://dev.ti.com/tirex/#/?link=Software%2FSimpleLink%20CC3220%20SDK%2FSimpleLink%20Academy%2FLabs%2FWi-Fi%2FWi-Fi%20Provisioning). The following two mobile applications are supported.
- [SimpleLink SDK Explorer](https://itunes.apple.com/us/app/simplelink-sdk-explorer/id1237329921?mt=8) (iOS only)
- [Simplelink WiFi Starter Pro](https://www.ti.com/tool/wifistarterpro) (iOS and Android)
Support is encouraged through use of the [TI E2E Community](https://e2e.ti.com/). Additional support can be garnered through the various documentation provided with the underlying SimpleLink SDK WiFi Plugin package.