drivers/winc: Update WINC host driver to 19.7.3

This commit is contained in:
iabdalkader 2021-05-07 23:52:03 +02:00
parent c58c7d126d
commit 4e02ad9f78
20 changed files with 4543 additions and 4090 deletions

View File

@ -4,7 +4,7 @@
*
* \brief WINC BSP API Declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -52,13 +52,13 @@
#define NMI_API
/*!<
* Attribute used to define the memory section to map Functions in host memory.
*/
* Attribute used to define the memory section to map Functions in host memory.
*/
#define CONST const
/*!<
* Used for code portability.
*/
* Used for code portability.
*/
#ifndef NULL
#define NULL ((void*)0)
@ -67,7 +67,6 @@
* Void Pointer to '0' in case NULL is not defined.
*/
#define BSP_MIN(x,y) ((x)>(y)?(y):(x))
/*!<
* Computes the minimum value between \b x and \b y.
@ -77,7 +76,6 @@
/**@addtogroup DataT
* @{
*/
/*!
* @typedef void (*tpfNmBspIsr) (void);
* @brief Pointer to function.\n Used as a data type of ISR function registered by
@ -86,53 +84,53 @@
*/
typedef void (*tpfNmBspIsr)(void);
/*!
* @ingroup DataTypes
* @typedef unsigned char uint8;
* @brief Range of values between 0 to 255
*/
/*!
* @ingroup DataTypes
* @typedef unsigned char uint8;
* @brief Range of values between 0 to 255
*/
typedef unsigned char uint8;
/*!
* @ingroup DataTypes
* @typedef unsigned short uint16;
* @brief Range of values between 0 to 65535
*/
/*!
* @ingroup DataTypes
* @typedef unsigned short uint16;
* @brief Range of values between 0 to 65535
*/
typedef unsigned short uint16;
/*!
* @ingroup Data Types
* @typedef unsigned long uint32;
* @brief Range of values between 0 to 4294967295
*/
/*!
* @ingroup Data Types
* @typedef unsigned long uint32;
* @brief Range of values between 0 to 4294967295
*/
typedef unsigned long uint32;
/*!
* @ingroup Data Types
* @typedef signed char sint8;
* @brief Range of values between -128 to 127
*/
/*!
* @ingroup Data Types
* @typedef signed char sint8;
* @brief Range of values between -128 to 127
*/
typedef signed char sint8;
/*!
* @ingroup DataTypes
* @typedef signed short sint16;
* @brief Range of values between -32768 to 32767
*/
/*!
* @ingroup DataTypes
* @typedef signed short sint16;
* @brief Range of values between -32768 to 32767
*/
typedef signed short sint16;
/*!
* @ingroup DataTypes
* @typedef signed long sint32;
* @brief Range of values between -2147483648 to 2147483647
*/
/*!
* @ingroup DataTypes
* @typedef signed long sint32;
* @brief Range of values between -2147483648 to 2147483647
*/
typedef signed long sint32;
/**@}*/ //DataTypes
#ifndef CORTUS_APP
#ifdef __cplusplus
extern "C"{
extern "C" {
#endif
/** @defgroup NmBspInitFn nm_bsp_init
@ -141,8 +139,8 @@ extern "C"{
* such as Reset and Chip Enable Pins for WINC, delays, register ISR, enable/disable IRQ for WINC, etc.
* You must use this function at the head of your application to enable WINC and Host Driver to
* communicate with each other.
* @{
*/
/**@{*/
/*!
* @fn sint8 nm_bsp_init(void);
* @brief This function is used to initialize the <strong>B</strong>oard <strong>S</strong>upport
@ -157,7 +155,7 @@ extern "C"{
* @ref nm_bsp_reset.
*
* @note Implementation of this function is host dependent.
* @warning Inappropriate use of this function will lead to unavailability of host-chip communication.
* @warning Omitting this function will lead to unavailability of host-chip communication.
*
* @see nm_bsp_deinit, nm_bsp_reset
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
@ -166,12 +164,12 @@ sint8 nm_bsp_init(void);
/**@}*/ //NmBspInitFn
/** @defgroup NmBspDeinitFn nm_bsp_deinit
/** @defgroup NmBspDeinitFn nm_bsp_deinit
* @ingroup BSPAPI
* De-initialization of the BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage).\n
* This function should be called only after a successful call to @ref nm_bsp_init.
* @{
*/
/**@{*/
/*!
* @fn sint8 nm_bsp_deinit(void);
* @brief This function is used to de-initialize the BSP and turn off the WINC board.
@ -182,7 +180,7 @@ sint8 nm_bsp_init(void);
* consuming higher power than expected, since it won't be properly de-initialized.
* @pre The BSP should be initialized through @ref nm_bsp_init first.
* @note Implementation of this function is host dependent.
* @warning Misuse may lead to unknown behavior in case of soft reset.
* @warning Omitting this function may lead to unknown behavior in case of soft reset.
* @see nm_bsp_init
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
@ -190,15 +188,14 @@ sint8 nm_bsp_init(void);
sint8 nm_bsp_deinit(void);
/**@}*/ //NmBspDeinitFn
/** @defgroup NmBspResetFn nm_bsp_reset
* @ingroup BSPAPI
* @ingroup BSPAPI
* Resets the WINC SoC by setting CHIP_EN and RESET_N signals low, then after an appropriate delay,
* this function will put CHIP_EN high then RESET_N high, for more details on the timing between signals
* please check the WINC data-sheet.
*/
/**@{*/
/*!
* @{
*/
/*!
* @fn void nm_bsp_reset(void);
* @brief Performs a hardware reset to the WINC board.
* @details The nm_bsp_reset is used to perform a hard reset on the WINC board by setting CHIP_EN and
@ -212,24 +209,22 @@ sint8 nm_bsp_deinit(void);
* de-initialized before calling nm_bsp_reset and initialized again, which can be achieved by
* use of @ref m2m_wifi_init and @ref m2m_wifi_deinit.
* @pre Initialize the BSP first by calling @ref nm_bsp_init.
* @note Implementation of this function is host dependent and it is called by HIF layer.
* @warning Calling this function will drop any connection and lose the internal state saved on the
* WINC firmware.
* @note Implementation of this function is host dependent and called by HIF layer.
* @warning Calling this function will drop any connection and lose the internal state saved on the WINC firmware.
* @see nm_bsp_init, m2m_wifi_init, m2m_wifi_deinit
* @return None
*/
*/
void nm_bsp_reset(void);
/**@}*/ //NmBspResetFn
/** @defgroup NmBspSleepFn nm_bsp_sleep
* @ingroup BSPAPI
* Sleep in units of milliseconds.\n
* This function used by the HIF Layer on several different scenarios.
*/
/**@{*/
* @ingroup BSPAPI
* Sleep in units of milliseconds.\n
* This function used by the HIF Layer on several different scenarios.
* @{
*/
/*!
* @fn void nm_bsp_sleep(uint32);
* @fn void nm_bsp_sleep(uint32 u32TimeMsec);
* @brief Used to put the host to sleep for the specified duration (in milliseconds).
* Forcing the host to sleep for extended period may lead to host not being able to respond
* to WINC board events. It is important to be considerate while choosing the sleep period.
@ -244,13 +239,12 @@ void nm_bsp_reset(void);
void nm_bsp_sleep(uint32 u32TimeMsec);
/**@}*/ //NmBspSleepFn
/** @defgroup NmBspRegisterFn nm_bsp_register_isr
* @ingroup BSPAPI
* Register ISR (Interrupt Service Routine) in the initialization of the HIF (Host Interface) Layer.
* When the interrupt is triggered, the BSP layer should call the pfisr function from the interrupt handler.
*/
/**@{*/
* @ingroup BSPAPI
* Register ISR (Interrupt Service Routine) in the initialization of the HIF (Host Interface) Layer.
* When the interrupt is triggered, the BSP layer should call the pfisr function from the interrupt handler.
* @{
*/
/*!
* @fn void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
* @brief Register the host interface interrupt service routine.
@ -258,8 +252,8 @@ void nm_bsp_sleep(uint32 u32TimeMsec);
* the SPI interrupt to notify the host whenever there is an outstanding message from the WINC
* board. This function should be called during the initialization of the host interface. It is
* an internal driver function and shouldn't be called by the Application.
* @param [in] pfIsr tpfNmBspIsr
* Pointer to ISR handler in the HIF Layer.
* @param [in] pfIsr
* Pointer to ISR handler in the HIF layer.
* @note Implementation of this function is host dependent and called by HIF layer.
* @warning Make sure that ISR for IRQ pin for WINC is disabled by default in your implementation.
* @see tpfNmBspIsr
@ -268,14 +262,13 @@ void nm_bsp_sleep(uint32 u32TimeMsec);
void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
/**@}*/ //NmBspRegisterFn
/** @defgroup NmBspInterruptCtrl nm_bsp_interrupt_ctrl
* @ingroup BSPAPI
* Synchronous enable/disable of WINC to host interrupts.
*/
/**@{*/
* @ingroup BSPAPI
* Synchronous enable/disable of WINC to host interrupts.
* @{
*/
/*!
* @fn void nm_bsp_interrupt_ctrl(uint8);
* @fn void nm_bsp_interrupt_ctrl(uint8 u8Enable);
* @brief Enable/Disable interrupts from the WINC.
* @details This function can be used to enable/disable the WINC to host interrupts, depending on how
* the driver is implemented. It is an internal driver function and shouldn't be called by
@ -297,19 +290,28 @@ void nm_bsp_interrupt_ctrl(uint8 u8Enable);
#endif
/**
* @addtogroup BSPDefine
* @{
*/
#ifdef _NM_BSP_BIG_END
/*! Switch endianness of 32bit word (In the case that Host is BE) */
#define NM_BSP_B_L_32(x) \
((((x) & 0x000000FF) << 24) + \
(((x) & 0x0000FF00) << 8) + \
(((x) & 0x00FF0000) >> 8) + \
(((x) & 0xFF000000) >> 24))
/*! Switch endianness of 16bit word (In the case that Host is BE) */
#define NM_BSP_B_L_16(x) \
((((x) & 0x00FF) << 8) + \
(((x) & 0xFF00) >> 8))
#else
/*! Retain endianness of 32bit word (In the case that Host is LE) */
#define NM_BSP_B_L_32(x) (x)
/*! Retain endianness of 16bit word (In the case that Host is LE) */
#define NM_BSP_B_L_16(x) (x)
#endif
/**@}*/ //BSPDefine
#endif /*_NM_BSP_H_*/

View File

@ -4,7 +4,7 @@
*
* \brief This module contains NMC1000 bus wrapper APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -164,6 +164,19 @@ sint8 nm_bus_reinit(void *);
uint8 nm_bus_get_chip_type(void);
sint8 nm_bus_break(void);
#endif
/**
* @fn spi_rw
* @brief Process SPI Read/Write operation
* @param pu8Mosi TX Data buffer
* @param pu8Miso RX Data buffer
* @param u16Sz Transfer length
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
#ifdef CONF_WINC_USE_SPI
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -4,7 +4,7 @@
*
* \brief WINC Driver Common API Declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -45,9 +45,10 @@
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_debug.h"
#define WINC1500_EXPORT(name) winc1500_ ## name
/**@addtogroup COMMONDEF
* @{
*/
/**@{*/
#define M2M_TIME_OUT_DELAY 10000
/*states*/
@ -66,24 +67,17 @@
#define M2M_ERR_FAIL ((sint8)-12)
#define M2M_ERR_FW_VER_MISMATCH ((sint8)-13)
#define M2M_ERR_SCAN_IN_PROGRESS ((sint8)-14)
/* Invalid argument */
#define M2M_ERR_INVALID_ARG ((sint8)-15)
#define M2M_ERR_INVALID ((sint8)-16)
/*i2c MAASTER ERR*/
#define I2C_ERR_LARGE_ADDRESS 0xE1UL
/*!< The address exceeds the max addressing mode in I2C flash.
*/
#define I2C_ERR_TX_ABRT 0xE2UL
/*!< NO ACK from slave.
*/
/* I2C MASTER ERR */
#define I2C_ERR_LARGE_ADDRESS 0xE1UL /*!< The address exceeds the max addressing mode in I2C flash. */
#define I2C_ERR_TX_ABRT 0xE2UL /*!< NO ACK from slave. */
#define I2C_ERR_OVER_SIZE 0xE3UL
#define ERR_PREFIX_NMIS 0xE4UL
/*!< Wrong first four bytes in flash NMIS.
*/
#define ERR_FIRMEWARE_EXCEED_SIZE 0xE5UL
/*!< Total size of firmware exceeds the max size 256k.
*/
/**/
#define ERR_PREFIX_NMIS 0xE4UL /*!< Wrong first four bytes in flash NMIS. */
#define ERR_FIRMWARE_EXCEED_SIZE 0xE5UL /*!< Total size of firmware exceeds the max size 256k. */
#define PROGRAM_START 0x26961735UL
#define BOOT_SUCCESS 0x10add09eUL
#define BOOT_START 0x12345678UL
@ -121,28 +115,39 @@
#define NBIT1 (0x00000002)
#define NBIT0 (0x00000001)
/*! Maximum of two values */
#define M2M_MAX(A,B) ((A) > (B) ? (A) : (B))
/*! Choose one of three values */
#define M2M_SEL(x,m1,m2,m3) ((x>1)?((x>2)?(m3):(m2)):(m1))
/*! Align to next multiple of 4 */
#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val))
#define DATA_PKT_OFFSET 4
#if _BYTE_ORDER == _LITTLE_ENDIAN
#define BYTE_0(word) ((uint8)(((word) >> 0 ) & 0x000000FFUL))
#define BYTE_1(word) ((uint8)(((word) >> 8 ) & 0x000000FFUL))
/*! Most significant byte of 32bit word (LE) */
#define BYTE_0(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (LE) */
#define BYTE_1(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
/*! Third most significant byte of 32bit word (LE) */
#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
/*! Least significant byte of 32bit word (LE) */
#define BYTE_3(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
#else
/*! Most significant byte of 32bit word (BE) */
#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (BE) */
#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
#define BYTE_2(word) ((uint8)(((word) >> 8 ) & 0x000000FFUL))
#define BYTE_3(word) ((uint8)(((word) >> 0 ) & 0x000000FFUL))
/*! Third most significant byte of 32bit word (BE) */
#define BYTE_2(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
/*! Least significant byte of 32bit word (BE) */
#define BYTE_3(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
#endif
/**@}*/
/**@}*/ //COMMONDEF
#ifdef __cplusplus
extern "C" {
#endif
extern "C" {
#endif
/*!
* @ingroup COMMONAPI
@ -156,7 +161,7 @@
* Destination buffer.
* @return None
*/
NMI_API void m2m_memcpy(uint8* pDst,uint8* pSrc,uint32 sz);
NMI_API void m2m_memcpy(uint8 *pDst, uint8 *pSrc, uint32 sz);
/*!
* @ingroup COMMONAPI
@ -170,7 +175,7 @@ NMI_API void m2m_memcpy(uint8* pDst,uint8* pSrc,uint32 sz);
* The specified data buffer (whose data bytes will be set to the specified value).
* @return None
*/
NMI_API void m2m_memset(uint8* pBuf,uint8 val,uint32 sz);
NMI_API void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz);
/*!
* @ingroup COMMONAPI
@ -180,7 +185,7 @@ NMI_API void m2m_memset(uint8* pBuf,uint8 val,uint32 sz);
* Null terminated string buffer.
* @return Length of the string in the specified string buffer.
*/
NMI_API uint16 m2m_strlen(uint8 * pcStr);
NMI_API uint16 m2m_strlen(uint8 *pcStr);
/*!
* @ingroup COMMONAPI
@ -194,7 +199,7 @@ NMI_API uint16 m2m_strlen(uint8 * pcStr);
* One of two data buffers for the comparison.
* @return Zero if matched, one if not matched.
*/
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1,uint8 *pu8Buff2 ,uint32 u32Size);
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size);
/*!
* @ingroup COMMONAPI
@ -218,9 +223,9 @@ NMI_API uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len);
* One of two string buffers.
* @param [in] pcIn
* One of two string buffers.
* @return If pcStr string is part of pcIn string return a valid pointer to the start of pcStr within pcIn. If not, a NULL Pointer is returned
* @return If pcStr string is part of pcIn string return a valid pointer to the start of pcStr within pcIn. If not, a NULL Pointer is returned.
*/
NMI_API uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr);
NMI_API uint8 *m2m_strstr(uint8 *pcIn, uint8 *pcStr);
/*!
* @ingroup COMMONAPI
@ -232,7 +237,21 @@ NMI_API uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr);
* The specified data buffer (whose data bytes will be used to calculate the checksum).
* @return The calculated checksum.
*/
NMI_API uint8 m2m_checksum(uint8* buf, int sz);
NMI_API uint8 m2m_checksum(uint8 *buf, int sz);
/*!
* @ingroup COMMONAPI
* @fn sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
* @brief Converts a string of hex characters to bytes.
* @param[out] pu8Out
* Output buffer (eg {0x11, 0x12, 0x13,...})
* @param[in] pu8In
* Input buffer (eg {0x31, 0x31, 0x31, 0x32, 0x31, 0x33, ...})
* @param[in] u8SizeOut
* Length of output buffer (should be half of the length of the input buffer).
* @return @ref M2M_SUCCESS if successful, M2M_ERR_INVALID_ARG otherwise (eg unrecognised hexchar in input).
*/
sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
/*!
* @ingroup COMMONAPI
@ -242,5 +261,5 @@ NMI_API uint8 m2m_checksum(uint8* buf, int sz);
extern NMI_API void (*at_sb_printf)(const char *_format, ...);
#ifdef __cplusplus
}
#endif
#endif
#endif /*_NM_COMMON_H_*/

View File

@ -4,7 +4,7 @@
*
* \brief WINC OTA Upgrade API Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -35,10 +35,11 @@
/**@defgroup OTAAPI OTA
@brief
The WINC supports OTA (Over-The-Air) updates. Using the APIs described in this module,
it is possible to request an ATWINC15x0 to update its firmware, or safely rollback to
the previous firmware version.\n There are also APIs to download files and store them in
the WINC's Flash (supported by ATWINC1510 only), which can be used for Host MCU OTA
updates or accessing information stored remotely.
it is possible to request an ATWINC15x0 to update its firmware image, or safely rollback to
the previous firmware image.\n Note that it is NOT possible to update other areas of the WINC
flash (e.g. the HTTP file area) using the OTA mechanism.\n\n There are also APIs to download
files and store them in the WINC's Flash (supported by ATWINC1510 only), which can be used
for Host MCU OTA updates or accessing information stored remotely.
@{
@defgroup OTACALLBACKS Callbacks
@brief
@ -58,7 +59,12 @@
@defgroup OTAFUNCTIONS Functions
@brief
Lists the full set of available APIs to manage OTA updates and Host File Downloads.
@}
@{
@defgroup OTACOMMON Common
@defgroup WINCOTA WINC
@defgroup HFD HFD
@}
@}
*/
#ifndef __M2M_OTA_H__
@ -77,8 +83,8 @@ MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**@addtogroup OTACALLBACKS
* @{
*/
/**@{*/
/*!
@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *pstrOtaUpdateInfo);
@ -94,7 +100,7 @@ MACROS
@warning
The notification is not supported (Not implemented yet)
*/
typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo * pstrOtaUpdateInfo);
typedef void (*tpfOtaNotifCb)(tstrOtaUpdateInfo *pstrOtaUpdateInfo);
/*!
@ -118,7 +124,7 @@ typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo * pstrOtaUpdateInfo);
tenuOtaUpdateStatusType
tenuOtaUpdateStatus
*/
typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
typedef void (*tpfOtaUpdateCb)(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus);
/*!
@typedef void (*tpfFileGetCb) (uint8 u8Status, uint8 u8Handler, uint32 u32Size);
@ -142,7 +148,7 @@ typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateSt
by the WINC when the download finished successfully. This handler will be required
for all operations on the file like read and erase.
*/
typedef void (*tpfFileGetCb) (uint8 u8Status, uint8 u8Handler, uint32 u32Size);
typedef void (*tpfFileGetCb)(uint8 u8Status, uint8 u8Handler, uint32 u32Size);
/*!
@typedef void (*tpfFileReadCb) (uint8 u8Status, void *pBuff, uint32 u32Size);
@ -165,7 +171,7 @@ typedef void (*tpfFileGetCb) (uint8 u8Status, uint8 u8Handler, uint32 u32Size);
@warning
After the callback is executed, pBuff will be freed.
*/
typedef void (*tpfFileReadCb) (uint8 u8Status, void *pBuff, uint32 u32Size);
typedef void (*tpfFileReadCb)(uint8 u8Status, void *pBuff, uint32 u32Size);
/*!
@typedef void (*tpfFileEraseCb) (uint8 u8Status);
@ -176,49 +182,49 @@ typedef void (*tpfFileReadCb) (uint8 u8Status, void *pBuff, uint32 u32Size);
@param[in] u8Status
Status of the operation (see @ref tenuOtaUpdateStatus).
*/
typedef void (*tpfFileEraseCb) (uint8 u8Status);
typedef void (*tpfFileEraseCb)(uint8 u8Status);
/**@}*/ //OTACALLBACKS
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/** @addtogroup OTAFUNCTIONS
*/
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
/**@{*/
/*!
@ingroup OTACOMMON
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb)
sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Synchronous initialization function for the OTA layer by registering the update callback.\n
The notification callback is not supported at the current version. Calling this API is a
MUST for all the OTA API's.
@param [in] pfOtaUpdateCb
@param[in] pfOtaUpdateCb
OTA Update callback function.
@param [in] pfOtaNotifCb
@param[in] pfOtaNotifCb
OTA Notify callback function.
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb);
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA notification server URL, the functions need to be called before any check for update.\n
Set the OTA notification server URL, the function needs to be called before any check for update.\n
This functionality is not supported by WINC firmware.
@param [in] u8Url
Set the OTA notification server URL, the functions need to be called before any check for update.
@param[in] u8Url
Set the OTA notification server URL, the function needs to be called before any check for update.
@pre
Prior calling of @ref m2m_ota_init is required.
@ -232,11 +238,12 @@ NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNo
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
NMI_API sint8 m2m_ota_notif_set_url(uint8 *u8Url);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
sint8 m2m_ota_notif_check_for_update(void);
@brief
Synchronous function to check for the OTA update using the Notification Server URL.\n
@ -255,14 +262,15 @@ NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
NMI_API sint8 m2m_ota_notif_check_for_update(void);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA notification Server check for update request after specific number of days.\n
Function is not implemented (not supported at the current version).
@param [in] u32Period
@param[in] u32Period
Period in days
@warning
@ -279,25 +287,27 @@ NMI_API sint8 m2m_ota_notif_check_for_update(void);
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
@brief
Request OTA start update using the download URL, the OTA module will download the OTA image, ensure integrity of the image
Request OTA start update using the download URL. The OTA module will download the OTA image, ensure integrity of the image
and update the validity of the image in the control structure. On completion, a callback of type @ref tpfOtaUpdateCb is called
(callback previously provided via m2m_ota_init).
(callback previously provided via @ref m2m_ota_init). Switching to the updated image additionally requires completion of
@ref m2m_ota_switch_firmware and @ref system_reset.
@param [in] pcDownloadUrl
@param[in] pcDownloadUrl
The download firmware URL, according to the application server.
@warning
Calling this API does not guarantee OTA WINC image update, it depends on the connection with the
download server and the validity of the image.\n
Calling this API invalidates any previous valid rollback image. When the OTA succeeds, the current
image will become the rollback image after @ref m2m_ota_switch_firmware.
Calling this API invalidates any previous valid rollback image, irrespective of the result, but when
the OTA succeeds, the current image will become the rollback image after @ref m2m_ota_switch_firmware.
@pre
@ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update().\n
@ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update.\n
Switching to the newly downloaded image requires calling @ref m2m_ota_switch_firmware API.
@sa
@ -307,97 +317,123 @@ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
Note that successful operation in this context means the OTA update request has reached the firmware OTA module.
It does not indicate whether or not the image update succeeded.
\section OTAExample Example
@section OTAExample Example
This example shows how an OTA image update and switch is carried out.
It demonstrates use of the following OTA APIs:
@ref m2m_ota_init
@ref tpfOtaUpdateCb
@ref m2m_ota_start_update
@ref m2m_ota_switch_firmware
@ref m2m_ota_rollback
- @ref m2m_ota_init
- @ref tpfOtaUpdateCb
- @ref m2m_ota_start_update
- @ref m2m_ota_switch_firmware
- @ref m2m_ota_rollback
@code
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus)
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus)
{
if(u8OtaUpdateStatusType == DL_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) {
//switch to the upgraded firmware
M2M_INFO("%d %d\n", u8OtaUpdateStatusType, u8OtaUpdateStatus);
switch(u8OtaUpdateStatusType)
{
case DL_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("OTA download succeeded\n");
// In this case the application MAY WANT TO update the host driver before calling
// @ref m2m_ota_switch_firmware(). Switching firmware image and resetting without
// updating host driver may lead to suboptimal functionality.
// Switch to the upgraded firmware
M2M_INFO("Now switching active partition...\n");
m2m_ota_switch_firmware();
}
break;
case SW_STATUS:
case RB_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("Switch/Rollback succeeded\n");
// Start the host SW upgrade if required, then system reset is required (Reinitialize the driver)
M2M_INFO("Now resetting the system...\n");
system_reset();
}
else if(u8OtaUpdateStatusType == SW_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) {
M2M_INFO("Now OTA successfully done");
//start the host SW upgrade then system reset is required (Reinitialize the driver)
}
break;
}
}
void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg)
static void wifi_event_cb(uint8 u8WiFiEvent, void *pvMsg)
{
// ...
case M2M_WIFI_REQ_DHCP_CONF:
{
//after successfully connection, start the over air upgrade
// After successful connection, start the OTA upgrade
m2m_ota_start_update(OTA_URL);
}
break;
default:
break;
// ...
}
int main (void)
{
sint8 s8Ret;
tstrWifiInitParam param;
sint8 s8Ret = M2M_SUCCESS;
bool rollback_required = FALSE;
tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS;
nm_bsp_init();
// System init, etc should be here...
m2m_memset((uint8*)&param, 0, sizeof(param));
param.pfAppWifiCb = wifi_event_cb;
//Initialize the WINC Driver
// Initialize the WINC Driver
s8Ret = m2m_wifi_init(&param);
if(s8Ret == M2M_ERR_FW_VER_MISMATCH)
{
M2M_ERR("Firmware version mismatch\n");
}
if (M2M_SUCCESS != s8Ret)
{
M2M_ERR("Driver Init Failed <%d>\n",s8Ret);
while(1);
}
//Initialize the OTA module
// Initialize the OTA module
m2m_ota_init(OtaUpdateCb,NULL);
//connect to AP that provide connection to the OTA server
// Connect to AP that provides connection to the OTA server
m2m_wifi_default_connect();
while(1)
{
//Handle the app state machine plus the WINC event handler
// Handle the app state machine plus the WINC event handler
while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) {
}
}
}
@endcode
*/
NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
NMI_API sint8 m2m_ota_start_update(unsigned char *pcDownloadUrl);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_rollback(void);
sint8 m2m_ota_rollback(void);
@brief
Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the Roll-back image
and activate it if valid. On completion, a callback of type tpfOtaUpdateCb is called (application must previously have
provided the callback via m2m_ota_init). If the callback indicates successful activation, the newly-activated image
Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the inactive image
and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb is called (application must previously have
provided the callback via @ref m2m_ota_init). If the callback indicates successful activation, the newly-activated image
will start running after next system reset.
@warning
If rollback requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this
API.\n
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware.
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@sa
m2m_ota_init
@ -409,35 +445,40 @@ NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
NMI_API sint8 m2m_ota_rollback(void);
/*!
@ingroup OTACOMMON
@fn \
NMI_API sint8 m2m_ota_abort(void);
sint8 m2m_ota_abort(void);
@brief
Request the WINC to abort an OTA or Host File download in progress.\n
If no download is in progress, the API will respond with failure.
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
The function returns @ref M2M_SUCCESS for a successful operation and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
sint8 m2m_ota_switch_firmware(void);
@brief
Request switch to the updated WINC image. The WINC firmware will check the validity of the
inactive image and activate it if it is valid. On completion, a callback of type @ref tpfOtaUpdateCb
inactive image and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb
is called (application must previously have provided the callback via @ref m2m_ota_init).
If the callback indicates successful activation, the newly-activated image will start running
after next system reset.
@warning
If switch will necessitate a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this
API.\n
If switch requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware.
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@sa
m2m_ota_init
@ -449,8 +490,9 @@ NMI_API sint8 m2m_ota_abort(void);
NMI_API sint8 m2m_ota_switch_firmware(void);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
@brief
Download a file from a remote location and store it in WINC's Flash.
@ -481,8 +523,9 @@ NMI_API sint8 m2m_ota_switch_firmware(void);
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
@brief
Read a certain amount of bytes from a file previously stored in WINC's Flash using HIF transfer.
@ -506,7 +549,7 @@ NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb p
Requires @ref m2m_ota_init to be called before a read via HIF can be requested.
@warning
There is a limitation on how much data can be transferred at a time using hif read, which is 128 bytes.
There is a limitation on how much data can be transferred at a time using HIF read, which is 128 bytes.
The limitation described above can potentially reduce the speed of the read due to extra overhead, but
using the HIF is non-blocking and therefore the Application can continue execution as normal, being
interrupted only when data is available. Another advantage is that it does not require the WINC to be
@ -528,8 +571,9 @@ NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb p
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
sint8 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.
@ -686,11 +730,12 @@ void main(void)
}
@endcode
*/
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8* pu8Buff, uint32 u32Offset, uint32 u32Size);
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
@brief
Erase any traces of file stored in WINC's Flash.
@ -731,18 +776,17 @@ NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDErase
#if 0
NMI_API sint8 m2m_ota_test(void);
#endif
/**@}*/ //OTAFUNCTIONS
/*!
@ingroup VERSIONAPI
@fn NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev* pstrRev);
@fn sint8 m2m_ota_get_firmware_version(tstrM2mRev* pstrRev);
@brief Get the OTA Firmware version.
@details Get OTA Firmware version info from the inactive partition, as defined in the structure tstrM2mRev.
@param [out] pstrRev
@param[out] pstrRev
Pointer to the structure tstrM2mRev that contains the firmware version parameters.
@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev* pstrRev);
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev);
#ifdef __cplusplus
}

View File

@ -4,7 +4,7 @@
*
* \brief WINC Peripherals Application Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -52,18 +52,6 @@ MACROS
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@struct \
tstrPerphInitParam
@brief
Peripheral module initialization parameters.
*/
typedef struct {
void * arg;
} tstrPerphInitParam;
/*!
@enum \
tenuGpioNum
@ -72,94 +60,25 @@ typedef struct {
A list of GPIO numbers configurable through the m2m_periph module.
*/
typedef enum {
M2M_PERIPH_GPIO3, /*!< GPIO15 pad */
M2M_PERIPH_GPIO4, /*!< GPIO16 pad */
M2M_PERIPH_GPIO5, /*!< GPIO18 pad */
M2M_PERIPH_GPIO6, /*!< GPIO18 pad */
M2M_PERIPH_GPIO15, /*!< GPIO15 pad */
M2M_PERIPH_GPIO16, /*!< GPIO16 pad */
M2M_PERIPH_GPIO18, /*!< GPIO18 pad */
M2M_PERIPH_GPIO0 = 0, /*!< GPIO0 pad */
M2M_PERIPH_GPIO1 = 1, /*!< GPIO1 pad */
M2M_PERIPH_GPIO2 = 2, /*!< GPIO2 pad */
M2M_PERIPH_GPIO3 = 3, /*!< GPIO3 pad */
M2M_PERIPH_GPIO4 = 4, /*!< GPIO4 pad */
M2M_PERIPH_GPIO5 = 5, /*!< GPIO5 pad */
M2M_PERIPH_GPIO6 = 6, /*!< GPIO6 pad */
M2M_PERIPH_GPIO_MAX
} tenuGpioNum;
/*!
@enum \
tenuI2cMasterSclMuxOpt
@brief
Allowed pin multiplexing options for I2C master SCL signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_HOST_WAKEUP, /*!< I2C master SCL is avaiable on HOST_WAKEUP. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_SD_DAT3, /*!< I2C master SCL is avaiable on SD_DAT3 (GPIO 7). */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO13, /*!< I2C master SCL is avaiable on GPIO 13. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO4, /*!< I2C master SCL is avaiable on GPIO 4.*/
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_I2C_SCL, /*!< I2C master SCL is avaiable on I2C slave SCL. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_NUM
} tenuI2cMasterSclMuxOpt;
/*!
@enum \
tenuI2cMasterSdaMuxOpt
@brief
Allowed pin multiplexing options for I2C master SDA signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_RTC_CLK , /*!< I2C master SDA is avaiable on RTC_CLK. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_SD_CLK, /*!< I2C master SDA is avaiable on SD_CLK (GPIO 8). */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO14, /*!< I2C master SDA is avaiable on GPIO 14. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO6, /*!< I2C master SDA is avaiable on GPIO 6.*/
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_I2C_SDA, /*!< I2C master SDA is avaiable on I2C slave SDA. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_NUM
} tenuI2cMasterSdaMuxOpt;
/*!
@struct \
tstrI2cMasterInitParam
@brief
I2C master configuration parameters.
@sa
tenuI2cMasterSclMuxOpt
tenuI2cMasterSdaMuxOpt
*/
typedef struct {
uint8 enuSclMuxOpt; /*!< SCL multiplexing option. Allowed value are defined in tenuI2cMasterSclMuxOpt */
uint8 enuSdaMuxOpt; /*!< SDA multiplexing option. Allowed value are defined in tenuI2cMasterSdaMuxOpt */
uint8 u8ClkSpeedKHz; /*!< I2C master clock speed in KHz. */
} tstrI2cMasterInitParam;
/*!
@enum \
tenuI2cMasterFlags
@brief
Bitwise-ORed flags for use in m2m_periph_i2c_master_write and m2m_periph_i2c_master_read
@sa
m2m_periph_i2c_master_write
m2m_periph_i2c_master_read
*/
typedef enum {
I2C_MASTER_NO_FLAGS = 0x00,
/*!< No flags. */
I2C_MASTER_NO_STOP = 0x01,
/*!< No stop bit after this transaction. Useful for scattered buffer read/write operations. */
I2C_MASTER_NO_START = 0x02,
/*!< No start bit at the beginning of this transaction. Useful for scattered buffer read/write operations.*/
} tenuI2cMasterFlags;
/*!
@enum \
tenuPullupMask
@brief
Bitwise-ORed flags for use in m2m_perph_pullup_ctrl.
Bitwise-ORed flags for use in @ref m2m_periph_pullup_ctrl.
@sa
m2m_periph_pullup_ctrl
*/
typedef enum {
M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP = (1ul << 0),
@ -199,42 +118,24 @@ FUNCTION PROTOTYPES
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
/*!
@fn \
NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param);
@brief
Initialize the NMC1500 peripheral driver module.
@param [in] param
Peripheral module initialization structure. See members of tstrPerphInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrPerphInitParam
*/
NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
@brief
Configure a specific NMC1500 pad as a GPIO and sets its direction (input or output).
Configure a specific WINC15x0 pad as a GPIO and sets its direction (input or output).
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref tenuGpioNum.
@param [in] u8GpioDir
@param[in] u8GpioDir
GPIO direction: Zero = input. Non-zero = output.
@return
The function SHALL return 0 for success and a negative value otherwise.
The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa
tenuGpioNum
@ -246,12 +147,12 @@ NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
@brief
Set an NMC1500 GPIO output level high or low.
Set an WINC15x0 GPIO output level high or low.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref tenuGpioNum.
@param [in] u8GpioVal
@param[in] u8GpioVal
GPIO output value. Zero = low, non-zero = high.
@return
@ -267,112 +168,21 @@ NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal);
@brief
Read an NMC1500 GPIO input level.
Read an WINC15x0 GPIO input level.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref tenuGpioNum.
@param [out] pu8GpioVal
GPIO input value. Zero = low, non-zero = high.
@return
The function SHALL return 0 for success and a negative value otherwise.
The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
@brief
Set an NMC1500 GPIO pullup resistor enable or disable.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8PullupEn
Zero: pullup disabled. Non-zero: pullup enabled.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param);
@brief
Initialize and configure the NMC1500 I2C master peripheral.
@param [in] param
I2C master initialization structure. See members of tstrI2cMasterInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrI2cMasterInitParam
*/
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [in] pu8Buf
A pointer to an input buffer which contains a stream of bytes.
@param [in] u16BufLen
Input buffer length in bytes.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [out] pu8Buf
A pointer to an output buffer in which a stream of bytes are received.
@param [in] u16BufLen
Max output buffer length in bytes.
@param [out] pu16ReadLen
Actual number of bytes received.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags);
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 *pu8GpioVal);
/*!
@fn \
@ -381,15 +191,14 @@ NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint
@brief
Control the programmable pull-up resistor on the chip pads .
@param[in] pinmask
Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in @ref tenuPullupMask.
@param [in] pinmask
Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in tenuPullupMask.
@param [in] enable
@param[in] enable
Set to 0 to disable pull-up resistor. Non-zero will enable the pull-up.
@return
The function SHALL return 0 for success and a negative value otherwise.
The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa
tenuPullupMask

View File

@ -4,7 +4,7 @@
*
* \brief WINC Application Interface Internal Types.
*
* Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -81,8 +81,8 @@ FUNCTION PROTOTYPES
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
@brief Initializes the SSL layer.
@param[in] pfAppSSLCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
@ -105,10 +105,10 @@ NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDat
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz);
@brief Sends certificates to the WINC
@param [in] pu8Buffer
Pointer to the certificates.
@param [in] u32BufferSz
@brief Sends certificates to the WINC.
@param[in] pu8Buffer
Pointer to the certificates. The buffer format must match the format of @ref tstrTlsSrvSecHdr.
@param[in] u32BufferSz
Size of the certificates.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
@ -116,47 +116,119 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key);
@brief Retrieve the certificate to be verified from the WINC
@param [in] pu16CurveType
Pointer to the certificate curve type.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] pu8Sig
Pointer to the certificate signature.
@param [in] pu8Key
Pointer to the certificate Key.
@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] penuCurve
The named curve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
@param[inout] pu16ValueSz
in: Size of value buffer provided by caller.
out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
@param[out] pu8Sig
Signature retrieved for verification.
@param[inout] pu16SigSz
in: Size of signature buffer provided by caller.
out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key);
NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz);
@brief Retrieve the certificate hash.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] u16HashSz
Hash size.
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] pu16Curve
The named curve, to be cast to type @ref tenuEcNamedCurve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
@param[out] pu8Sig
Signature retrieved for verification.
The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz);
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
@brief Retrieve the value from the WINC for ECDSA signing.
@param[out] pu8Value
Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
@param[in] u16ValueSz
Size of value to be retrieved. (The application should obtain this information,
along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
signing information is ready via @ref ECC_REQ_SIGN_GEN.
@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_stop_retrieving(void);
@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
information.
@return None.
@warning The application must call this function if it has been notified (via
@ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
retrieving from the WINC, but chooses not to retrieve it all.
The application must not call this function if it has retrieved all the available
information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
remaining information has been lost.
@see m2m_ssl_retrieve_next_for_verifying\n
m2m_ssl_retrieve_cert\n
m2m_ssl_retrieve_hash
*/
NMI_API void m2m_ssl_stop_retrieving(void);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_stop_processing_certs(void);
@brief Allow ssl driver to tidy up in case application does not read all available certificates.
@warning This API must only be called if some certificates are left unread.
@return None.
@brief Allow SSL driver to tidy up in case application does not read all available certificates.
@return None.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_stop_retrieving is used instead.
*/
NMI_API void m2m_ssl_stop_processing_certs(void);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_ecc_process_done(void);
@brief Allow ssl driver to tidy up after application has finished processing ecc message.
@warning This API must be called after receiving a SSL callback with message type @ref M2M_SSL_REQ_ECC.
@return None.
@brief Allow SSL driver to tidy up after application has finished processing ECC message.
@return None.
@warning The application should call this function after receiving an SSL callback with message
type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
calling @ref m2m_ssl_handshake_rsp.
*/
NMI_API void m2m_ssl_ecc_process_done(void);
@ -167,18 +239,14 @@ NMI_API void m2m_ssl_ecc_process_done(void);
@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by
the caller in the form of a bitmap containing the required ciphers to be on.\n
There is no need to call this function if the application will not change the default ciphersuites.
@param [in] u32SslCsBMP
@param[in] u32SslCsBMP
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination, except for combinations involving both RSA
and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
change.
@return
- @ref SOCK_ERR_NO_ERROR
- @ref SOCK_ERR_INVALID_ARG
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
*
* \brief BSD compatible socket interface internal types.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -65,7 +65,19 @@ MACROS
#define SSL_MAX_OPT_LEN HOSTNAME_MAX_SIZE
#define ALPN_LIST_MIN_SIZE 4
#define ALPN_LIST_MAX_SIZE 32
/*!<
Maximum length of ALPN list that can be specified by the application.
The list is in the following format:
@verbatim
0 1 2 3 ... (bytes)
+-------+-------+-------+ ... +-------+ ... +-------+ ...
| Length L (BE) | len1 | name1... | len2 | name2... | len3 | name3...
+-------+-------+-------+ ... +-------+ ... +-------+ ...
Length fields do not include themselves.
@endverbatim
*/
#define SOCKET_CMD_INVALID 0x00
/*!<
@ -195,6 +207,16 @@ MACROS
*/
#define SOCKET_CMD_SECURE 0x56
/*!<
Make secure a previously opened socket.
*/
#define SOCKET_CMD_SSL_CONNECT_ALPN 0x57
/*!<
SSL-Socket Connect with ALPN command value.
*/
#define PING_ERR_SUCCESS 0
#define PING_ERR_DEST_UNREACH 1
@ -318,14 +340,49 @@ typedef struct{
typedef struct{
SOCKET sock;
sint8 s8Error;
/*!<
0 for successful connection, in which case u16AppDataOffset is valid.
Negative for failed connection, in which case u8ErrorType and u8ErrorDetail may give more info.
*/
union {
uint16 u16AppDataOffset;
/*!<
In further packet send requests the host interface should put the user application
data at this offset in the allocated shared data packet.
*/
struct {
uint8 u8ErrSource;
/*!<
0: No detail
1: TLS Alert received from peer
2: TLS Alert generated locally
*/
uint8 u8ErrCode;
/*!<
For TLS Alerts, this is the Alert ID.
*/
};
};
}tstrConnectReply;
/*!
@struct \
tstrConnectAlpnReply
@brief
Connect Reply, contains sock number, error value and index of negotiated application protocol.
*/
typedef struct{
tstrConnectReply strConnReply;
uint8 u8AppProtocolIdx;
/*!<
1-based index of application-layer protocol negotiated during TLS handshake.
*/
uint8 __PAD24__[3];
}tstrConnectAlpnReply;
/*!
@brief
*/
@ -363,11 +420,13 @@ typedef struct{
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
uint16 u16BufLen;
}tstrRecvCmd;
/*!
@struct
@struct \
tstrRecvReply
@brief
*/
typedef struct{

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -71,14 +71,14 @@ FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
* @brief OTA call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
@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)
{
@ -140,9 +140,9 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
s8Ret = hif_receive(u32Addr, (uint8*)&strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
if(gpfHFDReadCb)
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.FileBlockSz);
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz);
}
else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
{
tstrOtaHostFileEraseStatusResp strOtaHostFileEraseStatusResp = {0};
s8Ret = hif_receive(u32Addr, (uint8*)&strOtaHostFileEraseStatusResp, sizeof(tstrOtaHostFileEraseStatusResp), 1);
@ -161,20 +161,13 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
}
}
/*!
@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 SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -197,17 +190,11 @@ NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNot
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 SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -222,14 +209,9 @@ NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@brief
check for ota update
@return
The function SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -239,17 +221,11 @@ NMI_API sint8 m2m_ota_notif_check_for_update(void)
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA update
@param [in] u32Period
@fn NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
@brief Schedule OTA update.
@param[in] u32Period
Period in days
@return
The function SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
@ -259,18 +235,11 @@ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
}
/*!
@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 SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -284,14 +253,9 @@ NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@brief
Request OTA Rollback image
@return
The function SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -301,14 +265,9 @@ NMI_API sint8 m2m_ota_rollback(void)
}
/*!
@fn \
NMI_API sint8 m2m_ota_abort(void);
@brief
Request OTA Abort
@return
The function SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -317,16 +276,10 @@ NMI_API sint8 m2m_ota_abort(void)
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@brief
Switch to the upgraded Firmware
@return
The function SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -336,14 +289,9 @@ NMI_API sint8 m2m_ota_switch_firmware(void)
}
/*!
@fn \
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev);
@brief
Get the OTA Firmware version.
@return
The function SHALL return 0 for success and a negative value otherwise.
@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)
{
@ -409,23 +357,15 @@ NMI_API sint8 m2m_ota_test(void)
#endif
/*!
@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.
@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 1. Providing a callback is mandatory.
2. This functionality is only supported from WINC release 19.6.0 onwards.
@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)
{
@ -457,11 +397,8 @@ EXIT:
}
/*!
@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.
@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.
@ -473,12 +410,8 @@ EXIT:
@param[in] pfHFDReadCb
Callback to be executed when the read operation completes.
@return
Status of the read operation
@warning 1. Providing a callback is mandatory.
2. This functionality is only supported from WINC release 19.6.0 onwards.
@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)
{
@ -496,11 +429,8 @@ EXIT:
}
/*!
@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.
@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.
@ -512,22 +442,17 @@ EXIT:
@param[in] u32Size
The amount of data to read (in Bytes).
@return
Status of the read operation
@warning 1. Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
@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.
2. This functionality is only supported from WINC release 19.6.0 onwards.
*/
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 != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pu8Buff)) goto EXIT;
if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT;
if(WIFI_STATE_INIT != m2m_wifi_get_state())
{
@ -542,6 +467,10 @@ NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32
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))
@ -560,20 +489,13 @@ EXIT:
}
/*!
@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.
@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
@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;
@ -581,8 +503,6 @@ EXIT:
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.
@warning This functionality is only supported from WINC release 19.6.0 onwards.
*/
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
{

View File

@ -4,7 +4,7 @@
*
* \brief NMC1500 Peripherials Application Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -56,57 +56,35 @@ DATA TYPES
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static sint8 get_gpio_idx(uint8 u8GpioNum)
{
if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) return -1;
if(u8GpioNum == M2M_PERIPH_GPIO15) { return 15;
} else if(u8GpioNum == M2M_PERIPH_GPIO16) { return 16;
} else if(u8GpioNum == M2M_PERIPH_GPIO18) { return 18;
} else if(u8GpioNum == M2M_PERIPH_GPIO3) { return 3;
} else if(u8GpioNum == M2M_PERIPH_GPIO4) { return 4;
} else if(u8GpioNum == M2M_PERIPH_GPIO5) { return 5;
} else if(u8GpioNum == M2M_PERIPH_GPIO6) { return 6;
} else {
return -2;
}
}
/*
* GPIO read/write skeleton with wakeup/sleep capability.
*/
static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 * pu8OutVal)
{
sint8 ret, gpio;
sint8 s8Ret = hif_chip_wake();
if(s8Ret != M2M_SUCCESS) goto _EXIT;
ret = hif_chip_wake();
if(ret != M2M_SUCCESS) goto _EXIT;
gpio = get_gpio_idx(u8GpioNum);
if(gpio < 0) goto _EXIT1;
if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) goto _EXIT1;
if(op == GPIO_OP_DIR) {
ret = set_gpio_dir((uint8)gpio, u8InVal);
s8Ret = set_gpio_dir(u8GpioNum, u8InVal);
} else if(op == GPIO_OP_SET) {
ret = set_gpio_val((uint8)gpio, u8InVal);
s8Ret = set_gpio_val(u8GpioNum, u8InVal);
} else if(op == GPIO_OP_GET) {
ret = get_gpio_val((uint8)gpio, pu8OutVal);
s8Ret = get_gpio_val(u8GpioNum, pu8OutVal);
}
if(ret != M2M_SUCCESS) goto _EXIT1;
_EXIT1:
ret = hif_chip_sleep();
s8Ret = hif_chip_sleep();
_EXIT:
return ret;
return s8Ret;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
sint8 m2m_periph_init(tstrPerphInitParam * param)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir)
{
return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL);
@ -122,27 +100,6 @@ sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal)
return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal);
}
sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable)
{
return pullup_ctrl(pinmask, enable);

View File

@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi SSL APIs implementation.
*
* Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -62,13 +62,13 @@ FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief SSL callback function
@param [in] u8OpCode
@fn void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief Internal SSL callback function.
@param [in] u8OpCode
HIF Opcode type.
@param [in] u16DataSize
@param [in] u16DataSize
HIF data length.
@param [in] u32Addr
@param [in] u32Addr
HIF address.
*/
static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@ -79,10 +79,10 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
case M2M_SSL_REQ_ECC:
{
tstrEccReqInfo strEccREQ;
s8tmp = hif_receive(u32Addr, (uint8*)&strEccREQ, sizeof(tstrEccReqInfo), 0);
s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0);
if(s8tmp == M2M_SUCCESS)
{
if (gpfAppSSLCb)
if(gpfAppSSLCb)
{
gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
@ -93,10 +93,10 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
case M2M_SSL_RESP_SET_CS_LIST:
{
tstrSslSetActiveCsList strCsList;
s8tmp = hif_receive(u32Addr, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
if(s8tmp == M2M_SUCCESS)
{
if (gpfAppSSLCb)
if(gpfAppSSLCb)
gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
}
}
@ -106,7 +106,7 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
tstrTlsSrvChunkHdr strTlsSrvChunkRsp;
uint8 bCallApp = 1;
s8tmp = hif_receive(u32Addr, (uint8*)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0);
s8tmp = hif_receive(u32Addr, (uint8 *)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0);
if(s8tmp == M2M_SUCCESS)
{
uint16 offset = strTlsSrvChunkRsp.u16Offset32;
@ -115,17 +115,17 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig);
/* If first chunk, reset status. */
if (offset == 0)
if(offset == 0)
genuStatus = TLS_FLASH_OK_NO_CHANGE;
/* Only send status to app when processing last chunk. */
if (offset + chunk_size != total_size)
if(offset + chunk_size != total_size)
bCallApp = 0;
switch (status)
switch(status)
{
case TLS_FLASH_OK:
// Good flash write. Update status if no errors yet.
if (genuStatus == TLS_FLASH_OK_NO_CHANGE)
if(genuStatus == TLS_FLASH_OK_NO_CHANGE)
genuStatus = status;
break;
case TLS_FLASH_OK_NO_CHANGE:
@ -137,17 +137,17 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
break;
case TLS_FLASH_ERR_NO_CHANGE:
// Failed flash write. Update status if no more serious error.
if ((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN))
if((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN))
genuStatus = status;
break;
default:
// Don't expect any other case. Ensure we don't mask a previous corrupt error.
if (genuStatus != TLS_FLASH_ERR_CORRUPT)
if(genuStatus != TLS_FLASH_ERR_CORRUPT)
genuStatus = TLS_FLASH_ERR_UNKNOWN;
break;
}
}
if (bCallApp && gpfAppSSLCb)
if(bCallApp && gpfAppSSLCb)
gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus);
}
break;
@ -158,45 +158,68 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
}
}
/*!
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
genuStatus = TLS_FLASH_ERR_UNKNOWN;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
if(s8Ret != M2M_SUCCESS)
{
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC
@param [in] strECCResp
@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC.
@param[in] strECCResp
ECC Response struct.
@param [in] pu8RspDataBuffe
@param[in] pu8RspDataBuff
Pointer of the response data to be sent.
@param [in] u16RspDataSz
@param[in] u16RspDataSz
Response data size.
@return The function SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8*)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8 *)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
return s8Ret;
}
/*!
@fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
@brief Sends certificates to the WINC
@param [in] pu8Buffer
@fn NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
@brief Sends certificates to the WINC
@param[in] pu8Buffer
Pointer to the certificates.
@param [in] u32BufferSz
@param[in] u32BufferSz
Size of the certificates.
@return The function SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
{
sint8 s8Ret = M2M_SUCCESS;
#define TXLIMIT (256 * 6)
#define TXLIMIT (256 * 6)
if(u32BufferSz <= TXLIMIT)
{
// set chunk header for one chunk
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)pu8Buffer;
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = (u32BufferSz + 3) >> 2;
pchkhdr->u16Offset32 = 0;
@ -208,39 +231,44 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
{
// chunk it
// We are sneaking in a header - tstrTlsSrvChunkHdr
#define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr))
#define CHUNKSZ (TXLIMIT - 256) // divisible by 4
#define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr))
#define CHUNKSZ (TXLIMIT - 256) // divisible by 4
uint8 saveblob[CHUNKHDRSZ];
uint32 ofs = 0;
uint32 thischunksz = 0;
// first is special - over writing our header
m2m_memcpy(saveblob, &pu8Buffer[ofs], CHUNKHDRSZ);
thischunksz = min(CHUNKSZ,u32BufferSz-ofs); // no need to round up to quad words this time
tstrTlsSrvChunkHdr* pchkhdr = (tstrTlsSrvChunkHdr*)&pu8Buffer[ofs];
thischunksz = min(CHUNKSZ, u32BufferSz-ofs); // no need to round up to quad words this time
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs];
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs], thischunksz, 0);
M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %lu total %lu\n", thischunksz, ofs, u32BufferSz);
M2M_INFO("Transferred %u bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
while (ofs < u32BufferSz)
while(ofs < u32BufferSz)
{
// Subsequent chunks write header before and send a little more
m2m_memcpy(saveblob, &pu8Buffer[ofs-CHUNKHDRSZ], CHUNKHDRSZ);
thischunksz = min(CHUNKSZ,u32BufferSz-ofs);
thischunksz = min(CHUNKSZ, u32BufferSz-ofs);
thischunksz = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length
pchkhdr = (tstrTlsSrvChunkHdr*)&pu8Buffer[ofs - CHUNKHDRSZ];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs - CHUNKHDRSZ];
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs - CHUNKHDRSZ], thischunksz + CHUNKHDRSZ, 0);
M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %lu total %lu\n", thischunksz, ofs, u32BufferSz);
M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
}
@ -250,104 +278,195 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
}
/*!
@fn \ m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
@brief Retrieve the certificate to be verified from the WINC
@param [in] pu16CurveType
Pointer to the certificate curve type.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] pu8Sig
Pointer to the certificate signature.
@param [in] pu8Key
Pointer to the certificate Key.
@return The function SHALL return 0 for success and a negative value otherwise.
@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] penuCurve
The named curve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
@param[inout] pu16ValueSz
in: Size of value buffer provided by caller.
out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
@param[out] pu8Sig
Signature retrieved for verification.
@param[inout] pu16SigSz
in: Size of signature buffer provided by caller.
out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey)
{
uint8 bSetRxDone = 1;
sint8 s8Ret = M2M_ERR_FAIL;
uint16 u16HashSz, u16SigSz, u16KeySz;
sint8 s8Ret = M2M_SUCCESS;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if(hif_receive(gu32HIFAddr, (uint8*)pu16CurveType, 2, 0) != M2M_SUCCESS) goto __ERR;
if((NULL == penuCurve) || (NULL == pu8Value) || (NULL == pu16ValueSz) || (NULL == pu8Sig) || (NULL == pu16SigSz) || (NULL == pstrKey))
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
*penuCurve = _htons(u16KeySz);
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8*)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16KeySz = _htons(u16KeySz);
if(u16KeySz > sizeof(pstrKey->X)) goto __ERR;
pstrKey->u16Size = u16KeySz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8*)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8*)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += 2;
(*pu16CurveType)= _htons((*pu16CurveType));
pu8Key->u16Size = _htons(u16KeySz);
if(hif_receive(gu32HIFAddr, (uint8 *)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16HashSz = _htons(u16HashSz);
if(u16HashSz > *pu16ValueSz) goto __ERR;
*pu16ValueSz = u16HashSz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16SigSz = _htons(u16SigSz);
if(u16SigSz > *pu16SigSz) goto __ERR;
*pu16SigSz = u16SigSz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += (pu8Key->u16Size * 2);
if(hif_receive(gu32HIFAddr, pstrKey->X, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16KeySz;
if(hif_receive(gu32HIFAddr, pstrKey->Y, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16KeySz;
if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
if(hif_receive(gu32HIFAddr, pu8Value, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16HashSz;
if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16SigSz;
bSetRxDone = 0;
return M2M_SUCCESS;
__ERR:
if(bSetRxDone)
{
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
@brief Retrieve the certificate hash
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] u16HashSz
Hash size.
@return The function SHALL return 0 for success and a negative value otherwise.
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] pu16Curve
The named curve, to be cast to type @ref tenuEcNamedCurve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
@param[out] pu8Sig
Signature retrieved for verification.
The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz)
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey)
{
uint8 bSetRxDone = 1;
sint8 s8Ret = M2M_SUCCESS;
uint16 u16ValueSz = 32, u16SigSz = 64;
return m2m_ssl_retrieve_next_for_verifying((tenuEcNamedCurve *)pu16Curve, pu8Value, &u16ValueSz, pu8Sig, &u16SigSz, pstrKey);
}
/*!
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
@brief Retrieve the value from the WINC for ECDSA signing.
@param[out] pu8Value
Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
@param[in] u16ValueSz
Size of value to be retrieved. (The application should obtain this information,
along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
signing information is ready via @ref ECC_REQ_SIGN_GEN.
@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz)
{
sint8 s8Ret = M2M_ERR_FAIL;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
if(NULL == pu8Value)
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
bSetRxDone = 0;
if(hif_receive(gu32HIFAddr, pu8Value, u16ValueSz, 0) != M2M_SUCCESS) goto __ERR;
return M2M_SUCCESS;
__ERR:
if(bSetRxDone)
{
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_stop_processing_certs(void)
@brief Stops receiving from the HIF
@fn NMI_API void m2m_ssl_stop_retrieving(void);
@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
information.
@return None.
@warning The application must call this function if it has been notified (via
@ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
retrieving from the WINC, but chooses not to retrieve it all.
The application must not call this function if it has retrieved all the available
information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
remaining information has been lost.
@see m2m_ssl_retrieve_next_for_verifying\n
m2m_ssl_retrieve_cert\n
m2m_ssl_retrieve_hash
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
NMI_API void m2m_ssl_stop_retrieving(void)
{
hif_receive(0, NULL, 0, 1);
}
/*!
@fn \ m2m_ssl_ecc_process_done(void)
@brief Stops receiving from the HIF
@fn NMI_API void m2m_ssl_stop_processing_certs(void);
@brief Allow SSL driver to tidy up in case application does not read all available certificates.
@return None.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_stop_retrieving is used instead.
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
{
m2m_ssl_stop_retrieving();
}
/*!
@fn NMI_API void m2m_ssl_ecc_process_done(void);
@brief Allow SSL driver to tidy up after application has finished processing ECC message.
@return None.
@warning The application should call this function after receiving an SSL callback with message
type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
calling @ref m2m_ssl_handshake_rsp.
*/
NMI_API void m2m_ssl_ecc_process_done(void)
{
@ -355,9 +474,9 @@ NMI_API void m2m_ssl_ecc_process_done(void)
}
/*!
@fn \
m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
@fn NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
@brief Sets the active ciphersuites.
@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
a bitmap containing the required ciphers to be on.
There is no need to call this function if the application will not change the default ciphersuites.
@ -365,45 +484,21 @@ NMI_API void m2m_ssl_ecc_process_done(void)
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination, except for combinations involving both RSA
and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
be changed.
change.
@return
- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
- @ref SOCK_ERR_NO_ERROR
- @ref SOCK_ERR_INVALID_ARG
*/
sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
{
sint8 s8Ret = M2M_SUCCESS;
tstrSslSetActiveCsList strCsList;
strCsList.u32CsBMP = u32SslCsBMP;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
return s8Ret;
}
/*!
@fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
genuStatus = TLS_FLASH_ERR_UNKNOWN;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL,m2m_ssl_cb);
if (s8Ret != M2M_SUCCESS)
{
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}

View File

@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -45,11 +45,34 @@
* \{
*/
static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT;
static volatile uint8 gu8ChNum;
static volatile uint8 gu8scanInProgress = 0;
static tpfAppWifiCb gpfAppWifiCb = NULL;
/* Require authentication of server. */
#define WIFI_1X_TLS_HS_FLAGS_PEER_AUTH NBIT1
/* Enable expiry checking of server certificate chain. */
#define WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK NBIT2
/* Require local system time to be known (i.e. fail expiry checking if time is not known locally). */
#define WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME NBIT3
/* Enable TLS session caching. */
#define WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING NBIT4
/* Reserved, this bit must be clear. */
#define WIFI_1X_TLS_HS_FLAGS_RSV5 NBIT5
/* Require server authentication to be against a specified root certificate. */
#define WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT NBIT6
/* Reserved, this bit must be clear. */
#define WIFI_1X_TLS_HS_FLAGS_RSV7 NBIT7
#define WIFI_1X_TLS_HS_FLAGS_DEFAULT ( \
WIFI_1X_TLS_HS_FLAGS_PEER_AUTH \
| WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK \
| WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING \
)
static volatile uint8 gu8ChNum;
static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT;
static tpfAppWifiCb gpfAppWifiCb = NULL;
static volatile uint8 gu8scanInProgress = 0;
static uint32 gu321xTlsHsFlags = WIFI_1X_TLS_HS_FLAGS_DEFAULT;
static uint8 gau81xRootSha1[20] = {0};
#ifdef ETH_MODE
static tpfAppEthCb gpfAppEthCb = NULL;
@ -58,19 +81,16 @@ static uint16 gu16ethRcvBufSize ;
#endif
/**
* @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
@fn void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
@brief Internal WiFi callback function.
@param[in] u8OpCode
HIF Opcode type.
@param[in] u16DataSize
HIF data length.
@param[in] u32Addr
HIF address.
@param[in] grp
HIF group type.
*/
static void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
@ -617,36 +637,6 @@ INVALID_ARG:
return M2M_ERR_INVALID_ARG;
}
/* Convert hexchar to value 0-15 */
static uint8 hexchar_2_val(uint8 ch)
{
ch -= 0x30;
if (ch <= 9)
return ch;
ch |= 0x20;
ch -= 0x31;
if (ch <= 5)
return ch + 10;
return 0xFF;
}
/* Convert hexstring to bytes */
static sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
{
while (u8SizeOut--)
{
uint8 u8Out = hexchar_2_val(*pu8In++);
if (u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out = u8Out * 0x10;
u8Out = hexchar_2_val(*pu8In++);
if (u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out += u8Out;
pu8Out++;
}
return M2M_SUCCESS;
}
/*************************************************************************************************/
/* WIFI CONNECT APIS */
/*************************************************************************************************/
@ -692,18 +682,24 @@ sint8 m2m_wifi_connect_wep(
if (ret == M2M_SUCCESS)
{
tstrM2mWifiWep pstrWep;
pstrWep.u8KeyIndex = pstrAuthWep->u8KeyIndx - 1;
pstrWep.u8KeyLen = pstrAuthWep->u8KeySz/2;
hexstr_2_bytes(pstrWep.au8WepKey, (pstrAuthWep->pu8WepKey), pstrWep.u8KeyLen);
tstrM2mWifiWep *pstrWep = (tstrM2mWifiWep*)fb_alloc(sizeof(tstrM2mWifiWep), 0);
if (pstrWep != NULL)
{
pstrWep->u8KeyIndex = pstrAuthWep->u8KeyIndx - 1;
pstrWep->u8KeyLen = pstrAuthWep->u8KeySz/2;
hexstr_2_bytes(pstrWep->au8WepKey, (pstrAuthWep->pu8WepKey), pstrWep->u8KeyLen);
ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8*)&pstrWep, sizeof(tstrM2mWifiWep), sizeof(tstrM2mWifiConnHdr));
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8 *)pstrWep, sizeof(tstrM2mWifiWep), sizeof(tstrM2mWifiConnHdr));
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
return ret;
}
}
sint8 m2m_wifi_connect_psk(
tenuCredStoreOption enuCredStoreOption,
@ -723,46 +719,175 @@ sint8 m2m_wifi_connect_psk(
pstrNetworkId,
&strConnHdr);
if (ret == M2M_SUCCESS)
if(ret == M2M_SUCCESS)
{
tstrM2mWifiPsk pstrPsk;
m2m_memset((uint8*)&pstrPsk, 0, sizeof(tstrM2mWifiPsk));
if (pstrAuthPsk->pu8Psk != NULL)
tstrM2mWifiPsk *pstrPsk = (tstrM2mWifiPsk *)fb_alloc(sizeof(tstrM2mWifiPsk), 0);
if(pstrPsk != NULL)
{
if (pstrAuthPsk->pu8Passphrase != NULL)
m2m_memset((uint8 *)pstrPsk, 0, sizeof(tstrM2mWifiPsk));
if(pstrAuthPsk->pu8Psk != NULL)
{
if(pstrAuthPsk->pu8Passphrase != NULL)
ret = M2M_ERR_INVALID_ARG;
else
{
pstrPsk.u8PassphraseLen = M2M_MAX_PSK_LEN-1;
pstrPsk->u8PassphraseLen = M2M_MAX_PSK_LEN-1;
/* Use hexstr_2_bytes to verify pu8Psk input. */
if (M2M_SUCCESS != hexstr_2_bytes(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen/2))
if(M2M_SUCCESS != hexstr_2_bytes(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen/2))
ret = M2M_ERR_INVALID_ARG;
m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen);
m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen);
}
}
else if (pstrAuthPsk->pu8Passphrase != NULL)
else if(pstrAuthPsk->pu8Passphrase != NULL)
{
if (pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1)
if(pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1)
ret = M2M_ERR_INVALID_ARG;
else
{
pstrPsk.u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk.u8PassphraseLen);
pstrPsk->u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk->u8PassphraseLen);
}
}
else
ret = M2M_ERR_INVALID_ARG;
if (ret == M2M_SUCCESS)
if(ret == M2M_SUCCESS)
{
ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8*)&pstrPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr));
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8 *)pstrPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr));
}
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
return ret;
}
sint8 m2m_wifi_1x_set_option(tenu1xOption enuOptionName, const void *pOptionValue, size_t OptionLen)
{
if((pOptionValue == NULL) && (OptionLen > 0))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_1X_BYPASS_SERVER_AUTH:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
break;
case 0:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_TIME_VERIF_MODE:
if(OptionLen != sizeof(tenuSslCertExpSettings))
return M2M_ERR_INVALID_ARG;
switch(*(tenuSslCertExpSettings*)pOptionValue)
{
case SSL_CERT_EXP_CHECK_DISABLE:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
case SSL_CERT_EXP_CHECK_ENABLE:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
case SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_SESSION_CACHING:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
break;
case 0:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_SPECIFIC_ROOTCERT:
switch(OptionLen)
{
case 20:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
m2m_memcpy(gau81xRootSha1, (uint8*)pOptionValue, sizeof(gau81xRootSha1));
break;
case 0:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
m2m_memset(gau81xRootSha1, 0, sizeof(gau81xRootSha1));
default:
return M2M_ERR_INVALID_ARG;
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
sint8 m2m_wifi_1x_get_option(tenu1xOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
{
if(pOptionValue == NULL)
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_1X_BYPASS_SERVER_AUTH:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_AUTH) ? 0 : 1;
break;
case WIFI_1X_TIME_VERIF_MODE:
if(*pOptionLen < sizeof(tenuSslCertExpSettings))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(tenuSslCertExpSettings);
if(!(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK))
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_DISABLE;
else if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME)
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_ENABLE;
else
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME;
break;
case WIFI_1X_SESSION_CACHING:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING) ? 1 : 0;
break;
case WIFI_1X_SPECIFIC_ROOTCERT:
if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT)
{
if(*pOptionLen < sizeof(gau81xRootSha1))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(gau81xRootSha1);
m2m_memcpy((uint8*)pOptionValue, gau81xRootSha1, sizeof(gau81xRootSha1));
}
else
*pOptionLen = 0;
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
sint8 m2m_wifi_connect_1x_mschap2(
tenuCredStoreOption enuCredStoreOption,
tstrNetworkId *pstrNetworkId,
@ -807,28 +932,34 @@ sint8 m2m_wifi_connect_1x_mschap2(
if (pstrAuth1xMschap2->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
pstr1xHdr->u8DomainLength = 0;
if (pstrAuth1xMschap2->pu8Domain != NULL)
if(pstrAuth1xMschap2->pu8Domain != NULL)
{
pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xMschap2->u16DomainLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, pstr1xHdr->u8DomainLength);
pu8AuthPtr += pstr1xHdr->u8DomainLength;
}
pstr1xHdr->u16UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u16UserNameLength);
pu8AuthPtr += pstr1xHdr->u16UserNameLength;
pstr1xHdr->u8UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u8UserNameLength);
pu8AuthPtr += pstr1xHdr->u8UserNameLength;
pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
pstr1xHdr->u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen;
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Password, pstr1xHdr->u16PrivateKeyLength);
ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8*)pstr1xHdr, u16AuthSize,
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8 *)pstr1xHdr, u16AuthSize,
sizeof(tstrM2mWifiConnHdr));
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
}
@ -886,17 +1017,21 @@ tstrAuth1xTls *pstrAuth1xTls
if (pstrAuth1xTls->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
pstr1xHdr->u8DomainLength = 0;
if (pstrAuth1xTls->pu8Domain != NULL)
if(pstrAuth1xTls->pu8Domain != NULL)
{
pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xTls->u16DomainLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, pstr1xHdr->u8DomainLength);
pu8AuthPtr += pstr1xHdr->u8DomainLength;
}
pstr1xHdr->u16UserNameLength = (pstrAuth1xTls->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u16UserNameLength);
pu8AuthPtr += pstr1xHdr->u16UserNameLength;
pstr1xHdr->u8UserNameLength = (pstrAuth1xTls->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u8UserNameLength);
pu8AuthPtr += pstr1xHdr->u8UserNameLength;
pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen;
@ -911,20 +1046,22 @@ tstrAuth1xTls *pstrAuth1xTls
strInfoHdr.u8Type = M2M_802_1X_TLS_CLIENT_CERTIFICATE;
strInfoHdr.u16InfoPos = pstr1xHdr->u16CertificateOffset;
strInfoHdr.u16InfoLen = pstr1xHdr->u16CertificateLength;
ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_IND_CONN_PARAM | M2M_REQ_DATA_PKT,
(uint8*)&strInfoHdr, sizeof(tstrM2mWifiAuthInfoHdr),
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_IND_CONN_PARAM | M2M_REQ_DATA_PKT,
(uint8 *)&strInfoHdr, sizeof(tstrM2mWifiAuthInfoHdr),
pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen,
sizeof(tstrM2mWifiAuthInfoHdr));
if (ret == M2M_SUCCESS)
if(ret == M2M_SUCCESS)
{
ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8*)pstr1xHdr, u16Payload1Size,
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
(uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
(uint8 *)pstr1xHdr, u16Payload1Size,
sizeof(tstrM2mWifiConnHdr));
}
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
}
@ -1091,6 +1228,29 @@ sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption)
}
return s8Ret;
}
sint8 m2m_wifi_set_stop_scan_on_first(uint8 u8StopScanOption)
{
sint8 s8Ret = M2M_ERR_FAIL;
tstrM2MStopScanOption StopScanOption = { 0 };
if(1 >= u8StopScanOption)
{
StopScanOption.u8StopOnFirstResult = u8StopScanOption;
s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_STOP_SCAN_OPTION, (uint8 *)&StopScanOption, sizeof(tstrM2MStopScanOption), NULL, 0, 0);
M2M_INFO("Scan will %s stop on first result.\n", StopScanOption.u8StopOnFirstResult ? "" : "NOT");
}
else
{
s8Ret = M2M_ERR_INVALID_ARG;
}
return s8Ret;
}
sint8 m2m_wifi_set_scan_region(uint16 ScanRegion)
{
sint8 s8Ret = M2M_ERR_FAIL;
@ -1217,15 +1377,14 @@ sint8 m2m_wifi_wps_disable(void)
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_req_client_ctrl(uint8 cmd);
@brief Send a command to the PS Client (An WINC1500 board running the ps_firmware),
if the PS client send any commands it will be received in wifi_cb M2M_WIFI_RESP_CLIENT_INFO
@param [in] cmd
Control command sent from PS Server to PS Client (command values defined by the application)
@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
@fn NMI_API sint8 m2m_wifi_req_client_ctrl(uint8 cmd)
@brief Send a command to the PS Client (An WINC board running the ps_firmware),
if the PS client send any commands it will be received in wifi_cb @ref M2M_WIFI_RESP_CLIENT_INFO.
@param[in] cmd
Control command sent from PS Server to PS Client (command values defined by the application).
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa m2m_wifi_req_server_init, M2M_WIFI_RESP_CLIENT_INFO
@pre m2m_wifi_req_server_init should be called first
@warning
*/
sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
{
@ -1241,14 +1400,14 @@ sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_req_server_init(uint8 ch);
@brief Initialize the PS Server, The WINC1500 support Non secure communication with another WINC1500,
(SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup
@param [in] ch
@fn NMI_API sint8 m2m_wifi_req_server_init(uint8 ch)
@brief Initialize the PS Server, The WINC support non secure communication with another WINC,
(SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup.
@param[in] ch
Server listening channel
@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa m2m_wifi_req_client_ctrl
@warning The server mode can't be used with any other modes (STA/P2P/AP)
@warning The server mode can't be used with any other modes (STA/AP).
*/
sint8 m2m_wifi_req_server_init(uint8 ch)
{
@ -1480,7 +1639,7 @@ sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn)
}
/*!
@fn NMI_API sint8 m2m_wifi_request_sleep(void)
@brief Request from WINC1500 device to Sleep for specific time in the M2M_PS_MANUAL Power save mode (only).
@brief Request from WINC device to Sleep for specific time in the M2M_PS_MANUAL Power save mode (only).
@param [in] u32SlpReqTime
Request Sleep in ms
@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
@ -1502,7 +1661,7 @@ sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime)
}
/*!
@fn NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength);
@brief Set the WINC1500 device name which is used as P2P device name.
@brief Sets the WINC device name. The name string is used as a device name in DHCP hostname (option 12).
@param [in] pu8DeviceName
Buffer holding the device name.
@param [in] u8DeviceNameLength
@ -1756,15 +1915,18 @@ sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
{
sint8 ret = M2M_ERR_FAIL;
tstrPrng strRng = {0};
if((u16PrngSize < (M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)))&&(pu8PrngBuff != NULL))
if(
(u16PrngSize <= (M2M_HIF_MAX_PACKET_SIZE - (M2M_HIF_HDR_OFFSET + sizeof(tstrPrng))))
&& (pu8PrngBuff != NULL)
)
{
strRng.u16PrngSize = u16PrngSize;
strRng.pu8RngBuff = pu8PrngBuff;
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT,(uint8 *)&strRng, sizeof(tstrPrng),NULL,0, 0);
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT, (uint8 *)&strRng, sizeof(tstrPrng), NULL, 0, 0);
}
else
{
M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n",u16PrngSize);
M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n", u16PrngSize);
}
return ret;
}
@ -1905,3 +2067,19 @@ sint8 m2m_wifi_disable_roaming(void)
strWiFiRoaming.u8EnableRoaming = 0;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ROAMING, (uint8 *) &strWiFiRoaming, sizeof(tstrM2mWiFiRoaming), NULL, 0,0);
}
sint8 m2m_wifi_enable_XO_during_sleep(uint8 bXOSleepEnable)
{
tstrM2mWiFiXOSleepEnable strM2mWiFiXOSleepEnable;
if(0 == bXOSleepEnable || 1 == bXOSleepEnable)
{
strM2mWiFiXOSleepEnable.u8EnableXODuringSleep = bXOSleepEnable;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_XO_SLEEP_ENABLE,
(uint8 *) &strM2mWiFiXOSleepEnable, sizeof(strM2mWiFiXOSleepEnable), NULL, 0, 0);
}
else
{
return M2M_ERR_INVALID_ARG;
}
}

View File

@ -55,7 +55,7 @@ sint8 nm_bus_deinit(void) {
return M2M_SUCCESS;
}
static sint8 nm_bus_rw(uint8 *txbuf, uint8 *rxbuf, uint16 size) {
sint8 nm_spi_rw(uint8 *txbuf, uint8 *rxbuf, uint16 size) {
sint8 result = M2M_SUCCESS;
omv_spi_transfer_t spi_xfer = {
.txbuf = txbuf,
@ -85,7 +85,7 @@ sint8 nm_bus_ioctl(uint8 cmd, void *arg) {
switch (cmd) {
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *spi_rw = (tstrNmSpiRw *) arg;
ret = nm_bus_rw(spi_rw->pu8InBuf, spi_rw->pu8OutBuf, spi_rw->u16Sz);
ret = nm_spi_rw(spi_rw->pu8InBuf, spi_rw->pu8OutBuf, spi_rw->u16Sz);
}
break;
default:

View File

@ -4,7 +4,7 @@
*
* \brief This module contains common APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -127,3 +127,37 @@ sint8 m2m_memcmp(uint8 *pu8Buff1,uint8 *pu8Buff2 ,uint32 u32Size)
}
return s8Result;
}
/* Convert hexchar to value 0-15 */
static uint8 hexchar_2_val(uint8 ch)
{
/* ch -= '0' */
ch -= 0x30;
if(ch <= 9)
return ch;
/* OR with 0x20 to convert upper case to lower case. */
ch |= 0x20;
/* ch -= ('a'-'0') */
ch -= 0x31;
if(ch <= 5)
return ch + 10;
return 0xFF;
}
/* Convert hexstring to bytes */
sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
{
while(u8SizeOut--)
{
uint8 u8Out = hexchar_2_val(*pu8In++);
if(u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out = u8Out * 0x10;
u8Out = hexchar_2_val(*pu8In++);
if(u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out += u8Out;
pu8Out++;
}
return M2M_SUCCESS;
}

View File

@ -4,7 +4,7 @@
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -35,8 +35,6 @@
#ifdef CONF_WINC_USE_SPI
#define USE_OLD_SPI_SW
#include "bus_wrapper/include/nm_bus_wrapper.h"
#include "driver/include/nmspi.h"
@ -73,10 +71,10 @@
#define CMD_SINGLE_READ 0xca
#define CMD_RESET 0xcf
#define N_OK 1
#define N_FAIL 0
#define N_RESET -1
#define N_RETRY -2
#define N_OK 0
#define N_FAIL -1
#define N_RESET -2
#define N_RETRY -3
#define SPI_RESP_RETRY_COUNT (10)
#define SPI_RETRY_COUNT (10)
@ -89,33 +87,19 @@
static uint8 gu8Crc_off = 0;
static sint8 nmi_spi_read(uint8* b, uint16 sz)
static inline sint8 nmi_spi_read(uint8 *b, uint16 sz)
{
tstrNmSpiRw spi;
spi.pu8InBuf = NULL;
spi.pu8OutBuf = b;
spi.u16Sz = sz;
return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
return nm_spi_rw(NULL, b, sz);
}
static inline sint8 nmi_spi_write(uint8 *b, uint16 sz)
{
return nm_spi_rw(b, NULL, sz);
}
static sint8 nmi_spi_writeread(uint8 *bw, uint8 *br, uint16 sz)
{
return nm_spi_rw(bw, br, sz);
}
static sint8 nmi_spi_write(uint8* b, uint16 sz)
{
tstrNmSpiRw spi;
spi.pu8InBuf = b;
spi.pu8OutBuf = NULL;
spi.u16Sz = sz;
return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
}
#ifndef USE_OLD_SPI_SW
static sint8 nmi_spi_rw(uint8 *bin,uint8* bout,uint16 sz)
{
tstrNmSpiRw spi;
spi.pu8InBuf = bin;
spi.pu8OutBuf = bout;
spi.u16Sz = sz;
return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
}
#endif
/********************************************
Crc7
@ -158,12 +142,12 @@ static const uint8 crc7_syndrome_table[256] = {
};
static uint8 crc7_byte(uint8 crc, uint8 data)
static inline uint8 crc7_byte(uint8 crc, uint8 data)
{
return crc7_syndrome_table[(crc << 1) ^ data];
}
static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
static inline uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
{
while (len--)
crc = crc7_byte(crc, *buffer++);
@ -176,25 +160,6 @@ static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
********************************************/
#define CMD_DMA_WRITE 0xc1
#define CMD_DMA_READ 0xc2
#define CMD_INTERNAL_WRITE 0xc3
#define CMD_INTERNAL_READ 0xc4
#define CMD_TERMINATE 0xc5
#define CMD_REPEAT 0xc6
#define CMD_DMA_EXT_WRITE 0xc7
#define CMD_DMA_EXT_READ 0xc8
#define CMD_SINGLE_WRITE 0xc9
#define CMD_SINGLE_READ 0xca
#define CMD_RESET 0xcf
#define DATA_PKT_SZ_256 256
#define DATA_PKT_SZ_512 512
#define DATA_PKT_SZ_1K 1024
#define DATA_PKT_SZ_4K (4 * 1024)
#define DATA_PKT_SZ_8K (8 * 1024)
#define DATA_PKT_SZ DATA_PKT_SZ_8K
static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 clockless)
{
uint8 bc[9];
@ -216,24 +181,29 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
bc[3] = 0x00;
len = 5;
break;
#if defined(CMD_TERMINATE)
case CMD_TERMINATE: /* termination */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
#endif
#if defined(CMD_REPEAT)
case CMD_REPEAT: /* repeat */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
#endif
case CMD_RESET: /* reset */
bc[1] = 0xff;
bc[2] = 0xff;
bc[3] = 0xff;
len = 5;
break;
#if defined(CMD_DMA_WRITE) || defined(CMD_DMA_READ)
case CMD_DMA_WRITE: /* dma write */
case CMD_DMA_READ: /* dma read */
bc[1] = (uint8)(adr >> 16);
@ -243,6 +213,7 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
bc[5] = (uint8)(sz);
len = 7;
break;
#endif
case CMD_DMA_EXT_WRITE: /* dma extended write */
case CMD_DMA_EXT_READ: /* dma extended read */
bc[1] = (uint8)(adr >> 16);
@ -278,7 +249,7 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
break;
}
if (result) {
if(result == N_OK) {
if (!gu8Crc_off)
bc[len-1] = (crc7(0x7f, (const uint8 *)&bc[0], len-1)) << 1;
else
@ -330,14 +301,22 @@ static sint8 spi_cmd_rsp(uint8 cmd)
/**
Command/Control response
**/
if ((cmd == CMD_RESET) ||
(cmd == CMD_TERMINATE) ||
(cmd == CMD_REPEAT)) {
#if defined(CMD_TERMINATE)
if(cmd == CMD_TERMINATE) {
if(M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
#endif
#if defined(CMD_REPEAT)
if(cmd == CMD_REPEAT) {
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
#endif
/* wait for response */
s8RetryCnt = SPI_RESP_RETRY_COUNT;
@ -368,372 +347,27 @@ _fail_:
return result;
}
#ifndef USE_OLD_SPI_SW
static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
sint8 nm_spi_reset(void)
{
uint8_t wb[32], rb[32];
uint8_t wix, rix;
uint32_t len2;
uint8_t rsp;
int len = 0;
int result = N_OK;
//M2M_INFO("Reset Spi\n");
spi_cmd(CMD_RESET, 0, 0, 0, 0);
wb[0] = cmd;
switch (cmd) {
case CMD_SINGLE_READ: /* single word (4 bytes) read */
wb[1] = (uint8_t)(adr >> 16);
wb[2] = (uint8_t)(adr >> 8);
wb[3] = (uint8_t)adr;
len = 5;
break;
case CMD_INTERNAL_READ: /* internal register read */
wb[1] = (uint8_t)(adr >> 8);
if(clockless == 1) wb[1] |= (1 << 7);
wb[2] = (uint8_t)adr;
wb[3] = 0x00;
len = 5;
break;
case CMD_TERMINATE: /* termination */
wb[1] = 0x00;
wb[2] = 0x00;
wb[3] = 0x00;
len = 5;
break;
case CMD_REPEAT: /* repeat */
wb[1] = 0x00;
wb[2] = 0x00;
wb[3] = 0x00;
len = 5;
break;
case CMD_RESET: /* reset */
wb[1] = 0xff;
wb[2] = 0xff;
wb[3] = 0xff;
len = 5;
break;
case CMD_DMA_WRITE: /* dma write */
case CMD_DMA_READ: /* dma read */
wb[1] = (uint8_t)(adr >> 16);
wb[2] = (uint8_t)(adr >> 8);
wb[3] = (uint8_t)adr;
wb[4] = (uint8_t)(sz >> 8);
wb[5] = (uint8_t)(sz);
len = 7;
break;
case CMD_DMA_EXT_WRITE: /* dma extended write */
case CMD_DMA_EXT_READ: /* dma extended read */
wb[1] = (uint8_t)(adr >> 16);
wb[2] = (uint8_t)(adr >> 8);
wb[3] = (uint8_t)adr;
wb[4] = (uint8_t)(sz >> 16);
wb[5] = (uint8_t)(sz >> 8);
wb[6] = (uint8_t)(sz);
len = 8;
break;
case CMD_INTERNAL_WRITE: /* internal register write */
wb[1] = (uint8_t)(adr >> 8);
if(clockless == 1) wb[1] |= (1 << 7);
wb[2] = (uint8_t)(adr);
wb[3] = b[3];
wb[4] = b[2];
wb[5] = b[1];
wb[6] = b[0];
len = 8;
break;
case CMD_SINGLE_WRITE: /* single word write */
wb[1] = (uint8_t)(adr >> 16);
wb[2] = (uint8_t)(adr >> 8);
wb[3] = (uint8_t)(adr);
wb[4] = b[3];
wb[5] = b[2];
wb[6] = b[1];
wb[7] = b[0];
len = 9;
break;
default:
result = N_FAIL;
break;
}
if (result != N_OK) {
return result;
}
if (!gu8Crc_off) {
wb[len-1] = (crc7(0x7f, (const uint8_t *)&wb[0], len-1)) << 1;
} else {
len -=1;
}
#define NUM_SKIP_BYTES (1)
#define NUM_RSP_BYTES (2)
#define NUM_DATA_HDR_BYTES (1)
#define NUM_DATA_BYTES (4)
#define NUM_CRC_BYTES (2)
#define NUM_DUMMY_BYTES (3)
if ((cmd == CMD_RESET) ||
(cmd == CMD_TERMINATE) ||
(cmd == CMD_REPEAT)) {
len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
} else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
if (!gu8Crc_off) {
len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
+ NUM_CRC_BYTES + NUM_DUMMY_BYTES);
} else {
len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
+ NUM_DUMMY_BYTES);
}
} else {
len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
}
#undef NUM_DUMMY_BYTES
if(len2 > (sizeof(wb)/sizeof(wb[0]))) {
M2M_ERR("[nmi spi]: spi buffer size too small (%d) (%d)\n",
len2, (sizeof(wb)/sizeof(wb[0])));
result = N_FAIL;
return result;
}
/* zero spi write buffers. */
for(wix = len; wix< len2; wix++) {
wb[wix] = 0;
}
rix = len;
if (nmi_spi_rw(wb, rb, len2) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
result = N_FAIL;
return result;
}
#if 0
if(spi_cmd_rsp(CMD_RESET) != N_OK) {
// Reset command failed, need to send repeated 1's until reset occurs
uint8 w_buf[8] = {0xFF};
uint8 r_buf[8];
M2M_ERR("[nmi spi]: Failed rst cmd response\n");
nmi_spi_writeread(w_buf, r_buf, 8);
if(r_buf[7] != 0xFF)
{
int jj;
printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2);
for(jj=0; jj<sizeof(wb)/sizeof(wb[0]); jj++) {
if(jj >= len2) break;
if(((jj+1)%16) != 0) {
if((jj%16) == 0) {
printk("wb[%02x]: %02x ", jj, wb[jj]);
} else {
printk("%02x ", wb[jj]);
}
} else {
printk("%02x\n", wb[jj]);
M2M_ERR("[nmi spi]: Failed repeated reset\n");
return N_FAIL;
}
}
printk("\n");
for(jj=0; jj<sizeof(rb)/sizeof(rb[0]); jj++) {
if(jj >= len2) break;
if(((jj+1)%16) != 0) {
if((jj%16) == 0) {
printk("rb[%02x]: %02x ", jj, rb[jj]);
} else {
printk("%02x ", rb[jj]);
}
} else {
printk("%02x\n", rb[jj]);
}
}
printk("\n");
}
#endif
/**
Command/Control response
**/
if ((cmd == CMD_RESET) ||
(cmd == CMD_TERMINATE) ||
(cmd == CMD_REPEAT)) {
rix++; /* skip 1 byte */
}
rsp = rb[rix++];
if (rsp != cmd) {
M2M_ERR("[nmi spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
result = N_FAIL;
return result;
}
/**
State response
**/
rsp = rb[rix++];
if (rsp != 0x00) {
M2M_ERR("[nmi spi]: Failed cmd state response state (%02x)\n", rsp);
result = N_FAIL;
return result;
}
if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
|| (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
int retry;
//uint16_t crc1, crc2;
uint8_t crc[2];
/**
Data Response header
**/
retry = SPI_RESP_RETRY_COUNT;
do {
/* ensure there is room in buffer later to read data and crc */
if(rix < len2) {
rsp = rb[rix++];
} else {
retry = 0;
break;
}
if (((rsp >> 4) & 0xf) == 0xf)
break;
} while (retry--);
if (retry <= 0) {
M2M_ERR("[nmi spi]: Error, data read response (%02x)\n", rsp);
result = N_RESET;
return result;
}
if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
/**
Read bytes
**/
if((rix+3) < len2) {
b[0] = rb[rix++];
b[1] = rb[rix++];
b[2] = rb[rix++];
b[3] = rb[rix++];
} else {
M2M_ERR("[nmi spi]: buffer overrun when reading data.\n");
result = N_FAIL;
return result;
}
if (!gu8Crc_off) {
/**
Read Crc
**/
if((rix+1) < len2) {
crc[0] = rb[rix++];
crc[1] = rb[rix++];
} else {
M2M_ERR("[nmi spi]: buffer overrun when reading crc.\n");
result = N_FAIL;
return result;
}
}
} else if((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
int ix;
/* some data may be read in response to dummy bytes. */
for(ix=0; (rix < len2) && (ix < sz);) {
b[ix++] = rb[rix++];
}
#if 0
if(ix) M2M_INFO("ttt %d %d\n", sz, ix);
#endif
sz -= ix;
if(sz > 0) {
int nbytes;
if (sz <= (DATA_PKT_SZ-ix)) {
nbytes = sz;
} else {
nbytes = DATA_PKT_SZ-ix;
}
/**
Read bytes
**/
if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
result = N_FAIL;
goto _error_;
}
/**
Read Crc
**/
if (!gu8Crc_off) {
if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
result = N_FAIL;
goto _error_;
}
}
ix += nbytes;
sz -= nbytes;
}
/* if any data in left unread, then read the rest using normal DMA code.*/
while(sz > 0) {
int nbytes;
if (sz <= DATA_PKT_SZ) {
nbytes = sz;
} else {
nbytes = DATA_PKT_SZ;
}
/**
read data response only on the next DMA cycles not
the first DMA since data response header is already
handled above for the first DMA.
**/
/**
Data Response header
**/
retry = SPI_RESP_RETRY_COUNT;
do {
if (nmi_spi_read(&rsp, 1) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
result = N_FAIL;
break;
}
if (((rsp >> 4) & 0xf) == 0xf)
break;
} while (retry--);
if (result == N_FAIL)
break;
/**
Read bytes
**/
if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
result = N_FAIL;
break;
}
/**
Read Crc
**/
if (!gu8Crc_off) {
if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
result = N_FAIL;
break;
}
}
ix += nbytes;
sz -= nbytes;
}
}
}
_error_:
return result;
return N_OK;
}
#endif
static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
{
sint16 retry, ix, nbytes;
@ -761,7 +395,7 @@ static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
result = N_FAIL;
break;
}
if (((rsp >> 4) & 0xf) == 0xf)
if((rsp & 0xf0) == 0xf0)
break;
} while (retry--);
@ -805,16 +439,15 @@ static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
static sint8 spi_data_write(uint8 *b, uint16 sz)
{
sint16 ix;
sint16 ix = 0;
uint16 nbytes;
sint8 result = 1;
sint8 result = N_OK;
uint8 cmd, order, crc[2] = {0};
//uint8 rsp;
/**
Data
**/
ix = 0;
do {
if (sz <= DATA_PKT_SZ)
nbytes = sz;
@ -883,7 +516,16 @@ static sint8 spi_data_write(uint8 *b, uint16 sz)
********************************************/
static sint8 spi_write_reg(uint32 addr, uint32 u32data)
/**
* @fn nm_spi_write_reg
* @brief Write register
* @param[in] u32Addr
* Register address
* @param[in] u32Val
* Value to be written to the register
* @return @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_reg(uint32 addr, uint32 u32data)
{
uint8 retry = SPI_RETRY_COUNT;
sint8 result = N_OK;
@ -899,13 +541,7 @@ _RETRY_:
cmd = CMD_INTERNAL_WRITE;
clockless = 1;
}
else
{
cmd = CMD_SINGLE_WRITE;
clockless = 0;
}
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, u32data, 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, write reg (%08x)...\n", (unsigned int)addr);
@ -917,23 +553,13 @@ _RETRY_:
M2M_ERR("[nmi spi]: Failed cmd response, write reg (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
#else
result = spi_cmd_complete(cmd, addr, (uint8*)&u32data, 4, clockless);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
goto _FAIL_;
}
#endif
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %lx %lx\n",retry,addr,u32data);
M2M_ERR("Reset and retry %d %x %x\n",retry,addr,u32data);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
@ -953,7 +579,6 @@ _RETRY_:
/**
Command
**/
#if defined USE_OLD_SPI_SW
//Workaround hardware problem with single byte transfers over SPI bus
if (size == 1)
size = 2;
@ -969,13 +594,6 @@ _RETRY_:
M2M_ERR("[nmi spi ]: Failed cmd response, write block (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
#else
result = spi_cmd_complete(cmd, addr, NULL, size, 0);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
goto _FAIL_;
}
#endif
/**
Data
@ -1000,7 +618,7 @@ _FAIL_:
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
M2M_ERR("Reset and retry %d %x %d\n",retry,addr,size);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
@ -1010,10 +628,19 @@ _FAIL_:
return result;
}
static sint8 spi_read_reg(uint32 addr, uint32 *u32data)
/**
* @fn nm_spi_read_reg_with_ret
* @brief Read register with error code return
* @param[in] u32Addr
* Register address
* @param[out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return @ref M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_reg_with_ret(uint32 addr, uint32 *u32data)
{
uint8 retry = SPI_RETRY_COUNT;
sint8 result = N_OK;
volatile sint8 result = N_OK;
uint8 cmd = CMD_SINGLE_READ;
uint8 tmp[4];
uint8 clockless = 0;
@ -1028,13 +655,7 @@ _RETRY_:
cmd = CMD_INTERNAL_READ;
clockless = 1;
}
else
{
cmd = CMD_SINGLE_READ;
clockless = 0;
}
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, 0, 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, read reg (%08x)...\n", (unsigned int)addr);
@ -1053,14 +674,6 @@ _RETRY_:
M2M_ERR("[nmi spi]: Failed data read...\n");
goto _FAIL_;
}
#else
result = spi_cmd_complete(cmd, addr, (uint8*)&tmp[0], 4, clockless);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
goto _FAIL_;
}
#endif
*u32data = tmp[0] |
((uint32)tmp[1] << 8) |
@ -1070,7 +683,6 @@ _RETRY_:
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
@ -1088,17 +700,14 @@ static sint8 nm_spi_read(uint32 addr, uint8 *buf, uint16 size)
uint8 cmd = CMD_DMA_EXT_READ;
sint8 result;
uint8 retry = SPI_RETRY_COUNT;
#if defined USE_OLD_SPI_SW
uint8 tmp[2];
uint8 single_byte_workaround = 0;
#endif
_RETRY_:
/**
Command
**/
#if defined USE_OLD_SPI_SW
if (size == 1)
{
//Workaround hardware problem with single byte transfers over SPI bus
@ -1132,13 +741,6 @@ _RETRY_:
M2M_ERR("[nmi spi]: Failed block data read...\n");
goto _FAIL_;
}
#else
result = spi_cmd_complete(cmd, addr, buf, size, 0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
goto _FAIL_;
}
#endif
_FAIL_:
if(result != N_OK)
@ -1170,31 +772,32 @@ static void spi_init_pkt_sz(void)
val32 &= ~(0x7 << 4);
switch(DATA_PKT_SZ)
{
case 256: val32 |= (0 << 4); break;
case 512: val32 |= (1 << 4); break;
case 1024: val32 |= (2 << 4); break;
case 2048: val32 |= (3 << 4); break;
case 4096: val32 |= (4 << 4); break;
case 8192: val32 |= (5 << 4); break;
case 256:
val32 |= (0 << 4);
break;
case 512:
val32 |= (1 << 4);
break;
case 1024:
val32 |= (2 << 4);
break;
case 2048:
val32 |= (3 << 4);
break;
case 4096:
val32 |= (4 << 4);
break;
case 8192:
val32 |= (5 << 4);
break;
}
nm_spi_write_reg(SPI_BASE+0x24, val32);
}
sint8 nm_spi_reset(void)
{
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
return M2M_SUCCESS;
}
/*
/**
* @fn nm_spi_init
* @brief Initialize the SPI
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
* @return @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_init(void)
{
@ -1207,17 +810,15 @@ sint8 nm_spi_init(void)
**/
gu8Crc_off = 0;
// TODO: We can remove the CRC trials if there is a definite way to reset
// the SPI to it's initial value.
if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)) {
if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, &reg) != M2M_SUCCESS) {
/* Read failed. Try with CRC off. This might happen when module
is removed but chip isn't reset*/
gu8Crc_off = 1;
M2M_ERR("[nmi spi]: Failed internal read protocol with CRC on, retrying with CRC off...\n");
if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)){
if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, &reg) != M2M_SUCCESS) {
// Read failed with both CRC on and off, something went bad
M2M_ERR( "[nmi spi]: Failed internal read protocol...\n");
return 0;
return M2M_ERR_BUS_FAIL;
}
}
if(gu8Crc_off == 0)
@ -1225,9 +826,9 @@ sint8 nm_spi_init(void)
reg &= ~0xc; /* disable crc checking */
reg &= ~0x70;
reg |= (0x5 << 4);
if (!spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg)) {
if(nm_spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg) != M2M_SUCCESS) {
M2M_ERR( "[nmi spi]: Failed internal write protocol reg...\n");
return 0;
return M2M_ERR_BUS_FAIL;
}
gu8Crc_off = 1;
}
@ -1235,7 +836,7 @@ sint8 nm_spi_init(void)
/**
make sure can read back chip id correctly
**/
if (!spi_read_reg(0x1000, &chipid)) {
if(nm_spi_read_reg_with_ret(0x1000, &chipid) != M2M_SUCCESS) {
M2M_ERR("[nmi spi]: Fail cmd read chip id...\n");
return M2M_ERR_BUS_FAIL;
}
@ -1247,13 +848,10 @@ sint8 nm_spi_init(void)
return M2M_SUCCESS;
}
/*
/**
* @fn nm_spi_init
* @brief DeInitialize the SPI
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Samer Sarhan
* @date 27 Feb 2015
* @version 1.0
* @return @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_deinit(void)
{
@ -1267,67 +865,16 @@ sint8 nm_spi_deinit(void)
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_spi_read_reg(uint32 u32Addr)
{
uint32 u32Val;
spi_read_reg(u32Addr, &u32Val);
nm_spi_read_reg_with_ret(u32Addr, &u32Val);
return u32Val;
}
/*
* @fn nm_spi_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
{
sint8 s8Ret;
s8Ret = spi_read_reg(u32Addr,pu32RetVal);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
/*
* @fn nm_spi_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val)
{
sint8 s8Ret;
s8Ret = spi_write_reg(u32Addr, u32Val);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
/*
* @fn nm_spi_read_block
* @brief Read block of data

View File

@ -36,7 +36,7 @@
#ifdef CONF_WINC_USE_UART
#include "driver/include/nmuart.h"
#include "driver/source/nmuart.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#define HDR_SZ 12

View File

@ -4,7 +4,7 @@
*
* \brief BSD compatible socket interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -70,6 +70,7 @@ MACROS
#define SSL_FLAGS_CACHE_SESSION NBIT4
#define SSL_FLAGS_NO_TX_COPY NBIT5
#define SSL_FLAGS_CHECK_SNI NBIT6
#define SSL_FLAGS_DELAY NBIT7
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
PRIVATE DATA TYPES
@ -89,7 +90,7 @@ typedef struct{
/*!
* @brief
*/
typedef struct{
typedef struct {
uint8 *pu8UserBuffer;
uint16 u16UserBufferSize;
uint16 u16SessionID;
@ -97,7 +98,10 @@ typedef struct{
uint8 bIsUsed;
uint8 u8SSLFlags;
uint8 bIsRecvPending;
}tstrSocket;
uint8 u8AlpnStatus;
uint8 u8ErrSource;
uint8 u8ErrCode;
} tstrSocket;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
GLOBALS
@ -112,7 +116,9 @@ volatile uint16 gu16SessionID = 0;
volatile tpfAppSocketCb gpfAppSocketCb;
volatile tpfAppResolveCb gpfAppResolveCb;
volatile uint8 gbSocketInit = 0;
volatile tpfPingCb gfpPingCb;
static tpfPingCb gfpPingCb = NULL;
static uint32 gu32PingId = 0;
/*********************************************************************
Function
@ -152,6 +158,8 @@ NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint
s16Diff = u16Read - gastrSockets[sock].u16UserBufferSize;
if(s16Diff > 0)
{
/* We don't expect to be here. Firmware 19.6.4 and later only sends data to the driver according to the application's buffer size.
* But it is worth keeping this check, eg in case the application calls recv again with a smaller buffer size, or in case of HIF hacking. */
u8SetRxDone = 0;
u16Read = gastrSockets[sock].u16UserBufferSize;
}
@ -162,8 +170,8 @@ NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint
pstrRecv->s16BufferSize = u16Read;
pstrRecv->u16RemainingSize -= u16Read;
if (gpfAppSocketCb)
gpfAppSocketCb(sock,u8SocketMsg, pstrRecv);
if(gpfAppSocketCb)
gpfAppSocketCb(sock, u8SocketMsg, pstrRecv);
u16ReadCount -= u16Read;
u32Address += u16Read;
@ -183,7 +191,7 @@ NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint
M2M_INFO("(ERRR)Current <%d>\n", u16ReadCount);
break;
}
}while(u16ReadCount != 0);
} while(u16ReadCount != 0);
}
}
/*********************************************************************
@ -213,31 +221,31 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
tstrBindReply strBindReply;
tstrSocketBindMsg strBind;
if(hif_receive(u32Address, (uint8*)&strBindReply, sizeof(tstrBindReply), 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strBindReply, sizeof(tstrBindReply), 0) == M2M_SUCCESS)
{
strBind.status = strBindReply.s8Status;
if(gpfAppSocketCb)
gpfAppSocketCb(strBindReply.sock,SOCKET_MSG_BIND,&strBind);
gpfAppSocketCb(strBindReply.sock, SOCKET_MSG_BIND, &strBind);
}
}
else if(u8OpCode == SOCKET_CMD_LISTEN)
{
tstrListenReply strListenReply;
tstrSocketListenMsg strListen;
if(hif_receive(u32Address, (uint8*)&strListenReply, sizeof(tstrListenReply), 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strListenReply, sizeof(tstrListenReply), 0) == M2M_SUCCESS)
{
strListen.status = strListenReply.s8Status;
if(gpfAppSocketCb)
gpfAppSocketCb(strListenReply.sock,SOCKET_MSG_LISTEN, &strListen);
gpfAppSocketCb(strListenReply.sock, SOCKET_MSG_LISTEN, &strListen);
}
}
else if(u8OpCode == SOCKET_CMD_ACCEPT)
{
tstrAcceptReply strAcceptReply;
tstrSocketAcceptMsg strAccept;
if(hif_receive(u32Address, (uint8*)&strAcceptReply, sizeof(tstrAcceptReply), 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strAcceptReply, sizeof(tstrAcceptReply), 0) == M2M_SUCCESS)
{
if(strAcceptReply.sConnectedSock >= 0)
if((strAcceptReply.sConnectedSock >= 0) && (strAcceptReply.sConnectedSock < MAX_SOCKET))
{
gastrSockets[strAcceptReply.sConnectedSock].u8SSLFlags = gastrSockets[strAcceptReply.sListenSock].u8SSLFlags;
gastrSockets[strAcceptReply.sConnectedSock].bIsUsed = 1;
@ -250,7 +258,7 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
++gu16SessionID;
gastrSockets[strAcceptReply.sConnectedSock].u16SessionID = gu16SessionID;
M2M_DBG("Socket %d session ID = %d\r\n",strAcceptReply.sConnectedSock , gu16SessionID );
M2M_DBG("Socket %d session ID = %d\r\n", strAcceptReply.sConnectedSock, gu16SessionID);
}
strAccept.sock = strAcceptReply.sConnectedSock;
strAccept.strAddr.sin_family = AF_INET;
@ -260,29 +268,51 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
gpfAppSocketCb(strAcceptReply.sListenSock, SOCKET_MSG_ACCEPT, &strAccept);
}
}
else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT))
else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT_ALPN))
{
tstrConnectReply strConnectReply;
/* Note that for successful connections the fw always sends SOCKET_CMD_CONNECT, even for SSL connections. */
tstrConnectAlpnReply strConnectAlpnReply = {{0}};
tstrSocketConnectMsg strConnMsg;
if(hif_receive(u32Address, (uint8*)&strConnectReply, sizeof(tstrConnectReply), 0) == M2M_SUCCESS)
uint16 u16HifSz = sizeof(tstrConnectAlpnReply);
if(u8OpCode != SOCKET_CMD_SSL_CONNECT_ALPN)
u16HifSz = sizeof(tstrConnectReply);
if(hif_receive(u32Address, (uint8*)&strConnectAlpnReply, u16HifSz, 0) == M2M_SUCCESS)
{
strConnMsg.sock = strConnectReply.sock;
strConnMsg.s8Error = strConnectReply.s8Error;
if(strConnectReply.s8Error == SOCK_ERR_NO_ERROR)
if((strConnectAlpnReply.strConnReply.sock >= 0) && (strConnectAlpnReply.strConnReply.sock < MAX_SOCKET))
{
gastrSockets[strConnectReply.sock].u16DataOffset = strConnectReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET;
uint8 u8Msg = SOCKET_MSG_CONNECT;
strConnMsg.sock = strConnectAlpnReply.strConnReply.sock;
strConnMsg.s8Error = strConnectAlpnReply.strConnReply.s8Error;
/* If the SOCKET_CMD_SSL_CONNECT op code is received and the socket was already connected, then the
callback corresponds to an attempt to make the socket secure. */
if(0 != gastrSockets[strConnMsg.sock].u16DataOffset)
{
u8Msg = SOCKET_MSG_SECURE;
}
if(strConnectAlpnReply.strConnReply.s8Error == SOCK_ERR_NO_ERROR)
{
gastrSockets[strConnMsg.sock].u16DataOffset = strConnectAlpnReply.strConnReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET;
gastrSockets[strConnMsg.sock].u8AlpnStatus = strConnectAlpnReply.u8AppProtocolIdx;
}
else
{
gastrSockets[strConnMsg.sock].u8ErrSource = strConnectAlpnReply.strConnReply.u8ErrSource;
gastrSockets[strConnMsg.sock].u8ErrCode = strConnectAlpnReply.strConnReply.u8ErrCode;
}
if(gpfAppSocketCb)
gpfAppSocketCb(strConnectReply.sock,SOCKET_MSG_CONNECT, &strConnMsg);
gpfAppSocketCb(strConnMsg.sock, u8Msg, &strConnMsg);
}
}
}
else if(u8OpCode == SOCKET_CMD_DNS_RESOLVE)
{
tstrDnsReply strDnsReply;
if(hif_receive(u32Address, (uint8*)&strDnsReply, sizeof(tstrDnsReply), 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strDnsReply, sizeof(tstrDnsReply), 0) == M2M_SUCCESS)
{
if(gpfAppResolveCb)
gpfAppResolveCb((uint8*)strDnsReply.acHostName, strDnsReply.u32HostIP);
gpfAppResolveCb((uint8 *)strDnsReply.acHostName, strDnsReply.u32HostIP);
}
}
else if((u8OpCode == SOCKET_CMD_RECV) || (u8OpCode == SOCKET_CMD_RECVFROM) || (u8OpCode == SOCKET_CMD_SSL_RECV))
@ -301,7 +331,9 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
/* Read RECV REPLY data structure.
*/
u16ReadSize = sizeof(tstrRecvReply);
if(hif_receive(u32Address, (uint8*)&strRecvReply, u16ReadSize, 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strRecvReply, u16ReadSize, 0) == M2M_SUCCESS)
{
if((strRecvReply.sock >= 0) && (strRecvReply.sock < MAX_SOCKET))
{
uint16 u16SessionID = 0;
@ -327,8 +359,9 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
u32Address += u16DataOffset;
/* Read the Application data and deliver it to the application callback in
the given application buffer. If the buffer is smaller than the received data,
the data is passed to the application in chunks according to its buffer size.
the given application buffer. Firmware since 19.6.4 only sends data up to
the size of the application buffer. For TCP, a new call to recv is needed
in order to retrieve any outstanding data from firmware.
*/
u16ReadSize = (uint16)s16RecvStatus;
Socket_ReadSocketData(sock, &strRecvMsg, u8CallbackMsgID, u32Address, u16ReadSize);
@ -340,12 +373,12 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
strRecvMsg.s16BufferSize = s16RecvStatus;
strRecvMsg.pu8Buffer = NULL;
if(gpfAppSocketCb)
gpfAppSocketCb(sock,u8CallbackMsgID, &strRecvMsg);
gpfAppSocketCb(sock, u8CallbackMsgID, &strRecvMsg);
}
}
else
{
M2M_DBG("Discard recv callback %d %d \r\n",u16SessionID , gastrSockets[sock].u16SessionID);
M2M_DBG("Discard recv callback %d %d \r\n", u16SessionID, gastrSockets[sock].u16SessionID);
if(u16ReadSize < u16BufferSize)
{
if(hif_receive(0, NULL, 0, 1) == M2M_SUCCESS)
@ -356,6 +389,7 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
}
}
}
}
else if((u8OpCode == SOCKET_CMD_SEND) || (u8OpCode == SOCKET_CMD_SENDTO) || (u8OpCode == SOCKET_CMD_SSL_SEND))
{
SOCKET sock;
@ -366,34 +400,36 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
if(u8OpCode == SOCKET_CMD_SENDTO)
u8CallbackMsgID = SOCKET_MSG_SENDTO;
if(hif_receive(u32Address, (uint8*)&strReply, sizeof(tstrSendReply), 0) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strReply, sizeof(tstrSendReply), 0) == M2M_SUCCESS)
{
if((strReply.sock >=0) && (strReply.sock < MAX_SOCKET))
{
uint16 u16SessionID = 0;
sock = strReply.sock;
u16SessionID = strReply.u16SessionID;
M2M_DBG("send callback session ID = %d\r\n",u16SessionID);
M2M_DBG("send callback session ID = %d\r\n", u16SessionID);
s16Rcvd = NM_BSP_B_L_16(strReply.s16SentBytes);
if(u16SessionID == gastrSockets[sock].u16SessionID)
{
if(gpfAppSocketCb)
gpfAppSocketCb(sock,u8CallbackMsgID, &s16Rcvd);
gpfAppSocketCb(sock, u8CallbackMsgID, &s16Rcvd);
}
else
{
M2M_DBG("Discard send callback %d %d \r\n",u16SessionID , gastrSockets[sock].u16SessionID);
M2M_DBG("Discard send callback %d %d \r\n", u16SessionID, gastrSockets[sock].u16SessionID);
}
}
}
}
else if(u8OpCode == SOCKET_CMD_PING)
{
tstrPingReply strPingReply;
if(hif_receive(u32Address, (uint8*)&strPingReply, sizeof(tstrPingReply), 1) == M2M_SUCCESS)
if(hif_receive(u32Address, (uint8 *)&strPingReply, sizeof(tstrPingReply), 1) == M2M_SUCCESS)
{
gfpPingCb = (void (*)(uint32 , uint32 , uint8))strPingReply.u32CmdPrivate;
if(gfpPingCb != NULL)
if((gu32PingId == strPingReply.u32CmdPrivate) && (gfpPingCb != NULL))
{
gfpPingCb(strPingReply.u32IPAddr, strPingReply.u32RTT, strPingReply.u8ErrorCode);
}
@ -498,7 +534,7 @@ Version
Date
4 June 2012
*********************************************************************/
SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Flags)
SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Config)
{
SOCKET sock = -1;
uint8 u8SockID;
@ -554,12 +590,15 @@ SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Flags)
pstrSock->u16SessionID = gu16SessionID;
M2M_INFO("Socket %d session ID = %d\r\n",sock, gu16SessionID );
if(u8Flags & SOCKET_FLAGS_SSL)
if((u8Type == SOCK_STREAM) && (u8Config != SOCKET_CONFIG_SSL_OFF))
{
tstrSSLSocketCreateCmd strSSLCreate;
strSSLCreate.sslSock = sock;
SOCKET_REQUEST(SOCKET_CMD_SSL_CREATE, (uint8 *)&strSSLCreate, sizeof(tstrSSLSocketCreateCmd), 0, 0, 0);
pstrSock->u8SSLFlags = SSL_FLAGS_ACTIVE | SSL_FLAGS_NO_TX_COPY;
SOCKET_REQUEST(SOCKET_CMD_SSL_CREATE, (uint8*)&strSSLCreate, sizeof(tstrSSLSocketCreateCmd), 0, 0, 0);
if(u8Config == SOCKET_CONFIG_SSL_DELAY)
pstrSock->u8SSLFlags |= SSL_FLAGS_DELAY;
}
}
}
@ -587,7 +626,7 @@ Date
sint8 WINC1500_EXPORT(bind)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((pstrAddr != NULL) && (sock >= 0) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
if((pstrAddr != NULL) && (sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
{
tstrBindCmd strBind;
uint8 u8CMD = SOCKET_CMD_BIND;
@ -633,7 +672,7 @@ sint8 WINC1500_EXPORT(listen)(SOCKET sock, uint8 backlog)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
tstrListenCmd strListen;
@ -671,7 +710,7 @@ sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8 *addrlen
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1) )
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
s8Ret = SOCK_ERR_NO_ERROR;
}
@ -699,7 +738,7 @@ Date
sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
if((sock >= 0) && (sock < MAX_SOCKET) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
{
tstrConnectCmd strConnect;
uint8 u8Cmd = SOCKET_CMD_CONNECT;
@ -721,6 +760,52 @@ sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8A
return s8Ret;
}
/*********************************************************************
Function
secure
Description
Make secure (TLS) an open TCP client connection.
Return
Author
Matthew Gunton
Version
1.0
Date
7 November 2019
*********************************************************************/
sint8 secure(SOCKET sock)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY)
&& (gastrSockets[sock].u16DataOffset != 0)
)
{
tstrConnectCmd strConnect = {0};
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_DELAY;
strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags;
strConnect.sock = sock;
strConnect.u16SessionID = gastrSockets[sock].u16SessionID;
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SECURE, (uint8*)&strConnect, sizeof(tstrConnectCmd), NULL, 0, 0);
if(s8Ret != SOCK_ERR_NO_ERROR)
{
s8Ret = SOCK_ERR_INVALID;
}
}
}
return s8Ret;
}
/*********************************************************************
Function
send
@ -741,7 +826,7 @@ sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLeng
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
{
uint16 u16DataOffset;
tstrSendCmd strSend;
@ -758,13 +843,16 @@ sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLeng
{
u16DataOffset = UDP_TX_PACKET_OFFSET;
}
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY))
)
{
u8Cmd = SOCKET_CMD_SSL_SEND;
u16DataOffset = gastrSockets[sock].u16DataOffset;
}
s16Ret = SOCKET_REQUEST(u8Cmd|M2M_REQ_DATA_PKT, (uint8*)&strSend, sizeof(tstrSendCmd), pvSendBuffer, u16SendLength, u16DataOffset);
s16Ret = SOCKET_REQUEST(u8Cmd|M2M_REQ_DATA_PKT, (uint8 *)&strSend, sizeof(tstrSendCmd), pvSendBuffer, u16SendLength, u16DataOffset);
if(s16Ret != SOCK_ERR_NO_ERROR)
{
s16Ret = SOCK_ERR_BUFFER_FULL;
@ -793,7 +881,7 @@ sint16 WINC1500_EXPORT(sendto)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLe
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
{
if(gastrSockets[sock].bIsUsed)
{
@ -848,10 +936,10 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
{
s16Ret = SOCK_ERR_NO_ERROR;
gastrSockets[sock].pu8UserBuffer = (uint8*)pvRecvBuf;
gastrSockets[sock].pu8UserBuffer = (uint8 *)pvRecvBuf;
gastrSockets[sock].u16UserBufferSize = u16BufLen;
if(!gastrSockets[sock].bIsRecvPending)
@ -860,7 +948,10 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
uint8 u8Cmd = SOCKET_CMD_RECV;
gastrSockets[sock].bIsRecvPending = 1;
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY))
)
{
u8Cmd = SOCKET_CMD_SSL_RECV;
}
@ -872,6 +963,7 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec);
strRecv.sock = sock;
strRecv.u16SessionID = gastrSockets[sock].u16SessionID;
strRecv.u16BufLen = u16BufLen;
s16Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strRecv, sizeof(tstrRecvCmd), NULL , 0, 0);
if(s16Ret != SOCK_ERR_NO_ERROR)
@ -904,7 +996,7 @@ sint8 WINC1500_EXPORT(close)(SOCKET sock)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
M2M_INFO("Sock to delete <%d>\n", sock);
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
uint8 u8Cmd = SOCKET_CMD_CLOSE;
tstrCloseCmd strclose;
@ -915,12 +1007,12 @@ sint8 WINC1500_EXPORT(close)(SOCKET sock)
{
u8Cmd = SOCKET_CMD_SSL_CLOSE;
}
s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strclose, sizeof(tstrCloseCmd), NULL,0, 0);
s8Ret = SOCKET_REQUEST(u8Cmd, (uint8 *)&strclose, sizeof(tstrCloseCmd), NULL, 0, 0);
if(s8Ret != SOCK_ERR_NO_ERROR)
{
s8Ret = SOCK_ERR_INVALID;
}
m2m_memset((uint8*)&gastrSockets[sock], 0, sizeof(tstrSocket));
m2m_memset((uint8 *)&gastrSockets[sock], 0, sizeof(tstrSocket));
}
return s8Ret;
}
@ -946,12 +1038,12 @@ Date
sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec)
{
sint16 s16Ret = SOCK_ERR_NO_ERROR;
if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
{
if(gastrSockets[sock].bIsUsed)
{
s16Ret = SOCK_ERR_NO_ERROR;
gastrSockets[sock].pu8UserBuffer = (uint8*)pvRecvBuf;
gastrSockets[sock].pu8UserBuffer = (uint8 *)pvRecvBuf;
gastrSockets[sock].u16UserBufferSize = u16BufLen;
if(!gastrSockets[sock].bIsRecvPending)
@ -967,6 +1059,7 @@ sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen,
strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec);
strRecv.sock = sock;
strRecv.u16SessionID = gastrSockets[sock].u16SessionID;
strRecv.u16BufLen = u16BufLen;
s16Ret = SOCKET_REQUEST(SOCKET_CMD_RECVFROM, (uint8*)&strRecv, sizeof(tstrRecvCmd), NULL , 0, 0);
if(s16Ret != SOCK_ERR_NO_ERROR)
@ -1003,14 +1096,12 @@ Date
*********************************************************************/
uint32 nmi_inet_addr(char *pcIpAddr)
{
uint8 tmp;
uint8 tmp = 0;
uint32 u32IP = 0;
uint8 au8IP[4];
uint8 c;
uint8 i, j;
tmp = 0;
for(i = 0; i < 4; ++i)
{
j = 0;
@ -1093,75 +1184,61 @@ static sint8 sslSetSockOpt(SOCKET sock, uint8 u8Opt, const void *pvOptVal, uint
if(sock < TCP_SOCK_MAX)
{
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
{
uint8 sslFlag = 0;
s8Ret = SOCK_ERR_NO_ERROR;
if(u16OptLen == sizeof(int))
{
if(u8Opt == SO_SSL_BYPASS_X509_VERIF)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_BYPASS_X509;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_BYPASS_X509;
}
s8Ret = SOCK_ERR_NO_ERROR;
sslFlag = SSL_FLAGS_BYPASS_X509;
}
else if(u8Opt == SO_SSL_ENABLE_SESSION_CACHING)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CACHE_SESSION;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CACHE_SESSION;
}
s8Ret = SOCK_ERR_NO_ERROR;
sslFlag = SSL_FLAGS_CACHE_SESSION;
}
else if(u8Opt == SO_SSL_ENABLE_SNI_VALIDATION)
{
sslFlag = SSL_FLAGS_CHECK_SNI;
}
}
if(sslFlag)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CHECK_SNI;
gastrSockets[sock].u8SSLFlags |= sslFlag;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CHECK_SNI;
gastrSockets[sock].u8SSLFlags &= ~sslFlag;
}
s8Ret = SOCK_ERR_NO_ERROR;
}
else if(u8Opt == SO_SSL_SNI)
else if(
((u8Opt == SO_SSL_SNI) && (u16OptLen < HOSTNAME_MAX_SIZE))
|| ((u8Opt == SO_SSL_ALPN) && (u16OptLen <= ALPN_LIST_MAX_SIZE))
)
{
if(u16OptLen < HOSTNAME_MAX_SIZE)
{
uint8 *pu8SNI = (uint8*)pvOptVal;
tstrSSLSetSockOptCmd strCmd;
tstrSSLSetSockOptCmd strCmd = {0};
strCmd.sock = sock;
strCmd.u16SessionID = gastrSockets[sock].u16SessionID;
strCmd.u8Option = u8Opt;
strCmd.u32OptLen = u16OptLen;
m2m_memcpy(strCmd.au8OptVal, pu8SNI, HOSTNAME_MAX_SIZE);
m2m_memcpy(strCmd.au8OptVal, (uint8*)pvOptVal, u16OptLen);
if(SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd),
0, 0, 0) == M2M_ERR_MEM_ALLOC)
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0);
if(s8Ret == M2M_ERR_MEM_ALLOC)
{
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT | M2M_REQ_DATA_PKT,
(uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0);
}
s8Ret = SOCK_ERR_NO_ERROR;
}
else
{
M2M_ERR("SNI Exceeds Max Length\n");
}
}
else
{
M2M_ERR("Unknown SSL Socket Option %d\n",u8Opt);
M2M_ERR("Unknown SSL Socket Option %d\n", u8Opt);
s8Ret = SOCK_ERR_INVALID_ARG;
}
}
else
@ -1193,13 +1270,15 @@ sint8 WINC1500_EXPORT(setsockopt)(SOCKET sock, uint8 u8Level, uint8 option_nam
const void *option_value, uint16 u16OptionLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1))
{
if(u8Level == SOL_SSL_SOCKET)
{
s8Ret = sslSetSockOpt(sock, option_name, option_value, u16OptionLen);
}
else
else if(u8Level == SOL_SOCKET)
{
if(u16OptionLen == sizeof(uint32))
{
uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION;
tstrSetSocketOptCmd strSetSockOpt;
@ -1208,13 +1287,14 @@ sint8 WINC1500_EXPORT(setsockopt)(SOCKET sock, uint8 u8Level, uint8 option_nam
strSetSockOpt.u32OptionValue = *(uint32*)option_value;
strSetSockOpt.u16SessionID = gastrSockets[sock].u16SessionID;
s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL,0, 0);
s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL, 0, 0);
if(s8Ret != SOCK_ERR_NO_ERROR)
{
s8Ret = SOCK_ERR_INVALID;
}
}
}
}
return s8Ret;
}
/*********************************************************************
@ -1237,8 +1317,8 @@ Date
*********************************************************************/
sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8* pu8OptLen)
{
/* TBD */
return M2M_SUCCESS;
// This is not implemented so return a value that will cause failure should this be used.
return SOCK_ERR_INVALID_ARG;
}
/*********************************************************************
Function
@ -1265,16 +1345,96 @@ sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb)
if((u32DstIP != 0) && (fpPingCb != NULL))
{
tstrPingCmd strPingCmd;
strPingCmd.u16PingCount = 1;
strPingCmd.u32DestIPAddr = u32DstIP;
strPingCmd.u32CmdPrivate = (uint32)fpPingCb;
strPingCmd.u32CmdPrivate = ++gu32PingId;
strPingCmd.u8TTL = u8TTL;
s8Ret = SOCKET_REQUEST(SOCKET_CMD_PING, (uint8*)&strPingCmd, sizeof(tstrPingCmd), NULL, 0, 0);
gfpPingCb = fpPingCb;
s8Ret = SOCKET_REQUEST(SOCKET_CMD_PING, (uint8 *)&strPingCmd, sizeof(tstrPingCmd), NULL, 0, 0);
}
return s8Ret;
}
/*********************************************************************
Function
set_alpn_protocol_list
Description
This function sets the protocol list used for application-layer protocol negotiation (ALPN).
If used, it must be called after creating a SSL socket (using @ref socket) and before
connecting/binding (using @ref connect or @ref bind).
Return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*********************************************************************/
sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (sock < TCP_SOCK_MAX) && (pcProtocolList != NULL))
{
uint8 u8Length = m2m_strlen((uint8 *)pcProtocolList);
if((u8Length > 0) && (u8Length < ALPN_LIST_MAX_APP_LENGTH))
{
/*
ALPN socket option requires Alpn list in this format:
0 1 2 3 ... (bytes)
+-------+-------+-------+ ... +-------+ ... +-------+ ...
| Length L (BE) | len1 | name1... | len2 | name2... | len3 | name3...
+-------+-------+-------+ ... +-------+ ... +-------+ ...
Length fields do not include themselves.
*/
uint8 au8AlpnList[ALPN_LIST_MAX_SIZE] = {0};
uint8 *pu8Ptr = &au8AlpnList[3] + u8Length;
uint8 u8Len = 0;
m2m_memcpy(&au8AlpnList[3], (uint8 *)pcProtocolList, u8Length);
u8Length++;
au8AlpnList[1] = u8Length;
au8AlpnList[2] = ' ';
/* Convert space characters into length fields. */
while(u8Length--)
{
if(*--pu8Ptr == ' ')
{
if(u8Len == 0) goto ERR;
*pu8Ptr = u8Len;
u8Len = 0;
}
else u8Len++;
}
s8Ret = WINC1500_EXPORT(setsockopt)(sock, SOL_SSL_SOCKET, SO_SSL_ALPN, au8AlpnList, sizeof(au8AlpnList));
}
}
ERR:
return s8Ret;
}
/*********************************************************************
Function
get_alpn_protocol_index
Description
This function gets the protocol list used for application-layer protocol negotiation (ALPN).
If used, it must be called after creating a SSL socket (using @ref socket) and before
connecting/binding (using @ref connect or @ref bind).
Return
The function returns the index of the selected application-layer protocol.
Special values:
0: no negotiation has occurred.
<0: error.
*********************************************************************/
sint8 get_alpn_index(SOCKET sock)
{
if(sock >= TCP_SOCK_MAX || sock < 0)
return SOCK_ERR_INVALID_ARG;
if(!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) || !gastrSockets[sock].bIsUsed)
return SOCK_ERR_INVALID_ARG;
return gastrSockets[sock].u8AlpnStatus;
}
/*********************************************************************
Function
sslEnableCertExpirationCheck
@ -1322,3 +1482,27 @@ uint8 IsSocketReady(void)
{
return gbSocketInit;
}
/*********************************************************************
Function
get_error_detail
Description
This function gets detail about a socket failure.
The application can call this when notified of a socket failure via
@ref SOCKET_MSG_CONNECT or @ref SOCKET_MSG_RECV.
If used, it must be called before @ref close.
Return
The function returns @ref SOCK_ERR_NO_ERROR if the request is successful
and a negative value otherwise.
*********************************************************************/
sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr)
{
if((sock >= TCP_SOCK_MAX) || (sock < 0) || (pstrErr == NULL))
return SOCK_ERR_INVALID_ARG;
if(!gastrSockets[sock].bIsUsed)
return SOCK_ERR_INVALID_ARG;
pstrErr->enuErrSource = gastrSockets[sock].u8ErrSource;
pstrErr->u8ErrCode = gastrSockets[sock].u8ErrCode;
return SOCK_ERR_NO_ERROR;
}

View File

@ -4,7 +4,7 @@
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -539,18 +539,17 @@ sint8 spi_flash_enable(uint8 enable)
}
/* GPIO15/16/17/18 */
u32Val &= ~((0x7777ul) << 12);
if(enable) {
u32Val |= ((0x1111ul) << 12);
nm_write_reg(0x1410, u32Val);
if(enable) {
spi_flash_leave_low_power_mode();
} else {
spi_flash_enter_low_power_mode();
}
/* Disable pinmux to SPI flash to minimize leakage. */
u32Val &= ~((0x7777ul) << 12);
u32Val |= ((0x0010ul) << 12);
nm_write_reg(0x1410, u32Val);
}
}
ERR1:
return s8Ret;
}