mirror of https://github.com/FOME-Tech/fome-fw.git
576 lines
21 KiB
C++
Executable File
576 lines
21 KiB
C++
Executable File
/**
|
|
*
|
|
* \file
|
|
*
|
|
* \brief NMC1500 IoT OTA Interface.
|
|
*
|
|
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
|
|
*
|
|
* \asf_license_start
|
|
*
|
|
* \page License
|
|
*
|
|
* Subject to your compliance with these terms, you may use Microchip
|
|
* software and any derivatives exclusively with Microchip products.
|
|
* It is your responsibility to comply with third party license terms applicable
|
|
* to your use of third party software (including open source software) that
|
|
* may accompany Microchip software.
|
|
*
|
|
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
|
|
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
|
|
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
|
|
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
|
|
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
|
|
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
|
|
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
|
|
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
|
|
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
|
|
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
|
|
*
|
|
* \asf_license_stop
|
|
*
|
|
*/
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
INCLUDES
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
#include "common/include/nm_common.h"
|
|
#include "driver/include/m2m_types.h"
|
|
#include "driver/include/m2m_ota.h"
|
|
#include "driver/source/m2m_hif.h"
|
|
#include "spi_flash/include/spi_flash.h"
|
|
#include "driver/include/m2m_wifi.h"
|
|
#include "spi_flash/include/flexible_flash.h"
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
MACROS
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
DATA TYPES
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
|
|
static tpfOtaNotifCb gpfOtaNotifCb = NULL;
|
|
static tpfFileGetCb gpfHFDGetCb = NULL;
|
|
static tpfFileReadCb gpfHFDReadCb = NULL;
|
|
static tpfFileEraseCb gpfHFDEraseCb = NULL;
|
|
|
|
typedef struct {
|
|
uint32 u32Offset;
|
|
uint32 u32Size;
|
|
} FileBlockDescriptor;
|
|
|
|
static FileBlockDescriptor FileBlock;
|
|
|
|
static uint8 gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
|
|
static uint8 gu8OTASSLOpts = 0;
|
|
static uint8 gu8SNIServerName[64] = {0};
|
|
|
|
/* Map OTA SSL flags to SSL socket options */
|
|
#define WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH NBIT1
|
|
#define WIFI_OTA_SSL_FLAG_SNI_VALIDATION NBIT6
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
FUNCTION PROTOTYPES
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
|
|
/**
|
|
@fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
|
|
@brief Internal OTA call back function.
|
|
@param[in] u8OpCode
|
|
HIF Opcode type.
|
|
@param[in] u16DataSize
|
|
HIF data length.
|
|
@param[in] u32Addr
|
|
HIF address.
|
|
*/
|
|
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
|
|
{
|
|
sint8 s8Ret = M2M_SUCCESS;
|
|
if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
|
|
{
|
|
tstrOtaUpdateInfo strOtaUpdateInfo;
|
|
m2m_memset((uint8 *)&strOtaUpdateInfo, 0, sizeof(tstrOtaUpdateInfo));
|
|
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaUpdateInfo, sizeof(tstrOtaUpdateInfo), 0);
|
|
if(s8Ret == M2M_SUCCESS)
|
|
{
|
|
if(gpfOtaNotifCb)
|
|
gpfOtaNotifCb(&strOtaUpdateInfo);
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
|
|
{
|
|
tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
|
|
m2m_memset((uint8 *)&strOtaUpdateStatusResp, 0, sizeof(tstrOtaUpdateStatusResp));
|
|
s8Ret = hif_receive(u32Addr, (uint8 *) &strOtaUpdateStatusResp, sizeof(tstrOtaUpdateStatusResp), 0);
|
|
if(s8Ret == M2M_SUCCESS)
|
|
{
|
|
if(gpfOtaUpdateCb)
|
|
gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType, strOtaUpdateStatusResp.u8OtaUpdateStatus);
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_STATUS)
|
|
{
|
|
tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp;
|
|
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp), 1);
|
|
if(M2M_SUCCESS == s8Ret)
|
|
{
|
|
if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) {
|
|
gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler;
|
|
}
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_DOWNLOAD)
|
|
{
|
|
tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp;
|
|
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp), 1);
|
|
if(M2M_SUCCESS == s8Ret)
|
|
{
|
|
if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) {
|
|
gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler;
|
|
M2M_INFO("Generated HostFileHandlerID is %u\n", gu8CurrFileHandlerID);
|
|
}
|
|
|
|
if(gpfHFDGetCb) {
|
|
gpfHFDGetCb(strOtaHostFileGetStatusResp.u8OtaFileGetStatus, gu8CurrFileHandlerID, strOtaHostFileGetStatusResp.u32OtaFileSize);
|
|
gpfHFDGetCb = NULL;
|
|
}
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_READ)
|
|
{
|
|
tstrOtaHostFileReadStatusResp strOtaHostFileReadStatusResp;
|
|
m2m_memset((uint8 *)&strOtaHostFileReadStatusResp, 0, sizeof(tstrOtaHostFileReadStatusResp));
|
|
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp), 1);
|
|
if(M2M_SUCCESS == s8Ret)
|
|
if(gpfHFDReadCb)
|
|
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz);
|
|
}
|
|
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
|
|
{
|
|
tstrOtaHostFileEraseStatusResp strOtaHostFileEraseStatusResp;
|
|
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileEraseStatusResp, sizeof(tstrOtaHostFileEraseStatusResp), 1);
|
|
if(M2M_SUCCESS == s8Ret)
|
|
{
|
|
if(gpfHFDEraseCb)
|
|
{
|
|
gpfHFDEraseCb(strOtaHostFileEraseStatusResp.u8OtaFileEraseStatus);
|
|
gpfHFDEraseCb = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
M2M_ERR("Invalid OTA resp %d ?\n", u8OpCode);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
|
|
@brief Initialize the OTA layer.
|
|
@param[in] pfOtaUpdateCb
|
|
OTA Update callback function.
|
|
@param[in] pfOtaNotifCb
|
|
OTA Notify callback function.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
if(pfOtaUpdateCb) {
|
|
gpfOtaUpdateCb = pfOtaUpdateCb;
|
|
} else {
|
|
M2M_ERR("Invalid Ota update cb\n");
|
|
}
|
|
if(pfOtaNotifCb) {
|
|
gpfOtaNotifCb = pfOtaNotifCb;
|
|
} else {
|
|
M2M_ERR("Invalid Ota notify cb\n");
|
|
}
|
|
|
|
hif_register_cb(M2M_REQ_GROUP_OTA, m2m_ota_cb);
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_STATUS, NULL, 0, NULL, 0, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
|
|
@brief Set the OTA url.
|
|
@param[in] u8Url
|
|
The url server address.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_notif_set_url(uint8 *u8Url)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
|
|
/*Todo: we may change it to data pkt but we need to give it higher priority
|
|
but the priority is not implemented yet in data pkt
|
|
*/
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_SET_URL, u8Url, u16UrlSize, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_notif_check_for_update(void)
|
|
@brief Check for OTA update.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_notif_check_for_update(void)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
|
|
@brief Schedule OTA update.
|
|
@param[in] u32Period
|
|
Period in days
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
|
|
@brief Request OTA start update using the downloaded URL.
|
|
@param[in] pcDownloadUrl
|
|
The download firmware URL, you get it from device info.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_start_update(unsigned char *pcDownloadUrl)
|
|
{
|
|
tstrOtaStart strOtaStart;
|
|
uint16 u16UrlLen = m2m_strlen(pcDownloadUrl);
|
|
if (u16UrlLen >= 255)
|
|
{
|
|
return M2M_ERR_INVALID_ARG;
|
|
}
|
|
|
|
m2m_memset((uint8*)&strOtaStart, 0, sizeof(strOtaStart));
|
|
m2m_memcpy((uint8*)&strOtaStart.acUrl, (uint8*)pcDownloadUrl, u16UrlLen);
|
|
|
|
/* Convert SSL options to flags */
|
|
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH)
|
|
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH;
|
|
|
|
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_SNI_VALIDATION)
|
|
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_SNI_VALIDATION;
|
|
|
|
m2m_memcpy((uint8*)&strOtaStart.acSNI, gu8SNIServerName, m2m_strlen(gu8SNIServerName));
|
|
|
|
strOtaStart.u32TotalLen = sizeof(strOtaStart);
|
|
|
|
return hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_FW_UPDATE_V2 | M2M_REQ_DATA_PKT, (uint8*)&strOtaStart, strOtaStart.u32TotalLen, NULL, 0, 0);
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_rollback(void)
|
|
@brief Request OTA Rollback image.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_rollback(void)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ROLLBACK_FW, NULL, 0, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_abort(void)
|
|
@brief Request OTA Abort.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_abort(void)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ABORT, NULL, 0, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_switch_firmware(void)
|
|
@brief Switch to the upgraded Firmware.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_switch_firmware(void)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_SWITCH_FIRMWARE, NULL, 0, NULL, 0, 0);
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
|
|
@brief Get the OTA Firmware version.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
ret = hif_chip_wake();
|
|
if(ret == M2M_SUCCESS)
|
|
{
|
|
ret = nm_get_ota_firmware_info(pstrRev);
|
|
hif_chip_sleep();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
|
|
@brief Download a file from a remote location and store it in the WINC's Flash.
|
|
@param[in] pcDownloadUrl
|
|
Url pointing to the remote file. HTTP/HTTPS only.
|
|
@param[in] pfHFDGetCb
|
|
Pointer to a callback to be executed when the download finishes.
|
|
@return Status of the get operation.
|
|
@warning Providing a callback is mandatory.
|
|
*/
|
|
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
|
|
{
|
|
sint8 s8Ret = M2M_ERR_FAIL;
|
|
uint16 u16DUrlSize = m2m_strlen(pcDownloadUrl);
|
|
|
|
if((NULL == pfHFDGetCb) || (0 == u16DUrlSize))
|
|
{
|
|
M2M_ERR("Invalid parameters.\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
if('\0' != pcDownloadUrl[u16DUrlSize])
|
|
pcDownloadUrl[u16DUrlSize] = '\0';
|
|
else
|
|
u16DUrlSize++;
|
|
|
|
M2M_INFO("GetHostFile - URL: %s, urlSize: %u\n", pcDownloadUrl, u16DUrlSize);
|
|
|
|
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_DOWNLOAD, pcDownloadUrl, u16DUrlSize, NULL, 0, 0);
|
|
if(s8Ret == M2M_SUCCESS)
|
|
{
|
|
gpfHFDGetCb = pfHFDGetCb;
|
|
gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
|
|
}
|
|
|
|
EXIT:
|
|
return s8Ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
|
|
@brief Read a certain amount of bytes from a file in WINC's Flash using HIF transfer.
|
|
@param[in] u8Handler
|
|
ID of the file we are trying to read from. Must be valid.
|
|
@param[in] u32Offset
|
|
Offset from start of the file to read from (in bytes).
|
|
@param[in] u32Size
|
|
The amount of data to read (in bytes).
|
|
@param[in] pfHFDReadCb
|
|
Callback to be executed when the read operation completes.
|
|
@return Status of the read operation.
|
|
@warning Providing a callback is mandatory.
|
|
*/
|
|
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
|
|
{
|
|
sint8 s8Ret = M2M_ERR_INVALID_ARG;
|
|
FileBlock.u32Offset = u32Offset;
|
|
FileBlock.u32Size = u32Size;
|
|
|
|
if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pfHFDReadCb)) goto EXIT;
|
|
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_READ, (uint8 *) &FileBlock, sizeof(FileBlockDescriptor), NULL, 0, 0);
|
|
|
|
if(M2M_SUCCESS == s8Ret)
|
|
gpfHFDReadCb = pfHFDReadCb;
|
|
EXIT:
|
|
return s8Ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
|
|
@brief Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
|
|
@param[in] u8Handler
|
|
ID of the file we are trying to read from. Must be valid.
|
|
@param[in] pu8Buff
|
|
Pointer to a buffer to store the data being read. Must be valid.
|
|
@param[in] u32Offset
|
|
Offset from start of the file to read from (in bytes).
|
|
@param[in] u32Size
|
|
The amount of data to read (in Bytes).
|
|
@return Status of the read operation.
|
|
@warning Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
|
|
mode to allow for a safe access to the Flash. This can be done by calling
|
|
@ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read.
|
|
*/
|
|
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
|
|
{
|
|
static uint32 u32FlashHFDStart = 0;
|
|
static uint32 u32FlashHFDSize = 0;
|
|
sint8 s8Ret = M2M_ERR_INVALID_ARG;
|
|
if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT;
|
|
|
|
if(WIFI_STATE_INIT != m2m_wifi_get_state())
|
|
{
|
|
s8Ret = M2M_ERR_FAIL;
|
|
M2M_ERR("WINC is not in an appropriate state for this operation!\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
if((u32FlashHFDStart == 0) || (u32FlashHFDSize == 0))
|
|
{
|
|
s8Ret = spi_flexible_flash_find_section(ENTRY_ID_HOSTFILE, &u32FlashHFDStart, &u32FlashHFDSize);
|
|
if(M2M_SUCCESS != s8Ret) goto EXIT;
|
|
}
|
|
|
|
s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart, 4);
|
|
|
|
if((M2M_SUCCESS != s8Ret) || (pu8Buff[0] != u8Handler)) goto EXIT;
|
|
|
|
if((u32Offset >= u32FlashHFDSize) ||
|
|
(u32Size > u32FlashHFDSize) ||
|
|
((u32Offset + u32Size) >= u32FlashHFDSize))
|
|
{
|
|
s8Ret = M2M_ERR_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart + FLASH_SECTOR_SZ + u32Offset, u32Size);
|
|
|
|
if(M2M_SUCCESS != s8Ret)
|
|
{
|
|
M2M_ERR("Unable to read SPI Flash\n");
|
|
}
|
|
|
|
EXIT:
|
|
return s8Ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
|
|
@brief Erase any traces of an existing file, this means from host driver and WINC firmware.
|
|
@param[in] u8Handler
|
|
ID of the file we are trying to erase. Must be valid.
|
|
@param[in] pfHFDEraseCb
|
|
Pointer to callback to execute when the file erase in the WINC completes.
|
|
@return Status of the erase operation.
|
|
@note Providing a callback is optional.
|
|
If the current handler is invalid at this point, it means one of the three:
|
|
1. The file never existed;
|
|
2. The file has already been already deleted;
|
|
3. The request to get the file hasn't fully completed.
|
|
For 1. and 2. there is no need to signal the WINC to erase the file in Flash.
|
|
For 3. the Flash can't be erased while a file download is ongoing.
|
|
*/
|
|
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
|
|
{
|
|
sint8 s8Ret = M2M_ERR_INVALID;
|
|
if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID)) goto EXIT;
|
|
|
|
gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
|
|
gpfHFDReadCb = NULL;
|
|
gpfHFDEraseCb = pfHFDEraseCb;
|
|
|
|
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_ERASE, NULL, 0, NULL, 0, 0);
|
|
EXIT:
|
|
return s8Ret;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
|
|
@brief Sets SSL related options for OTA via https connections
|
|
@param[in] enuOptionName
|
|
The SSL option to set, from the set defined in tenuOTASSLOption
|
|
@param[in] pOptionValue
|
|
Pointer to the option value to set. Either a pointer to a uint32 with the value of 0 or 1, or a pointer to a string for the
|
|
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
|
|
@param[in] OptionLen
|
|
The size of the option referred to in pOptionValue
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
|
|
{
|
|
if((pOptionValue == NULL) && (OptionLen > 0))
|
|
return M2M_ERR_INVALID_ARG;
|
|
|
|
switch(enuOptionName)
|
|
{
|
|
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
|
|
if(OptionLen > 64)
|
|
return M2M_ERR_INVALID_ARG;
|
|
if (m2m_strlen((uint8*)pOptionValue)+1 != OptionLen)
|
|
return M2M_ERR_INVALID_ARG;
|
|
|
|
m2m_memcpy(gu8SNIServerName, (uint8*)pOptionValue, OptionLen);
|
|
break;
|
|
|
|
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
|
|
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
|
|
if(OptionLen != sizeof(int))
|
|
return M2M_ERR_INVALID_ARG;
|
|
switch(*(int*)pOptionValue)
|
|
{
|
|
case 1:
|
|
gu8OTASSLOpts |= enuOptionName;
|
|
break;
|
|
case 0:
|
|
gu8OTASSLOpts &= ~enuOptionName;
|
|
break;
|
|
default:
|
|
return M2M_ERR_INVALID_ARG;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return M2M_ERR_INVALID_ARG;
|
|
}
|
|
return M2M_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
@fn NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *OptionLen)
|
|
@brief Gets the status of SSL related options for OTA via https connections
|
|
@param[in] enuOptionName
|
|
The SSL option to obtain the status of, from the set defined in tenuOTASSLOption
|
|
@param[in] pOptionValue
|
|
Pointer to the option value to be updated by the function. Either a pointer to a uint32, or a pointer to a buffer for the
|
|
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
|
|
@param[in] OptionLen
|
|
A pointer to a size_t type variable which will be updated to contain the size of the returned option.
|
|
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
|
|
*/
|
|
NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
|
|
{
|
|
if((pOptionValue == NULL) || (pOptionLen == NULL))
|
|
return M2M_ERR_INVALID_ARG;
|
|
|
|
switch(enuOptionName)
|
|
{
|
|
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
|
|
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
|
|
if(*pOptionLen < sizeof(int))
|
|
return M2M_ERR_INVALID_ARG;
|
|
*pOptionLen = sizeof(int);
|
|
*(int*)pOptionValue = (gu8OTASSLOpts & enuOptionName) ? 1 : 0;
|
|
break;
|
|
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
|
|
{
|
|
uint16 sni_len = m2m_strlen(gu8SNIServerName)+1;
|
|
if(*pOptionLen < sni_len)
|
|
return M2M_ERR_INVALID_ARG;
|
|
*pOptionLen = sni_len;
|
|
m2m_memcpy((uint8*)pOptionValue, gu8SNIServerName, sni_len);
|
|
}
|
|
break;
|
|
default:
|
|
return M2M_ERR_INVALID_ARG;
|
|
}
|
|
return M2M_SUCCESS;
|
|
}
|