diff --git a/src/drivers/winc1500/include/bsp/include/nm_bsp.h b/src/drivers/winc1500/include/bsp/include/nm_bsp.h index ed5f7b47d..1294713a7 100644 --- a/src/drivers/winc1500/include/bsp/include/nm_bsp.h +++ b/src/drivers/winc1500/include/bsp/include/nm_bsp.h @@ -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 * @@ -31,7 +31,7 @@ * \asf_license_stop * */ - + /** @defgroup nm_bsp BSP @brief Description of the BSP (Board Support Package) module. @@ -51,25 +51,24 @@ #define _NM_BSP_H_ #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) #endif -/*!< +/*!< * 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. */ /**@}*/ //BSPDefine @@ -77,62 +76,61 @@ /**@addtogroup DataT * @{ */ - /*! - * @typedef void (*tpfNmBspIsr) (void); + * @typedef void (*tpfNmBspIsr) (void); * @brief Pointer to function.\n Used as a data type of ISR function registered by * @ref nm_bsp_register_isr. - * @return None + * @return None */ typedef void (*tpfNmBspIsr)(void); - /*! - * @ingroup DataTypes - * @typedef unsigned char uint8; - * @brief Range of values between 0 to 255 - */ -typedef unsigned char uint8; +/*! +* @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 - */ -typedef unsigned short uint16; +/*! +* @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 - */ -typedef unsigned long uint32; +/*! +* @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 - */ -typedef signed char sint8; +/*! +* @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 - */ -typedef signed short sint16; +/*! +* @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 - */ -typedef signed long sint32; +/*! +* @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,10 +139,10 @@ 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); + * @fn sint8 nm_bsp_init(void); * @brief This function is used to initialize the Board Support * Package (BSP) in order to prepare the WINC before any * WINC API calls. @@ -156,50 +154,49 @@ extern "C"{ * initializes the WINC, a hard reset must be applied to start the WINC board by calling * @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. - * - * @see nm_bsp_deinit, nm_bsp_reset + * @note Implementation of this function is host dependent. + * @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. */ sint8 nm_bsp_init(void); /**@}*/ //NmBspInitFn - - /** @defgroup NmBspDeinitFn nm_bsp_deinit - * @ingroup BSPAPI + +/** @defgroup NmBspDeinitFn nm_bsp_deinit + * @ingroup BSPAPI * De-initialization of the BSP (Board Support Package).\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. + * @fn sint8 nm_bsp_deinit(void); + * @brief This function is used to de-initialize the BSP and turn off the WINC board. * @details The nm_bsp_deinit is the last function that should be called after the application has * finished and before the WINC is switched off. A call to this function will turn off the WINC * board by setting CHIP_EN and RESET_N signals low. Every function call of @ref nm_bsp_init * should be matched with a call to nm_bsp_deinit. Failure to do so may result in the WINC * 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. - * @see nm_bsp_init + * @note Implementation of this function is host dependent. + * @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. */ 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); + * @{ + */ +/*! + * @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 * RESET_N signals low, then after an appropriate delay this function puts CHIP_EN high then @@ -212,81 +209,77 @@ 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. - * @see nm_bsp_init, m2m_wifi_init, m2m_wifi_deinit - * @return None - */ + * @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. - * @param [in] u32TimeMsec + * @param [in] u32TimeMsec * Time unit in milliseconds. * @pre Initialize @ref nm_bsp_init first. - * @note Implementation of this function is host dependent. + * @note Implementation of this function is host dependent. * @warning Maximum value must nor exceed 4294967295 milliseconds which is equal to 4294967.295 seconds. - * @see nm_bsp_init - * @return None + * @see nm_bsp_init + * @return None */ 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. + * @fn void nm_bsp_register_isr(tpfNmBspIsr pfIsr); + * @brief Register the host interface interrupt service routine. * @details The WINC board uses the SPI interface to communicate with the host. This function registers * 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. - * @note Implementation of this function is host dependent and called by 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 - * @return None + * @see tpfNmBspIsr + * @return None */ 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 * the application. - * @param [in] u8Enable + * @param [in] u8Enable * - '0' disable interrupts. * - '1' enable interrupts. * @pre The interrupt must be registered using @ref nm_bsp_register_isr first. - * @note Implementation of this function is host dependent and called by HIF layer. + * @note Implementation of this function is host dependent and called by HIF layer. * @see tpfNmBspIsr, nm_bsp_register_isr - * @return None + * @return None */ void nm_bsp_interrupt_ctrl(uint8 u8Enable); /**@}*/ //NmBspInterruptCtrl @@ -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_*/ +#endif /*_NM_BSP_H_*/ diff --git a/src/drivers/winc1500/include/bus_wrapper/include/nm_bus_wrapper.h b/src/drivers/winc1500/include/bus_wrapper/include/nm_bus_wrapper.h index 1394b0aba..60f6dedad 100644 --- a/src/drivers/winc1500/include/bus_wrapper/include/nm_bus_wrapper.h +++ b/src/drivers/winc1500/include/bus_wrapper/include/nm_bus_wrapper.h @@ -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 diff --git a/src/drivers/winc1500/include/common/include/nm_common.h b/src/drivers/winc1500/include/common/include/nm_common.h index 4510d51ae..6b353ef15 100644 --- a/src/drivers/winc1500/include/common/include/nm_common.h +++ b/src/drivers/winc1500/include/common/include/nm_common.h @@ -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,10 +45,11 @@ #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 +#define M2M_TIME_OUT_DELAY 10000 /*states*/ #define M2M_SUCCESS ((sint8)0) @@ -66,83 +67,87 @@ #define M2M_ERR_FAIL ((sint8)-12) #define M2M_ERR_FW_VER_MISMATCH ((sint8)-13) #define M2M_ERR_SCAN_IN_PROGRESS ((sint8)-14) -#define M2M_ERR_INVALID_ARG ((sint8)-15) -#define M2M_ERR_INVALID ((sint8)-16) +/* 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 PROGRAM_START 0x26961735UL -#define BOOT_SUCCESS 0x10add09eUL -#define BOOT_START 0x12345678UL +#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 NBIT31 (0x80000000) -#define NBIT30 (0x40000000) -#define NBIT29 (0x20000000) -#define NBIT28 (0x10000000) -#define NBIT27 (0x08000000) -#define NBIT26 (0x04000000) -#define NBIT25 (0x02000000) -#define NBIT24 (0x01000000) -#define NBIT23 (0x00800000) -#define NBIT22 (0x00400000) -#define NBIT21 (0x00200000) -#define NBIT20 (0x00100000) -#define NBIT19 (0x00080000) -#define NBIT18 (0x00040000) -#define NBIT17 (0x00020000) -#define NBIT16 (0x00010000) -#define NBIT15 (0x00008000) -#define NBIT14 (0x00004000) -#define NBIT13 (0x00002000) -#define NBIT12 (0x00001000) -#define NBIT11 (0x00000800) -#define NBIT10 (0x00000400) -#define NBIT9 (0x00000200) -#define NBIT8 (0x00000100) -#define NBIT7 (0x00000080) -#define NBIT6 (0x00000040) -#define NBIT5 (0x00000020) -#define NBIT4 (0x00000010) -#define NBIT3 (0x00000008) -#define NBIT2 (0x00000004) -#define NBIT1 (0x00000002) -#define NBIT0 (0x00000001) +#define PROGRAM_START 0x26961735UL +#define BOOT_SUCCESS 0x10add09eUL +#define BOOT_START 0x12345678UL -#define M2M_MAX(A,B) ((A) > (B) ? (A) : (B)) -#define M2M_SEL(x,m1,m2,m3) ((x>1)?((x>2)?(m3):(m2)):(m1)) -#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val)) +#define NBIT31 (0x80000000) +#define NBIT30 (0x40000000) +#define NBIT29 (0x20000000) +#define NBIT28 (0x10000000) +#define NBIT27 (0x08000000) +#define NBIT26 (0x04000000) +#define NBIT25 (0x02000000) +#define NBIT24 (0x01000000) +#define NBIT23 (0x00800000) +#define NBIT22 (0x00400000) +#define NBIT21 (0x00200000) +#define NBIT20 (0x00100000) +#define NBIT19 (0x00080000) +#define NBIT18 (0x00040000) +#define NBIT17 (0x00020000) +#define NBIT16 (0x00010000) +#define NBIT15 (0x00008000) +#define NBIT14 (0x00004000) +#define NBIT13 (0x00002000) +#define NBIT12 (0x00001000) +#define NBIT11 (0x00000800) +#define NBIT10 (0x00000400) +#define NBIT9 (0x00000200) +#define NBIT8 (0x00000100) +#define NBIT7 (0x00000080) +#define NBIT6 (0x00000040) +#define NBIT5 (0x00000020) +#define NBIT4 (0x00000010) +#define NBIT3 (0x00000008) +#define NBIT2 (0x00000004) +#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)) -#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL)) -#define BYTE_3(word) ((uint8)(((word) >> 24) & 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 -#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL)) -#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL)) -#define BYTE_2(word) ((uint8)(((word) >> 8 ) & 0x000000FFUL)) -#define BYTE_3(word) ((uint8)(((word) >> 0 ) & 0x000000FFUL)) +/*! 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)) +/*! 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,15 +237,29 @@ 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 void (*at_sb_printf)(const char *_format, ...); + * @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 + * @fn void (*at_sb_printf)(const char *_format, ...); * @brief Chooses which function to use in order to output debug. */ extern NMI_API void (*at_sb_printf)(const char *_format, ...); #ifdef __cplusplus } - #endif -#endif /*_NM_COMMON_H_*/ +#endif +#endif /*_NM_COMMON_H_*/ diff --git a/src/drivers/winc1500/include/driver/include/m2m_ota.h b/src/drivers/winc1500/include/driver/include/m2m_ota.h index 0a125042b..bb81caef0 100644 --- a/src/drivers/winc1500/include/driver/include/m2m_ota.h +++ b/src/drivers/winc1500/include/driver/include/m2m_ota.h @@ -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,24 +83,24 @@ MACROS *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ /**@addtogroup OTACALLBACKS + * @{ */ -/**@{*/ /*! @typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *pstrOtaUpdateInfo); -@brief - A callback to get notification about a potential OTA update. - -@param[in] pstrOtaUpdateInfo - A structure to provide notification payload. +@brief + A callback to get notification about a potential OTA update. -@sa - tstrOtaUpdateInfo +@param[in] pstrOtaUpdateInfo + A structure to provide notification payload. -@warning - The notification is not supported (Not implemented yet) +@sa + tstrOtaUpdateInfo + +@warning + The notification is not supported (Not implemented yet) */ -typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo * pstrOtaUpdateInfo); +typedef void (*tpfOtaNotifCb)(tstrOtaUpdateInfo *pstrOtaUpdateInfo); /*! @@ -115,10 +121,10 @@ typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo * pstrOtaUpdateInfo); Executes other callbacks passed to the OTA module. @see - tenuOtaUpdateStatusType - tenuOtaUpdateStatus + 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,12 +148,12 @@ 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); -@brief +@brief A callback to handle a buffer of data after requesting a Host File read. The callback will provide the status of the read operation and if successful, a pointer to a valid placeholder containing the data read and the amount of @@ -165,298 +171,334 @@ 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); -@brief +@brief A callback executed when the file erase has been completed. @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 - /**@{*/ /*! -@fn \ - NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb) +@ingroup OTACOMMON +@fn \ + 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. +@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); /*! -@fn \ - NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url); +@ingroup WINCOTA +@fn \ + 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. -@warning +@warning Notification Server is not supported in the current version (function is not implemented). -@see - m2m_ota_init +@see + m2m_ota_init -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@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); /*! -@fn \ - NMI_API sint8 m2m_ota_notif_check_for_update(void); +@ingroup WINCOTA +@fn \ + sint8 m2m_ota_notif_check_for_update(void); @brief Synchronous function to check for the OTA update using the Notification Server URL.\n Function is not implemented (not supported at the current version). -@warning +@warning Function is not implemented (not supported at the current version). - -@sa - m2m_ota_init - m2m_ota_notif_set_url -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@sa + m2m_ota_init + m2m_ota_notif_set_url + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. */ NMI_API sint8 m2m_ota_notif_check_for_update(void); /*! -@fn \ - NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period); +@ingroup WINCOTA +@fn \ + 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 - Period in days +@param[in] u32Period + Period in days @warning Function is not implemented (not supported at the current version). -@sa - m2m_ota_init - m2m_ota_notif_check_for_update - m2m_ota_notif_set_url +@sa + m2m_ota_init + m2m_ota_notif_check_for_update + m2m_ota_notif_set_url -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. */ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period); /*! -@fn \ - NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl); +@ingroup WINCOTA +@fn \ + 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 @ref m2m_ota_init @ref m2m_ota_switch_firmware @ref tpfOtaUpdateCb - -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. -\section OTAExample Example +@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 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_ota_switch_firmware(); - } - } - 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) - } - } + 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(); + } + 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 - m2m_ota_start_update(OTA_URL); - } - break; - default: - break; + // ... + case M2M_WIFI_REQ_DHCP_CONF: + { + // After successful connection, start the OTA upgrade + m2m_ota_start_update(OTA_URL); + } + break; + default: + break; + // ... } int main (void) { - sint8 s8Ret; - tstrWifiInitParam param; - tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS; + tstrWifiInitParam param; + sint8 s8Ret = M2M_SUCCESS; + bool rollback_required = FALSE; + tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS; - nm_bsp_init(); - - m2m_memset((uint8*)¶m, 0, sizeof(param)); - param.pfAppWifiCb = wifi_event_cb; - - //Initialize the WINC Driver + // System init, etc should be here... + + m2m_memset((uint8*)¶m, 0, sizeof(param)); + param.pfAppWifiCb = wifi_event_cb; + + // Initialize the WINC Driver s8Ret = m2m_wifi_init(¶m); + 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 - m2m_ota_init(OtaUpdateCb,NULL); + while(1); + } + // Initialize the OTA module + m2m_ota_init(OtaUpdateCb,NULL); - //connect to AP that provide connection to the OTA server - m2m_wifi_default_connect(); + // 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 - while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) { - - } - } + while(1) + { + // Handle the app state machine plus the WINC event handler + while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) { + } + } } -@endcode +@endcode */ -NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl); +NMI_API sint8 m2m_ota_start_update(unsigned char *pcDownloadUrl); /*! -@fn \ - NMI_API sint8 m2m_ota_rollback(void); +@ingroup WINCOTA +@fn \ + 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 - m2m_ota_start_update +@sa + m2m_ota_init + m2m_ota_start_update -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. */ NMI_API sint8 m2m_ota_rollback(void); /*! -@fn \ - NMI_API sint8 m2m_ota_abort(void); +@ingroup OTACOMMON +@fn \ + 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. + 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); /*! -@fn \ - NMI_API sint8 m2m_ota_switch_firmware(void); +@ingroup WINCOTA +@fn \ + 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 - m2m_ota_start_update +@sa + m2m_ota_init + m2m_ota_start_update -@return - The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. */ NMI_API sint8 m2m_ota_switch_firmware(void); /*! -@fn \ - NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb); +@ingroup HFD +@fn \ + 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. @param[in] pcDownloadUrl - Url pointing to the remote file. HTTP/HTTPS only. + Url pointing to the remote file. HTTP/HTTPS only. @param[in] pfHFDGetCb Pointer to a callback (see @ref tpfFileGetCb) to be executed when the download finishes. @@ -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); /*! -@fn \ - NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb); +@ingroup HFD +@fn \ + 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. @@ -491,10 +534,10 @@ NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb p Handler of the file we are trying to read from. Must be valid. @param[in] u32Offset - Offset from start of the file to read from (in bytes). + Offset from start of the file to read from (in bytes). @param[in] u32Size - The amount of data to read (in bytes). + The amount of data to read (in bytes). @param[in] pfHFDReadCb Callback (see @ref tpfFileReadCb) to be executed when the read operation completes. @@ -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); /*! -@fn \ - NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size); +@ingroup HFD +@fn \ + 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. @@ -541,10 +585,10 @@ NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint Pointer to a buffer to store the data being read. Must not be NULL. @param[in] u32Offset - Offset from start of the file to read from (in bytes). + Offset from start of the file to read from (in bytes). @param[in] u32Size - The amount of data to read (in Bytes). + The amount of data to read (in Bytes). @return The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. @@ -631,7 +675,7 @@ static void FileGetCallback(uint8 u8Status, uint8 u8Handler, uint32 u32Size) static void ReadFileSPI(void) { sint8 s8Ret = M2M_ERR_FAIL; - + if(WIFI_STATE_DEINIT != m2m_wifi_get_state()) m2m_wifi_deinit(NULL); @@ -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); /*! -@fn \ - NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb); +@ingroup HFD +@fn \ + 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 } diff --git a/src/drivers/winc1500/include/driver/include/m2m_periph.h b/src/drivers/winc1500/include/driver/include/m2m_periph.h index 10cecf126..001f7cbf0 100644 --- a/src/drivers/winc1500/include/driver/include/m2m_periph.h +++ b/src/drivers/winc1500/include/driver/include/m2m_periph.h @@ -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 * @@ -53,144 +53,63 @@ DATA TYPES *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ /*! -@struct \ - tstrPerphInitParam +@enum \ + tenuGpioNum @brief - Peripheral module initialization parameters. -*/ -typedef struct { - void * arg; -} tstrPerphInitParam; - - -/*! -@enum \ - tenuGpioNum - -@brief - A list of GPIO numbers configurable through the m2m_periph module. + 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_GPIO_MAX + 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 +@enum \ + tenuPullupMask @brief - Allowed pin multiplexing options for I2C master SCL signal. + Bitwise-ORed flags for use in @ref m2m_periph_pullup_ctrl. + +@sa + m2m_periph_pullup_ctrl */ 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. -@sa - m2m_periph_pullup_ctrl - -*/ -typedef enum { - M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP = (1ul << 0), - M2M_PERIPH_PULLUP_DIS_RTC_CLK = (1ul << 1), - M2M_PERIPH_PULLUP_DIS_IRQN = (1ul << 2), - M2M_PERIPH_PULLUP_DIS_GPIO_3 = (1ul << 3), - M2M_PERIPH_PULLUP_DIS_GPIO_4 = (1ul << 4), - M2M_PERIPH_PULLUP_DIS_GPIO_5 = (1ul << 5), - M2M_PERIPH_PULLUP_DIS_SD_DAT3 = (1ul << 6), - M2M_PERIPH_PULLUP_DIS_SD_DAT2_SPI_RXD = (1ul << 7), - M2M_PERIPH_PULLUP_DIS_SD_DAT1_SPI_SSN = (1ul << 9), - M2M_PERIPH_PULLUP_DIS_SD_CMD_SPI_SCK = (1ul << 10), - M2M_PERIPH_PULLUP_DIS_SD_DAT0_SPI_TXD = (1ul << 11), - M2M_PERIPH_PULLUP_DIS_GPIO_6 = (1ul << 12), - M2M_PERIPH_PULLUP_DIS_SD_CLK = (1ul << 13), - M2M_PERIPH_PULLUP_DIS_I2C_SCL = (1ul << 14), - M2M_PERIPH_PULLUP_DIS_I2C_SDA = (1ul << 15), - M2M_PERIPH_PULLUP_DIS_GPIO_11 = (1ul << 16), - M2M_PERIPH_PULLUP_DIS_GPIO_12 = (1ul << 17), - M2M_PERIPH_PULLUP_DIS_GPIO_13 = (1ul << 18), - M2M_PERIPH_PULLUP_DIS_GPIO_14 = (1ul << 19), - M2M_PERIPH_PULLUP_DIS_GPIO_15 = (1ul << 20), - M2M_PERIPH_PULLUP_DIS_GPIO_16 = (1ul << 21), - M2M_PERIPH_PULLUP_DIS_GPIO_17 = (1ul << 22), - M2M_PERIPH_PULLUP_DIS_GPIO_18 = (1ul << 23), - M2M_PERIPH_PULLUP_DIS_GPIO_19 = (1ul << 24), - M2M_PERIPH_PULLUP_DIS_GPIO_20 = (1ul << 25), - M2M_PERIPH_PULLUP_DIS_GPIO_21 = (1ul << 26), - M2M_PERIPH_PULLUP_DIS_GPIO_22 = (1ul << 27), - M2M_PERIPH_PULLUP_DIS_GPIO_23 = (1ul << 28), - M2M_PERIPH_PULLUP_DIS_GPIO_24 = (1ul << 29), + M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP = (1ul << 0), + M2M_PERIPH_PULLUP_DIS_RTC_CLK = (1ul << 1), + M2M_PERIPH_PULLUP_DIS_IRQN = (1ul << 2), + M2M_PERIPH_PULLUP_DIS_GPIO_3 = (1ul << 3), + M2M_PERIPH_PULLUP_DIS_GPIO_4 = (1ul << 4), + M2M_PERIPH_PULLUP_DIS_GPIO_5 = (1ul << 5), + M2M_PERIPH_PULLUP_DIS_SD_DAT3 = (1ul << 6), + M2M_PERIPH_PULLUP_DIS_SD_DAT2_SPI_RXD = (1ul << 7), + M2M_PERIPH_PULLUP_DIS_SD_DAT1_SPI_SSN = (1ul << 9), + M2M_PERIPH_PULLUP_DIS_SD_CMD_SPI_SCK = (1ul << 10), + M2M_PERIPH_PULLUP_DIS_SD_DAT0_SPI_TXD = (1ul << 11), + M2M_PERIPH_PULLUP_DIS_GPIO_6 = (1ul << 12), + M2M_PERIPH_PULLUP_DIS_SD_CLK = (1ul << 13), + M2M_PERIPH_PULLUP_DIS_I2C_SCL = (1ul << 14), + M2M_PERIPH_PULLUP_DIS_I2C_SDA = (1ul << 15), + M2M_PERIPH_PULLUP_DIS_GPIO_11 = (1ul << 16), + M2M_PERIPH_PULLUP_DIS_GPIO_12 = (1ul << 17), + M2M_PERIPH_PULLUP_DIS_GPIO_13 = (1ul << 18), + M2M_PERIPH_PULLUP_DIS_GPIO_14 = (1ul << 19), + M2M_PERIPH_PULLUP_DIS_GPIO_15 = (1ul << 20), + M2M_PERIPH_PULLUP_DIS_GPIO_16 = (1ul << 21), + M2M_PERIPH_PULLUP_DIS_GPIO_17 = (1ul << 22), + M2M_PERIPH_PULLUP_DIS_GPIO_18 = (1ul << 23), + M2M_PERIPH_PULLUP_DIS_GPIO_19 = (1ul << 24), + M2M_PERIPH_PULLUP_DIS_GPIO_20 = (1ul << 25), + M2M_PERIPH_PULLUP_DIS_GPIO_21 = (1ul << 26), + M2M_PERIPH_PULLUP_DIS_GPIO_22 = (1ul << 27), + M2M_PERIPH_PULLUP_DIS_GPIO_23 = (1ul << 28), + M2M_PERIPH_PULLUP_DIS_GPIO_24 = (1ul << 29), } tenuPullupMask; /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* @@ -199,197 +118,87 @@ FUNCTION PROTOTYPES #ifdef __cplusplus - extern "C" { +extern "C" { #endif /*! -@fn \ - NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param); +@fn \ + NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir); @brief - Initialize the NMC1500 peripheral driver module. + Configure a specific WINC15x0 pad as a GPIO and sets its direction (input or output). -@param [in] param - Peripheral module initialization structure. See members of tstrPerphInitParam. +@param[in] u8GpioNum + GPIO number. Allowed values are defined in @ref tenuGpioNum. + +@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 - 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). - -@param [in] u8GpioNum - GPIO number. Allowed values are defined in tenuGpioNum. - -@param [in] u8GpioDir - GPIO direction: Zero = input. Non-zero = output. - -@return - The function SHALL return 0 for success and a negative value otherwise. - -@sa - tenuGpioNum + tenuGpioNum */ NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir); /*! -@fn \ - NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal); +@fn \ + 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 - GPIO output value. Zero = low, non-zero = high. +@param[in] u8GpioVal + GPIO output value. Zero = low, non-zero = high. @return - The function SHALL return 0 for success and a negative value otherwise. + The function SHALL return 0 for success and a negative value otherwise. @sa - tenuGpioNum + tenuGpioNum */ NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal); /*! -@fn \ - NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal); +@fn \ + 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. + 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 + tenuGpioNum */ -NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal); +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); +@fn \ + NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable); @brief - Set an NMC1500 GPIO pullup resistor enable or disable. + Control the programmable pull-up resistor on the chip pads . -@param [in] u8GpioNum - GPIO number. Allowed values are defined in tenuGpioNum. +@param[in] pinmask + Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in @ref tenuPullupMask. -@param [in] u8PullupEn - Zero: pullup disabled. Non-zero: pullup enabled. +@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. - -@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); - - -/*! -@fn \ - NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable); - -@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 tenuPullupMask. - -@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 diff --git a/src/drivers/winc1500/include/driver/include/m2m_ssl.h b/src/drivers/winc1500/include/driver/include/m2m_ssl.h index 33cb2307f..084aedbcb 100644 --- a/src/drivers/winc1500/include/driver/include/m2m_ssl.h +++ b/src/drivers/winc1500/include/driver/include/m2m_ssl.h @@ -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,9 +81,9 @@ FUNCTION PROTOTYPES /*! @ingroup SSLFUNCTIONS @fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb); - @brief Initializes the SSL layer. - @param [in] pfAppSslCb - Application SSL callback function. +@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); @@ -105,58 +105,130 @@ 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 - Size of the certificates. +@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. */ 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); @@ -166,19 +238,15 @@ NMI_API void m2m_ssl_ecc_process_done(void); @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.\n - There is no need to call this function if the application will not change the default ciphersuites. -@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. - If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not + There is no need to call this function if the application will not change the default ciphersuites. +@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. + 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); diff --git a/src/drivers/winc1500/include/driver/include/m2m_types.h b/src/drivers/winc1500/include/driver/include/m2m_types.h index e5b8d263a..0b24c0629 100644 --- a/src/drivers/winc1500/include/driver/include/m2m_types.h +++ b/src/drivers/winc1500/include/driver/include/m2m_types.h @@ -4,7 +4,7 @@ * * \brief WINC Application 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 * @@ -49,6 +49,8 @@ INCLUDES #include "../../../firmware/wifi_v111/src/m2m/include/m2m_common.h" #endif #endif + +#ifndef _lint #endif @@ -90,26 +92,30 @@ MACROS ( ((uint32)M2M_MAKE_VERSION((fw_major), (fw_minor), (fw_patch))) << M2M_FW_VERSION_SHIFT) | \ ( ((uint32)M2M_MAKE_VERSION((drv_major), (drv_minor), (drv_patch))) << M2M_DRV_VERSION_SHIFT)) -#define REL_19_7_0_VER M2M_MAKE_VERSION_INFO(19,7,0,19,3,0) -#define REL_19_6_0_VER M2M_MAKE_VERSION_INFO(19,6,0,19,3,0) -#define REL_19_5_3_VER M2M_MAKE_VERSION_INFO(19,5,3,19,3,0) -#define REL_19_5_2_VER M2M_MAKE_VERSION_INFO(19,5,2,19,3,0) -#define REL_19_5_1_VER M2M_MAKE_VERSION_INFO(19,5,1,19,3,0) -#define REL_19_5_0_VER M2M_MAKE_VERSION_INFO(19,5,0,19,3,0) -#define REL_19_4_6_VER M2M_MAKE_VERSION_INFO(19,4,6,19,3,0) -#define REL_19_4_5_VER M2M_MAKE_VERSION_INFO(19,4,5,19,3,0) -#define REL_19_4_4_VER M2M_MAKE_VERSION_INFO(19,4,4,19,3,0) -#define REL_19_4_3_VER M2M_MAKE_VERSION_INFO(19,4,3,19,3,0) -#define REL_19_4_2_VER M2M_MAKE_VERSION_INFO(19,4,2,19,3,0) -#define REL_19_4_1_VER M2M_MAKE_VERSION_INFO(19,4,1,19,3,0) -#define REL_19_4_0_VER M2M_MAKE_VERSION_INFO(19,4,0,19,3,0) -#define REL_19_3_1_VER M2M_MAKE_VERSION_INFO(19,3,1,19,3,0) -#define REL_19_3_0_VER M2M_MAKE_VERSION_INFO(19,3,0,19,3,0) -#define REL_19_2_2_VER M2M_MAKE_VERSION_INFO(19,2,2,19,2,0) -#define REL_19_2_1_VER M2M_MAKE_VERSION_INFO(19,2,1,19,2,0) -#define REL_19_2_0_VER M2M_MAKE_VERSION_INFO(19,2,0,19,2,0) -#define REL_19_1_0_VER M2M_MAKE_VERSION_INFO(19,1,0,18,2,0) -#define REL_19_0_0_VER M2M_MAKE_VERSION_INFO(19,0,0,18,1,1) +#define REL_19_7_3_VER M2M_MAKE_VERSION_INFO(19,7,3,19,3,0) +#define REL_19_7_2_VER M2M_MAKE_VERSION_INFO(19,7,2,19,3,0) +#define REL_19_7_1_VER M2M_MAKE_VERSION_INFO(19,7,1,19,3,0) +#define REL_19_7_0_VER M2M_MAKE_VERSION_INFO(19,7,0,19,3,0) +#define REL_19_6_4_VER M2M_MAKE_VERSION_INFO(19,6,4,19,3,0) +#define REL_19_6_0_VER M2M_MAKE_VERSION_INFO(19,6,0,19,3,0) +#define REL_19_5_3_VER M2M_MAKE_VERSION_INFO(19,5,3,19,3,0) +#define REL_19_5_2_VER M2M_MAKE_VERSION_INFO(19,5,2,19,3,0) +#define REL_19_5_1_VER M2M_MAKE_VERSION_INFO(19,5,1,19,3,0) +#define REL_19_5_0_VER M2M_MAKE_VERSION_INFO(19,5,0,19,3,0) +#define REL_19_4_6_VER M2M_MAKE_VERSION_INFO(19,4,6,19,3,0) +#define REL_19_4_5_VER M2M_MAKE_VERSION_INFO(19,4,5,19,3,0) +#define REL_19_4_4_VER M2M_MAKE_VERSION_INFO(19,4,4,19,3,0) +#define REL_19_4_3_VER M2M_MAKE_VERSION_INFO(19,4,3,19,3,0) +#define REL_19_4_2_VER M2M_MAKE_VERSION_INFO(19,4,2,19,3,0) +#define REL_19_4_1_VER M2M_MAKE_VERSION_INFO(19,4,1,19,3,0) +#define REL_19_4_0_VER M2M_MAKE_VERSION_INFO(19,4,0,19,3,0) +#define REL_19_3_1_VER M2M_MAKE_VERSION_INFO(19,3,1,19,3,0) +#define REL_19_3_0_VER M2M_MAKE_VERSION_INFO(19,3,0,19,3,0) +#define REL_19_2_2_VER M2M_MAKE_VERSION_INFO(19,2,2,19,2,0) +#define REL_19_2_1_VER M2M_MAKE_VERSION_INFO(19,2,1,19,2,0) +#define REL_19_2_0_VER M2M_MAKE_VERSION_INFO(19,2,0,19,2,0) +#define REL_19_1_0_VER M2M_MAKE_VERSION_INFO(19,1,0,18,2,0) +#define REL_19_0_0_VER M2M_MAKE_VERSION_INFO(19,0,0,18,1,1) /*======*======*======*======* FIRMWARE VERSION NO INFO @@ -122,14 +128,14 @@ MACROS #ifndef BLDTESTVERSION1 // the real version number must appear first as the release script greps it out to create folder. -#define M2M_RELEASE_VERSION_MINOR_NO (6) +#define M2M_RELEASE_VERSION_MINOR_NO (7) #else -#define M2M_RELEASE_VERSION_MINOR_NO (8) +#define M2M_RELEASE_VERSION_MINOR_NO (8) #endif /*!< Firmware Minor release version number. */ -#define M2M_RELEASE_VERSION_PATCH_NO (1) +#define M2M_RELEASE_VERSION_PATCH_NO (3) /*!< Firmware patch release version number. */ @@ -174,7 +180,7 @@ MACROS #define M2M_MAC_ADDRES_LEN 6 -/*!< The size fo 802 MAC address. +/*!< The size of the 802 MAC address. */ #define M2M_ETHERNET_HDR_OFFSET 34 @@ -249,7 +255,7 @@ MACROS must be restricted to an AP with a certain BSSID. */ -#define M2M_AUTH_1X_USER_LEN_MAX 132 +#define M2M_AUTH_1X_USER_LEN_MAX 100 /*!< The maximum length (in ASCII characters) of domain name + username (including '@' or '\') for authentication with Enterprise methods. */ @@ -304,15 +310,15 @@ MACROS #define M2M_AP_CMD_BASE 70 /*!< The base value of all the Access Point mode host commands opcodes. */ -/**@}*/ //WlanDefines -#define M2M_P2P_CMD_BASE 90 +/**@cond P2P_DOC + */ +#define M2M_P2P_CMD_BASE 90 /*!< The base value of all the P2P mode host commands opcodes. */ -/**@addtogroup WlanDefines - * @{ - */ -#define M2M_SERVER_CMD_BASE 100 +/**@endcond*/ //P2P_DOC + +#define M2M_SERVER_CMD_BASE 100 /*!< The base value of all the power save mode host commands codes. */ #define M2M_GEN_CMD_BASE 105 @@ -511,60 +517,7 @@ MACROS */ /**@}*/ //OTADEFINE -/**@addtogroup OTATYPEDEF -*/ - /**@{*/ - -/*! -@enum \ - tenuOtaError - -@brief - OTA Error codes. -*/ -typedef enum { - OTA_SUCCESS = (0), - /*!< - OTA Success status - */ - OTA_ERR_WORKING_IMAGE_LOAD_FAIL = ((sint8) -1), - /*!< - Failure to load the firmware image - */ - OTA_ERR_INVALID_CONTROL_SEC = ((sint8) -2), - /*!< - Control structure is corrupted - */ - M2M_ERR_OTA_SWITCH_FAIL = ((sint8) -3), - /*!< - switching to the updated image failed as may be the image is invalid - */ - M2M_ERR_OTA_START_UPDATE_FAIL = ((sint8) -4), - /*!< - OTA update fail due to multiple reasons: - - Connection failure - - Image integrity fail - - */ - M2M_ERR_OTA_ROLLBACK_FAIL = ((sint8) -5), - /*!< - Roll-back failed due to Roll-back image is not valid - */ - M2M_ERR_OTA_INVALID_FLASH_SIZE = ((sint8) -6), - /*!< - The OTA Support at least 4MB flash size, this error code will appear if the current flash is less than 4M - */ - M2M_ERR_OTA_INVALID_ARG = ((sint8) -7), - /*!< - * Ota still in progress - */ - M2M_ERR_OTA_INPROGRESS = ((sint8) -8) -/*!< - Invalid argument in any OTA Function - */ -} tenuOtaError; - -/**@}*/ //OTATYPEDEF +#define tstrM2MSNTPConfig_PAD (4 - ((M2M_NTP_MAX_SERVER_NAME_LENGTH + 1 + 1) % 4)) /**@addtogroup WlanEnums * @{ @@ -827,8 +780,33 @@ static_assert((sizeof(tstrM2mWiFiRoaming)%4)==0, "Structure alignment error"); #endif /*! -@enum \ - tenuM2mReqGroup +@struct \ + tstrM2mWiFiXOSleepEnable + +@brief + Choose to keep the XO on or off over deep sleep. +*/ +typedef struct { + uint8 u8EnableXODuringSleep; + /*!< Enable/Disable XO during deep sleep + */ + uint8 __PAD16__[3]; + /*!< Padding bytes for forcing 4-byte alignment + */ +} tstrM2mWiFiXOSleepEnable; + +#ifndef _lint +#ifdef __GNUC__ +_Static_assert((sizeof(tstrM2mWiFiXOSleepEnable)%4)==0, "Structure alignment error"); +#else +static_assert((sizeof(tstrM2mWiFiXOSleepEnable)%4)==0, "Structure alignment error"); +#endif +#endif + + +/*! +@enum \ + tenuM2mReqGroup @brief */ @@ -884,123 +862,123 @@ typedef enum { */ M2M_WIFI_RESP_CONN_INFO, - /*!< Connect with default AP response. - */ - M2M_WIFI_REQ_SET_DEVICE_NAME, - /*!< - Set the WINC device name property. - */ - M2M_WIFI_REQ_START_PROVISION_MODE, - /*!< - Start the provisioning mode for the M2M Device. - */ - M2M_WIFI_RESP_PROVISION_INFO, - /*!< - Send the provisioning information to the host. - */ - M2M_WIFI_REQ_STOP_PROVISION_MODE, - /*!< - Stop the current running provision mode. - */ - M2M_WIFI_REQ_SET_SYS_TIME, - /*!< - Set time of day from host. - */ - M2M_WIFI_REQ_ENABLE_SNTP_CLIENT, - /*!< - Enable the simple network time protocol to get the - time from the Internet. this is required for security purposes. - */ - M2M_WIFI_REQ_DISABLE_SNTP_CLIENT, - /*!< - Disable the simple network time protocol for applications that - do not need it. - */ - M2M_WIFI_RESP_MEMORY_RECOVER, - /*!< - * Reserved for debugging - * */ - M2M_WIFI_REQ_CUST_INFO_ELEMENT, - /*!< Add Custom Element to Beacon Management Frame. - */ - M2M_WIFI_REQ_SCAN, - /*!< Request scan command. - */ - M2M_WIFI_RESP_SCAN_DONE, - /*!< Scan complete notification response. - */ - M2M_WIFI_REQ_SCAN_RESULT, - /*!< Request Scan results command. - */ - M2M_WIFI_RESP_SCAN_RESULT, - /*!< Request Scan results response. - */ - M2M_WIFI_REQ_SET_SCAN_OPTION, - /*!< Set Scan options "slot time, slot number .. etc" . - */ - M2M_WIFI_REQ_SET_SCAN_REGION, - /*!< Set scan region. - */ - M2M_WIFI_REQ_SET_POWER_PROFILE, - /*!< The API shall set power mode to one of 3 modes - */ - M2M_WIFI_REQ_SET_TX_POWER, - /*!< API to set TX power. - */ - M2M_WIFI_REQ_SET_BATTERY_VOLTAGE, - /*!< API to set Battery Voltage. - */ - M2M_WIFI_REQ_SET_ENABLE_LOGS, - /*!< API to set Battery Voltage. - */ - M2M_WIFI_REQ_GET_SYS_TIME, - /*!< - REQ GET time of day from WINC. - */ - M2M_WIFI_RESP_GET_SYS_TIME, - /*!< - RESP time of day from host. - */ - M2M_WIFI_REQ_SEND_ETHERNET_PACKET, - /*!< Send Ethernet packet in bypass mode. - */ - M2M_WIFI_RESP_ETHERNET_RX_PACKET, - /*!< Receive Ethernet packet in bypass mode. - */ - M2M_WIFI_REQ_SET_MAC_MCAST, - /*!< Set the WINC multicast filters. - */ - M2M_WIFI_REQ_GET_PRNG, - /*!< Request PRNG. - */ - M2M_WIFI_RESP_GET_PRNG, - /*!< Response for PRNG. - */ - M2M_WIFI_REQ_SCAN_SSID_LIST, - /*!< Request scan with list of hidden SSID plus the broadcast scan. - */ - M2M_WIFI_REQ_SET_GAINS, - /*!< Request set the PPA gain - */ - M2M_WIFI_REQ_PASSIVE_SCAN, - /*!< Request a passivr scan command. - */ - M2M_WIFI_REQ_CONG_AUTO_RATE, - /*!< Configure auto TX rate selection algorithm. - */ - M2M_WIFI_REQ_CONFIG_SNTP, - /*!< Configure NTP servers. - */ - M2M_WIFI_REQ_SET_GAIN_TABLE_IDX, - /*!< API to set Gain table index. - */ - M2M_WIFI_REQRSP_DELETE_APID, - /*!< Request/response to delete AP security credentials from WINC flash. - */ - /* This enum is now 'full' in the sense that (M2M_WIFI_REQRSP_DELETE_APID+1) == M2M_STA_CMD_BASE. - * Any new config values should be placed in tenuM2mGenCmd. */ - M2M_WIFI_MAX_CONFIG_ALL -}tenuM2mConfigCmd; + /*!< Connect with default AP response. + */ + M2M_WIFI_REQ_SET_DEVICE_NAME, + /*!< + Set the WINC device name property. + */ + M2M_WIFI_REQ_START_PROVISION_MODE, + /*!< + Start the provisioning mode for the M2M Device. + */ + M2M_WIFI_RESP_PROVISION_INFO, + /*!< + Send the provisioning information to the host. + */ + M2M_WIFI_REQ_STOP_PROVISION_MODE, + /*!< + Stop the current running provision mode. + */ + M2M_WIFI_REQ_SET_SYS_TIME, + /*!< + Set time of day from host. + */ + M2M_WIFI_REQ_ENABLE_SNTP_CLIENT, + /*!< + Enable the simple network time protocol to get the + time from the Internet. this is required for security purposes. + */ + M2M_WIFI_REQ_DISABLE_SNTP_CLIENT, + /*!< + Disable the simple network time protocol for applications that + do not need it. + */ + M2M_WIFI_RESP_MEMORY_RECOVER, + /*!< + * Reserved for debugging + * */ + M2M_WIFI_REQ_CUST_INFO_ELEMENT, + /*!< Add Custom Element to Beacon Management Frame. + */ + M2M_WIFI_REQ_SCAN, + /*!< Request scan command. + */ + M2M_WIFI_RESP_SCAN_DONE, + /*!< Scan complete notification response. + */ + M2M_WIFI_REQ_SCAN_RESULT, + /*!< Request Scan results command. + */ + M2M_WIFI_RESP_SCAN_RESULT, + /*!< Request Scan results response. + */ + M2M_WIFI_REQ_SET_SCAN_OPTION, + /*!< Set Scan options "slot time, slot number .. etc" . + */ + M2M_WIFI_REQ_SET_SCAN_REGION, + /*!< Set scan region. + */ + M2M_WIFI_REQ_SET_POWER_PROFILE, + /*!< The API shall set power mode to one of 3 modes + */ + M2M_WIFI_REQ_SET_TX_POWER, + /*!< API to set TX power. + */ + M2M_WIFI_REQ_SET_BATTERY_VOLTAGE, + /*!< API to set Battery Voltage. + */ + M2M_WIFI_REQ_SET_ENABLE_LOGS, + /*!< API to set Battery Voltage. + */ + M2M_WIFI_REQ_GET_SYS_TIME, + /*!< + REQ GET time of day from WINC. + */ + M2M_WIFI_RESP_GET_SYS_TIME, + /*!< + RESP time of day from host. + */ + M2M_WIFI_REQ_SEND_ETHERNET_PACKET, + /*!< Send Ethernet packet in bypass mode. + */ + M2M_WIFI_RESP_ETHERNET_RX_PACKET, + /*!< Receive Ethernet packet in bypass mode. + */ + M2M_WIFI_REQ_SET_MAC_MCAST, + /*!< Set the WINC multicast filters. + */ + M2M_WIFI_REQ_GET_PRNG, + /*!< Request PRNG. + */ + M2M_WIFI_RESP_GET_PRNG, + /*!< Response for PRNG. + */ + M2M_WIFI_REQ_SCAN_SSID_LIST, + /*!< Request scan with list of hidden SSID plus the broadcast scan. + */ + M2M_WIFI_REQ_SET_GAINS, + /*!< Request to set the PPA gain + */ + M2M_WIFI_REQ_PASSIVE_SCAN, + /*!< Request a passive scan. + */ + M2M_WIFI_REQ_CONG_AUTO_RATE, + /*!< Configure auto TX rate selection algorithm. + */ + M2M_WIFI_REQ_CONFIG_SNTP, + /*!< Configure NTP servers. + */ + M2M_WIFI_REQ_SET_GAIN_TABLE_IDX, + /*!< API to set Gain table index. + */ + M2M_WIFI_REQRSP_DELETE_APID, + /*!< Request/response to delete AP security credentials from WINC flash. + */ + /* This enum is now 'full' in the sense that (M2M_WIFI_REQRSP_DELETE_APID+1) == M2M_STA_CMD_BASE. + * Any new config values should be placed in tenuM2mGenCmd. */ + M2M_WIFI_MAX_CONFIG_ALL +} tenuM2mConfigCmd; /*! @enum \ @@ -1104,40 +1082,9 @@ typedef enum { M2M_WIFI_MAX_AP_ALL }tenuM2mApCmd; -/**@}*/ //WlanEnums - /*! -@enum \ - tenuM2mP2pCmd - -@brief - This enum contains WINC commands while in P2P mode. -*/ -typedef enum { - M2M_WIFI_REQ_P2P_INT_CONNECT = M2M_P2P_CMD_BASE, - /*!< This command is for internal use by the WINC and - should not be used by the host driver. - */ - M2M_WIFI_REQ_ENABLE_P2P, - /*!< Enable P2P mode command. - */ - M2M_WIFI_REQ_DISABLE_P2P, - /*!< Disable P2P mode command. - */ - M2M_WIFI_REQ_P2P_REPOST, - /*!< This command is for internal use by the WINC and - should not be used by the host driver. - */ - M2M_WIFI_MAX_P2P_ALL -}tenuM2mP2pCmd; - -/**@addtogroup WlanEnums - * @{ - */ - -/*! -@enum \ - tenuM2mServerCmd +@enum \ + tenuM2mServerCmd @brief This enum contains WINC commands while in PS mode. @@ -1158,12 +1105,20 @@ typedef enum { This enum contains additional WINC commands (overflow of previous enums). */ typedef enum { - M2M_WIFI_REQ_ROAMING = M2M_GEN_CMD_BASE, - /*!< Request to enable/disable wifi roaming. - (Processing matches @ref tenuM2mConfigCmd.) - */ - M2M_WIFI_MAX_GEN_ALL -}tenuM2mGenCmd; + M2M_WIFI_REQ_ROAMING = M2M_GEN_CMD_BASE, + /*!< Request to enable/disable wifi roaming. + (Processing matches @ref tenuM2mConfigCmd.) + */ + M2M_WIFI_REQ_XO_SLEEP_ENABLE, + /*!< Request to enable/disable the crystal oscillator during deep sleep. + (Processing matches @ref tenuM2mConfigCmd.) + */ + M2M_WIFI_REQ_SET_STOP_SCAN_OPTION, + /*!< Set Scan option to stop on first result. + (Processing matches @ref tenuM2mConfigCmd.) + */ + M2M_WIFI_MAX_GEN_ALL +} tenuM2mGenCmd; /*! @enum \ @@ -1587,32 +1542,42 @@ static_assert((sizeof(tstrM2mWifiPsk)%4)==0, "Structure alignment error"); Wi-Fi Authentication 802.1x header for parameters. The parameters (Domain, UserName, PrivateKey/Password) are appended to this structure. */ -typedef struct{ - uint8 u8Flags; - /*!< 802.1x-specific flags: - @ref M2M_802_1X_MSCHAP2_FLAG - @ref M2M_802_1X_TLS_FLAG - @ref M2M_802_1X_UNENCRYPTED_USERNAME_FLAG - @ref M2M_802_1X_PREPEND_DOMAIN_FLAG - */ - uint8 u8DomainLength; - /*!< Length of Domain. (Offset of Domain understood to be 0.) */ - uint16 u16UserNameLength; - /*!< Length of UserName. (Offset of UserName understood to be u8DomainLength.) */ - uint16 u16PrivateKeyOffset; - /*!< Offset within au81xAuthDetails of PrivateKey/Password. */ - uint16 u16PrivateKeyLength; - /*!< Length of PrivateKey/Password. In the case of PrivateKey, this is the length of the modulus. */ - uint16 u16CertificateOffset; - /*!< Offset within au81xAuthDetails of Certificate. */ - uint16 u16CertificateLength; - /*!< Length of Certificate. */ - uint8 au81xAuthDetails[]; - /*!< Placeholder for concatenation of Domain, UserName, PrivateKey/Password, Certificate. - Padding (0s) is placed between UserName and PrivateKey/Password so that - PrivateKey/Password begins on a 4-byte boundary. - Certificate (for 1x Tls only) is sent over HIF separately from the other parameters. */ -}tstrM2mWifi1xHdr; +typedef struct { + uint8 u8Flags; + /*!< 802.1x-specific flags: + @ref M2M_802_1X_MSCHAP2_FLAG + @ref M2M_802_1X_TLS_FLAG + @ref M2M_802_1X_UNENCRYPTED_USERNAME_FLAG + @ref M2M_802_1X_PREPEND_DOMAIN_FLAG + */ + uint8 u8DomainLength; + /*!< Length of Domain. (Offset of Domain, within au81xAuthDetails, understood to be 0.) */ + uint8 u8UserNameLength; + /*!< Length of UserName. (Offset of UserName, within au81xAuthDetails, understood to be u8DomainLength.) */ + uint8 u8HdrLength; + /*!< Length of header (offset of au81xAuthDetails within tstrM2mWifi1xHdr). + Legacy implementations may have 0 here, in which case header is 12 bytes. + The unusual placing of this field is in order to hit a zero in legacy implementations. */ + uint16 u16PrivateKeyOffset; + /*!< Offset within au81xAuthDetails of PrivateKey/Password. */ + uint16 u16PrivateKeyLength; + /*!< Length of PrivateKey/Password. In the case of PrivateKey, this is the length of the modulus. */ + uint16 u16CertificateOffset; + /*!< Offset within au81xAuthDetails of Certificate. */ + uint16 u16CertificateLength; + /*!< Length of Certificate. */ + uint8 au8TlsSpecificRootNameSha1[20]; + /*!< SHA1 digest of subject name to identify specific root certificate for phase 1 server verification. */ + uint32 u32Rsv1; + /*!< Reserved, set to 0. */ + uint32 u32TlsHsFlags; + /*!< TLS handshake flags for phase 1. */ + uint32 u32Rsv2; + /*!< Reserved, set to 0. */ + uint8 au81xAuthDetails[]; + /*!< Placeholder for concatenation of Domain, UserName, PrivateKey/Password, Certificate. + Certificate (for 1x Tls only) is sent over HIF separately from the other parameters. */ +} tstrM2mWifi1xHdr; #ifndef _lint #ifdef __GNUC__ _Static_assert((sizeof(tstrM2mWifi1xHdr)%4)==0, "Structure alignment error"); @@ -1836,9 +1801,11 @@ typedef struct { The device listens for probe responses and beacons during this time. Valid settings are in the range 10<=SlotTime<=250. Default setting is @ref M2M_SCAN_DEFAULT_SLOT_TIME. - */ - uint8 u8ProbesPerSlot; - /*!< Number of probe requests to be sent each scan slot. Refers to active scan only. + */ + uint8 u8ProbesPerSlot; + /*!< Number of probe requests to be sent for each scan slot (when not specifying network to scan). + Number of probe requests to be sent for each ssid to scan in each scan slot (when specifying network to scan). + Refers to active scan only. Valid settings are in the range 0u8Status == M2M_SUCCESS) - { - tstrNetworkId strNetworkId = {NULL, pstrProvInfo->au8SSID, (uint8)strlen((char*)(pstrProvInfo->au8SSID)), M2M_WIFI_CH_ALL}; - tstrAuthPsk strAuthPsk = {NULL, pstrProvInfo->au8Password, (uint8)strlen((char*)(pstrProvInfo->au8Password))}; - m2m_wifi_connect_psk(WIFI_CRED_SAVE_ENCRYPTED, &strNetworkId, &strAuthPsk); - - printf("PROV SSID : %s\n",pstrProvInfo->au8SSID); - printf("PROV PSK : %s\n",pstrProvInfo->au8Password); - } - else - { - printf("(ERR) Provisioning Failed\n"); - } - } - break; - - default: - break; - } - } - - int main() - { - tstrWifiInitParam param; - - param.pfAppWifiCb = wifi_event_cb; - if(!m2m_wifi_init(¶m)) - { - tstrM2MAPConfig apConfig; - uint8 bEnableRedirect = 1; - - strcpy(apConfig.au8SSID, "WINC_SSID"); - apConfig.u8ListenChannel = 1; - apConfig.u8SecType = M2M_WIFI_SEC_OPEN; - apConfig.u8SsidHide = 0; - - // IP Address - apConfig.au8DHCPServerIP[0] = 192; - apConfig.au8DHCPServerIP[1] = 168; - apConfig.au8DHCPServerIP[2] = 1; - apConfig.au8DHCPServerIP[3] = 1; - - m2m_wifi_start_provision_mode(&apConfig, "atmelwincconf.com", bEnableRedirect); - - while(1) - { - m2m_wifi_handle_events(NULL); - } - } - } -@endcode -*/ -NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect); - -/*! -@fn \ - NMI_API sint8 m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect); - -@brief - Asynchronous API for control of Wi-Fi provisioning functionality with extended options. - -@details - Asynchronous Wi-Fi provisioning function, which starts the WINC HTTP PROVISIONING mode. - The function triggers the WINC to activate the Wi-Fi AP (HOTSPOT) mode with the passed - configuration parameters and then starts the HTTP Provision WEB Server. - - Provisioning status is returned in an event @ref M2M_WIFI_RESP_PROVISION_INFO. - -@param [in] pstrAPModeConfig - AP configuration parameters as defined in @ref tstrM2MAPModeConfig configuration structure. - A NULL value passed in, will result in a negative error @ref M2M_ERR_FAIL. - -@param [in] pcHttpServerDomainName +@param[in] pcHttpServerDomainName Domain name of the HTTP Provision WEB server which others will use to load the provisioning Home page. The domain name can have one of the following 3 forms: - 1. "wincprov.com" - 2. "http://wincprov.com" - 3. "https://wincprov.com" - The forms 1 and 2 are equivalent, they both will start a plain http server, while form 3 + Forms 1 and 2 are equivalent, they will both start a plain http server, while form 3 will start a secure HTTP provisioning Session (HTTP over SSL connection). @param [in] bEnableHttpRedirect @@ -1377,22 +1429,21 @@ NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char - The event @ref M2M_WIFI_RESP_CONN_INFO must be handled in the callback to receive the requested connection info. @warning - DO Not use ".local" in the pcHttpServerDomainName. - + DO NOT use ".local" in the pcHttpServerDomainName. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + @see tpfAppWifiCb m2m_wifi_init M2M_WIFI_RESP_PROVISION_INFO m2m_wifi_stop_provision_mode - tstrM2MAPModeConfig + tstrM2MAPConfig -@return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. - -\section WIFIExample1b Example - The example demonstrates a code snippet for how provisioning is triggered and the response event - received accordingly. +\section WIFIExample1 Example + The example demonstrates a code snippet for how provisioning is triggered and the response event + received accordingly. @code #include "m2m_wifi.h" @@ -1404,7 +1455,7 @@ NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char { case M2M_WIFI_RESP_PROVISION_INFO: { - tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo*)pvMsg; + tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo*)pvMsg; if(pstrProvInfo->u8Status == M2M_SUCCESS) { tstrNetworkId strNetworkId = {NULL, pstrProvInfo->au8SSID, (uint8)strlen((char*)(pstrProvInfo->au8SSID)), M2M_WIFI_CH_ALL}; @@ -1428,9 +1479,134 @@ NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char int main() { - tstrWifiInitParam param; - - param.pfAppWifiCb = wifi_event_cb; + tstrWifiInitParam param; + + param.pfAppWifiCb = wifi_event_cb; + if(!m2m_wifi_init(¶m)) + { + tstrM2MAPConfig apConfig; + uint8 bEnableRedirect = 1; + + strcpy(apConfig.au8SSID, "WINC_SSID"); + apConfig.u8ListenChannel = 1; + apConfig.u8SecType = M2M_WIFI_SEC_OPEN; + apConfig.u8SsidHide = 0; + + // IP Address + apConfig.au8DHCPServerIP[0] = 192; + apConfig.au8DHCPServerIP[1] = 168; + apConfig.au8DHCPServerIP[2] = 1; + apConfig.au8DHCPServerIP[3] = 1; + + m2m_wifi_start_provision_mode(&apConfig, "atmelwincconf.com", bEnableRedirect); + + while(1) + { + m2m_wifi_handle_events(NULL); + } + } + } +@endcode +*/ +NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect); + +/*! +@ingroup WLANPROVISION +@fn \ + NMI_API sint8 m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect); + +@brief + Asynchronous API for control of Wi-Fi provisioning functionality with extended options. + +@details + Asynchronous Wi-Fi provisioning function, which starts the WINC HTTP PROVISIONING mode. + The function triggers the WINC to activate the Wi-Fi AP (HOTSPOT) mode with the passed + configuration parameters and then starts the HTTP Provision WEB Server. + + Provisioning status is returned in an event @ref M2M_WIFI_RESP_PROVISION_INFO. + +@param[in] pstrAPModeConfig + AP configuration parameters as defined in @ref tstrM2MAPModeConfig configuration structure. + A NULL value passed in, will result in a negative error @ref M2M_ERR_FAIL. + +@param[in] pcHttpServerDomainName + Domain name of the HTTP Provision WEB server which others will use to load the provisioning Home page. + The domain name can have one of the following 3 forms: + - 1. "wincprov.com" + - 2. "http://wincprov.com" + - 3. "https://wincprov.com" + + The forms 1 and 2 are equivalent, they both will start a plain http server, while form 3 + will start a secure HTTP provisioning Session (HTTP over SSL connection). + +@param[in] bEnableHttpRedirect + A flag to enable/disable the HTTP redirect feature. If Secure provisioning is enabled (i.e. the server + domain name uses "https" prefix) this flag is ignored (no meaning for redirect in HTTPS). + Possible values are: + - ZERO value, which means DO NOT use HTTP Redirect. In this case, the associated device could open the provisioning + page ONLY when the HTTP Provision URL of the WINC HTTP Server is correctly written on the browser. + - Non-Zero value, means use HTTP Redirect. In this case, all http traffic (http://URL) from the associated + device (Phone, PC, etc) will be redirected to the WINC HTTP Provisioning Home page. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at startup. Registering the callback + is done through passing it to the initialization @ref m2m_wifi_init function. + - The event @ref M2M_WIFI_RESP_CONN_INFO must be handled in the callback to receive the requested connection info. + +@warning + DO Not use ".local" in the pcHttpServerDomainName. + +@see + tpfAppWifiCb + m2m_wifi_init + M2M_WIFI_RESP_PROVISION_INFO + m2m_wifi_stop_provision_mode + tstrM2MAPModeConfig + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +\section WIFIExample1b Example + The example demonstrates a code snippet for how provisioning is triggered and the response event + received accordingly. + +@code + #include "m2m_wifi.h" + #include "m2m_types.h" + + void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg) + { + switch(u8WiFiEvent) + { + case M2M_WIFI_RESP_PROVISION_INFO: + { + tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo*)pvMsg; + if(pstrProvInfo->u8Status == M2M_SUCCESS) + { + tstrNetworkId strNetworkId = {NULL, pstrProvInfo->au8SSID, (uint8)strlen((char*)(pstrProvInfo->au8SSID)), M2M_WIFI_CH_ALL}; + tstrAuthPsk strAuthPsk = {NULL, pstrProvInfo->au8Password, (uint8)strlen((char*)(pstrProvInfo->au8Password))}; + m2m_wifi_connect_psk(WIFI_CRED_SAVE_ENCRYPTED, &strNetworkId, &strAuthPsk); + + printf("PROV SSID : %s\n",pstrProvInfo->au8SSID); + printf("PROV PSK : %s\n",pstrProvInfo->au8Password); + } + else + { + printf("(ERR) Provisioning Failed\n"); + } + } + break; + + default: + break; + } + } + + int main() + { + tstrWifiInitParam param; + + param.pfAppWifiCb = wifi_event_cb; if(!m2m_wifi_init(¶m)) { tstrM2MAPModeConfig apModeConfig; @@ -1472,8 +1648,9 @@ NMI_API sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char NMI_API sint8 m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect); /*! -@fn \ - sint8 m2m_wifi_stop_provision_mode(void); +@ingroup WLANPROVISION +@fn \ + sint8 m2m_wifi_stop_provision_mode(void); @brief Synchronous API for terminating provisioning mode on the WINC IC. @@ -1486,7 +1663,7 @@ NMI_API sint8 m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeC An active provisioning session must be active before it is terminated through this function. @return - The function returns ZERO for success and a negative value otherwise. + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. @see m2m_wifi_start_provision_mode @@ -1494,8 +1671,9 @@ NMI_API sint8 m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeC NMI_API sint8 m2m_wifi_stop_provision_mode(void); /*! -@fn \ - sint8 m2m_wifi_get_connection_info(void); +@ingroup WLANCONNECT +@fn \ + sint8 m2m_wifi_get_connection_info(void); @brief Asynchronous API for retrieving the WINC IC's connection status. @@ -1526,9 +1704,8 @@ NMI_API sint8 m2m_wifi_stop_provision_mode(void); - In case the WINC is operating in AP mode, the SSID field will be returned as a NULL string. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. - + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + @see M2M_WIFI_RESP_CONN_INFO, tstrM2MConnInfo @@ -1587,8 +1764,9 @@ NMI_API sint8 m2m_wifi_stop_provision_mode(void); NMI_API sint8 m2m_wifi_get_connection_info(void); /*! -@fn \ - NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); +@ingroup WLANCONF +@fn \ + NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); @brief Synchronous API for assigning a MAC address to the WINC IC. @@ -1600,15 +1778,15 @@ NMI_API sint8 m2m_wifi_get_connection_info(void); @param [in] au8MacAddress MAC Address to be provisioned to the WINC. -@return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. */ NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); /*! -@fn \ - NMI_API sint8 m2m_wifi_wps(uint8 u8TriggerType,const char * pcPinNumber); +@ingroup WLANWPS +@fn \ + NMI_API sint8 m2m_wifi_wps(uint8 u8TriggerType,const char * pcPinNumber); @brief Asynchronous API to engage the WINC IC's Wi-Fi Protected Setup (enrollee) function. @@ -1619,12 +1797,12 @@ NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); @param [in] u8TriggerType WPS Trigger method. This may be: - - [WPS_PIN_TRIGGER](@ref WPS_PIN_TRIGGER) Push button method - - [WPS_PBC_TRIGGER](@ref WPS_PBC_TRIGGER) Pin method - -@param [in] pcPinNumber - PIN number for WPS PIN method. It is not used if the trigger type is WPS_PBC_TRIGGER. It must follow the rules - stated by the WPS standard. + - @ref WPS_PIN_TRIGGER Push button method + - @ref WPS_PBC_TRIGGER Pin method + +@param[in] pcPinNumber + PIN number for WPS PIN method. It is not used if the trigger type is WPS_PBC_TRIGGER. It must follow the rules + stated by the WPS standard. @pre - A Wi-Fi notification callback of type (@ref tpfAppWifiCb MUST be implemented and registered at @@ -1640,8 +1818,7 @@ NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); This function is not allowed in AP mode. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see tpfAppWifiCb @@ -1715,8 +1892,9 @@ NMI_API sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6]); NMI_API sint8 m2m_wifi_wps(uint8 u8TriggerType,const char *pcPinNumber); /*! -@fn \ - NMI_API sint8 m2m_wifi_wps_disable(void); +@ingroup WLANWPS +@fn \ + NMI_API sint8 m2m_wifi_wps_disable(void); @brief Stops the ongoing WPS session. @@ -1725,22 +1903,19 @@ NMI_API sint8 m2m_wifi_wps(uint8 u8TriggerType,const char *pcPinNumber); WINC should be already in WPS mode using @ref m2m_wifi_wps. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_wps */ NMI_API sint8 m2m_wifi_wps_disable(void); -/**@}*/ - + /**@cond P2P_DOC - * @addtogroup WLANAPI */ -/**@{*/ /*! -@fn \ - NMI_API sint8 m2m_wifi_p2p(uint8 u8Channel); +@ingroup WLANP2P +@fn \ + NMI_API sint8 m2m_wifi_p2p(uint8 u8Channel); @warning P2P has been deprecated from version 19.5.3! @@ -1748,22 +1923,20 @@ NMI_API sint8 m2m_wifi_wps_disable(void); NMI_API sint8 m2m_wifi_p2p(uint8 u8Channel); /*! -@fn \ - NMI_API sint8 m2m_wifi_p2p_disconnect(void); +@ingroup WLANP2P +@fn \ + NMI_API sint8 m2m_wifi_p2p_disconnect(void); @warning P2P has been deprecated from version 19.5.3! */ NMI_API sint8 m2m_wifi_p2p_disconnect(void); -/**@}*/ -/**@endcond*/ +/**@endcond*/ //P2P_DOC -/**@addtogroup WLANAPI - */ -/**@{*/ /*! -@fn \ - NMI_API sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig); +@ingroup WLANAP +@fn \ + NMI_API sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig); @brief Asynchronous API to enable access point (AKA "hot-spot") mode on the WINC IC. @@ -1771,14 +1944,13 @@ NMI_API sint8 m2m_wifi_p2p_disconnect(void); @details The WINC IC supports the ability to operate as an access point with the following limitations: - Only 1 station may be associated at any given time. - - open system and WEP are the only security suites supported. + - Open system and WEP are the only security suites supported. -@param [in] pstrM2MAPConfig - A structure holding the AP configurations. +@param[in] pstrM2MAPConfig + A structure holding the AP configurations. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @pre - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback @@ -1856,7 +2028,8 @@ NMI_API sint8 m2m_wifi_p2p_disconnect(void); NMI_API sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig); /*! -@fn \ +@ingroup WLANAP +@fn \ NMI_API sint8 m2m_wifi_enable_ap_ext(CONST tstrM2MAPModeConfig* pstrM2MAPModeConfig); @brief @@ -1865,14 +2038,13 @@ NMI_API sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig); @details The WINC IC supports the ability to operate as an access point with the following limitations: - Only 1 station may be associated at any given time. - - open system and WEP are the only security suites supported. + - Open system and WEP are the only security suites supported. @param [in] pstrM2MAPModeConfig A structure holding the AP configurations. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @pre - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback @@ -1962,8 +2134,9 @@ NMI_API sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig); NMI_API sint8 m2m_wifi_enable_ap_ext(CONST tstrM2MAPModeConfig* pstrM2MAPModeConfig); /*! -@fn \ - NMI_API sint8 m2m_wifi_disable_ap(void); +@ingroup WLANAP +@fn \ + NMI_API sint8 m2m_wifi_disable_ap(void); @brief Synchronous API to disable access point mode on the WINC IC. @@ -1973,8 +2146,7 @@ NMI_API sint8 m2m_wifi_enable_ap_ext(CONST tstrM2MAPModeConfig* pstrM2MAPModeCon function. Otherwise the call to this function will not be useful. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_ap @@ -1982,8 +2154,9 @@ NMI_API sint8 m2m_wifi_enable_ap_ext(CONST tstrM2MAPModeConfig* pstrM2MAPModeCon NMI_API sint8 m2m_wifi_disable_ap(void); /*! -@fn \ - NMI_API sint8 m2m_wifi_set_static_ip(tstrM2MIPConfig * pstrStaticIPConf); +@ingroup WLANCONNECT +@fn \ + NMI_API sint8 m2m_wifi_set_static_ip(tstrM2MIPConfig * pstrStaticIPConf); @brief Synchronous API to manually assign a (static) IP address to the WINC IC. @@ -2011,18 +2184,18 @@ NMI_API sint8 m2m_wifi_disable_ap(void); DNS address). @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. - + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + @see tstrM2MIPConfig */ NMI_API sint8 m2m_wifi_set_static_ip(tstrM2MIPConfig * pstrStaticIPConf); /*! -@fn \ - NMI_API sint8 m2m_wifi_request_dhcp_client(void); - +@ingroup WLANCONNECT +@fn \ + NMI_API sint8 m2m_wifi_request_dhcp_client(void); + @brief Legacy (deprecated) Asynchronous API for starting a DHCP client on the WINC IC. @@ -2039,8 +2212,9 @@ NMI_API sint8 m2m_wifi_set_static_ip(tstrM2MIPConfig * pstrStaticIPConf); NMI_API sint8 m2m_wifi_request_dhcp_client(void); /*! -@fn \ - NMI_API sint8 m2m_wifi_request_dhcp_server(uint8* addr); +@ingroup WLANCONNECT +@fn \ + NMI_API sint8 m2m_wifi_request_dhcp_server(uint8* addr); @brief Dhcp requested by the firmware automatically in STA/AP mode). @@ -2055,9 +2229,10 @@ NMI_API sint8 m2m_wifi_request_dhcp_client(void); NMI_API sint8 m2m_wifi_request_dhcp_server(uint8* addr); /*! -@fn \ - NMI_API sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn ); - +@ingroup WLANCONNECT +@fn \ + NMI_API sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn); + @brief Enable/Disable the DHCP client after connection. @@ -2082,21 +2257,21 @@ NMI_API sint8 m2m_wifi_request_dhcp_server(uint8* addr); NMI_API sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn ); /*! -@fn \ +@ingroup WLANSCAN +@fn \ sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption); @brief Synchronous API for configuring the behaviour of the WINC IC's network scanning functions. @details - This function sets the time configuration parameters for the scan operation. + This function sets the configuration parameters for the scan operation. @param [in] ptstrM2MScanOption; Pointer to the structure holding the Scan Parameters. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see tenuM2mScanCh @@ -2106,7 +2281,37 @@ NMI_API sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn ); NMI_API sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption); /*! -@fn \ +@ingroup WLANSCAN +@fn \ + sint8 m2m_wifi_set_stop_scan_on_first(uint8 u8StopScanOption); + +@brief + Synchronous API for enabling/disabling the stop scan on first result of the WINC IC's network scanning functions. + +@details + Allows for enabling/disabling of stop scan on first result. When enabled, the WINC will stop the scan as soon as + it detects a network and return the results to the host. Setting is persistent and will need to be explicitly + reverted back by the application if it no longer wishes for it to be enabled. + +@param[in] u8StopScanOption; + Setting for enabling or disabling Stopping Scan on first result. + 1 = Enabled, 0 = Disabled (Default) + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tenuM2mScanCh + tstrM2MScanOption + tstrM2MStopScanOption + m2m_wifi_request_scan + m2m_wifi_set_scan_options +*/ +NMI_API sint8 m2m_wifi_set_stop_scan_on_first(uint8 u8StopScanOption); + +/*! +@ingroup WLANSCAN +@fn \ sint8 m2m_wifi_set_scan_region(uint16 ScanRegion); @brief @@ -2125,8 +2330,7 @@ NMI_API sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption); NORTH_AMERICA @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see tenuM2mScanCh @@ -2135,8 +2339,9 @@ NMI_API sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption); NMI_API sint8 m2m_wifi_set_scan_region(uint16 ScanRegion); /*! -@fn \ - NMI_API sint8 m2m_wifi_request_scan(uint8 ch); +@ingroup WLANSCAN +@fn \ + NMI_API sint8 m2m_wifi_request_scan(uint8 ch); @brief Asynchronous API to request the WINC IC to scan for networks. @@ -2154,8 +2359,7 @@ NMI_API sint8 m2m_wifi_set_scan_region(uint16 ScanRegion); value of @ref M2M_WIFI_CH_ALL to scan all channels. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @pre - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at @@ -2265,8 +2469,9 @@ NMI_API sint8 m2m_wifi_set_scan_region(uint16 ScanRegion); NMI_API sint8 m2m_wifi_request_scan(uint8 ch); /*! -@fn \ - NMI_API sint8 m2m_wifi_request_scan_passive(uint8 ch, uint16 scan_time); +@ingroup WLANSCAN +@fn \ + NMI_API sint8 m2m_wifi_request_scan_passive(uint8 ch, uint16 scan_time); @brief Similar to @ref m2m_wifi_request_scan but performs passive scanning instead of active scanning. @@ -2305,6 +2510,7 @@ NMI_API sint8 m2m_wifi_request_scan(uint8 ch); NMI_API sint8 m2m_wifi_request_scan_passive(uint8 ch, uint16 scan_time); /*! +@ingroup WLANSCAN @fn \ NMI_API sint8 m2m_wifi_request_scan_ssid_list(uint8 ch,uint8 * u8SsidList); @@ -2464,6 +2670,7 @@ NMI_API sint8 m2m_wifi_request_scan_passive(uint8 ch, uint16 scan_time); NMI_API sint8 m2m_wifi_request_scan_ssid_list(uint8 ch,uint8 * u8Ssidlist); /*! +@ingroup WLANSCAN @fn \ NMI_API uint8 m2m_wifi_get_num_ap_found(void); @@ -2580,6 +2787,7 @@ NMI_API sint8 m2m_wifi_request_scan_ssid_list(uint8 ch,uint8 * u8Ssidlist); NMI_API uint8 m2m_wifi_get_num_ap_found(void); /*! +@ingroup WLANSCAN @fn \ NMI_API sint8 m2m_wifi_req_scan_result(uint8 index); @@ -2597,8 +2805,7 @@ NMI_API uint8 m2m_wifi_get_num_ap_found(void); Index for the requested result, the index range start from 0 till number of AP's found. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see tstrM2mWifiscanResult @@ -2707,6 +2914,7 @@ NMI_API uint8 m2m_wifi_get_num_ap_found(void); NMI_API sint8 m2m_wifi_req_scan_result(uint8 index); /*! +@ingroup WLANCONNECT @fn \ NMI_API sint8 m2m_wifi_req_curr_rssi(void); @@ -2714,17 +2922,17 @@ NMI_API sint8 m2m_wifi_req_scan_result(uint8 index); Asynchronous API to request the current Receive Signal Strength (RSSI) of the current connection. @details - The response received in through the @ref M2M_WIFI_RESP_CURRENT_RSSI event. + This function will result in the application receiving the RSSI via a + @ref M2M_WIFI_RESP_CURRENT_RSSI event. @pre - - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered - before initialization. Registering the callback is done through passing it to the - @ref m2m_wifi_init through the @ref tstrWifiInitParam initialization structure. - - The event @ref M2M_WIFI_RESP_CURRENT_RSSI must be handled in the callback to receive the requested Rssi information. + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered + during initialization. Registration of the callback is done through passing it to @ref m2m_wifi_init + via the @ref tstrWifiInitParam initialization structure. + - The event @ref M2M_WIFI_RESP_CURRENT_RSSI must be handled in the callback to receive the requested Rssi information. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. \section WIFIExample9 Example The code snippet demonstrates how the RSSI request is called in the application's main function and the handling of the event received in the callback. @@ -2770,6 +2978,7 @@ NMI_API sint8 m2m_wifi_req_scan_result(uint8 index); NMI_API sint8 m2m_wifi_req_curr_rssi(void); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid); @@ -2791,8 +3000,8 @@ NMI_API sint8 m2m_wifi_req_curr_rssi(void); Output MAC address buffer 6 bytes in size. Valid only if *pu8Valid=1. @param [out] pu8IsValid - Output boolean value to indicate the validity of pu8MacAddr in OTP. - Output zero if the OTP memory is not programmed, non-zero otherwise. + A boolean value set by the callee to indicate the validity of pu8MacAddr in OTP. If no MAC has + been programmed in the OTP the value of this parameter will be zero; otherwise it will be non-zero. @return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. @@ -2803,6 +3012,7 @@ NMI_API sint8 m2m_wifi_req_curr_rssi(void); NMI_API sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr) @@ -2829,6 +3039,7 @@ NMI_API sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr); /*! +@ingroup WLANPS @fn \ NMI_API sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn); @@ -2840,7 +3051,7 @@ NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr); to tweak the system power consumption. Such tweaking can be done through one of two ways: - 1) Changing the power save mode, to one of the allowed power save modes (see @ref tenuPowerSaveModes). This is done by setting the first parameter. - 2) Configuring DTIM monitoring: Configuring beacon monitoring parameters by enabling or disabling the reception of broadcast/multicast data. - this is done by setting the second parameter. + This is done by setting the second parameter. @param [in] PsTyp Desired power saving mode. Supported types are enumerated in @ref tenuPowerSaveModes. @@ -2865,6 +3076,7 @@ NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr); NMI_API sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn); /*! +@ingroup WLANPS @fn \ NMI_API sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime); @@ -2900,6 +3112,7 @@ NMI_API sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn); NMI_API sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime); /*! +@ingroup WLANPS @fn \ NMI_API uint8 m2m_wifi_get_sleep_mode(void); @@ -2971,6 +3184,7 @@ NMI_API sint8 m2m_wifi_req_client_ctrl(uint8 cmd); NMI_API sint8 m2m_wifi_req_server_init(uint8 ch); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength); @@ -2998,12 +3212,12 @@ NMI_API sint8 m2m_wifi_req_server_init(uint8 ch); length @ref M2M_DEVICE_NAME_MAX (including null character). @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. */ NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength); /*! +@ingroup WLANTIME @fn \ NMI_API sint8 m2m_wifi_configure_sntp(uint8 *pu8NTPServerName, uint8 u8NTPServerNameLength, tenuSNTPUseDHCP useDHCP); @@ -3011,10 +3225,9 @@ NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameL Configures what NTP server the SNTP client should use. @details - Configures what NTP server the SNTP client should use. Only 1 server name can be provided, if the configured server name begins with an asterisk then it will be treated as a server pool. - The SNTP client can also use the NTP server provided by the DHCP server through option 42. - By default the NTP server provided by DHCP will be tried first, then the built-in default NTP server (time.nist.gov) will be used. - Configuring a server name will overwrite the built-in default server until next reboot. + Configures what NTP server the SNTP client should use. Only 1 server name can be provided, if the configured server name begins with an asterisk then it will be treated as a server pool. + The SNTP client can also use the NTP server provided by the DHCP server through option 42. + By default the NTP server provided by DHCP will be tried first, then the built-in default NTP server (time.nist.gov) will be used. @param [in] pu8NTPServerName Buffer holding the NTP server name. If the first character is an asterisk (*) then it will be treated as a server pool, where the asterisk will @@ -3023,8 +3236,16 @@ NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameL @param [in] u8NTPServerNameLength Length of the NTP server name. Should not exceed the maximum NTP server name length of @ref M2M_NTP_MAX_SERVER_NAME_LENGTH. -@param [in] useDHCP - Should the NTP server provided by the DHCP server be used. +@param[in] useDHCP + Explicity tell the WINC if it should use the NTP server provided by the DHCP server or not. + +@warning + SNTP should be configured before the connection takes place. If SNTP is configured after the device connects to a + network, the new configuration can take a minimum of 24h to be applied. However, it can take even longer since it is + triggered by DHCP renewal. + Currently there is also a known issue in which if the WINC obtains the NTP server from DHCP and then connects to a + different network, it will still use the NTP from the previous network. + Configuring a server name will overwrite the built-in default server until next reboot. @return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. @@ -3032,6 +3253,7 @@ NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameL NMI_API sint8 m2m_wifi_configure_sntp(uint8 *pu8NTPServerName, uint8 u8NTPServerNameLength, tenuSNTPUseDHCP useDHCP); /*! +@ingroup WLANPS @fn \ NMI_API sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt * pstrM2mLsnInt); @@ -3062,7 +3284,10 @@ NMI_API sint8 m2m_wifi_configure_sntp(uint8 *pu8NTPServerName, uint8 u8NTPServer */ NMI_API sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt); +/**@cond MON_DOC + */ /*! +@ingroup WLANMON @fn \ NMI_API sint8 m2m_wifi_enable_monitoring_mode(tstrM2MWifiMonitorModeCtrl *, uint8 *, uint16 , uint16); @@ -3108,8 +3333,7 @@ NMI_API sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt); When this mode is enabled, you cannot be connected in any mode (Station or Access Point). @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see tstrM2MWifiMonitorModeCtrl @@ -3179,6 +3403,7 @@ NMI_API sint8 m2m_wifi_enable_monitoring_mode(tstrM2MWifiMonitorModeCtrl *pstrMt uint16 u16BufferSize, uint16 u16DataOffset); /*! +@ingroup WLANMON @fn \ NMI_API sint8 m2m_wifi_disable_monitoring_mode(void); @@ -3190,8 +3415,7 @@ NMI_API sint8 m2m_wifi_enable_monitoring_mode(tstrM2MWifiMonitorModeCtrl *pstrMt no negative impact will reside. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_monitoring_mode @@ -3199,6 +3423,7 @@ NMI_API sint8 m2m_wifi_enable_monitoring_mode(tstrM2MWifiMonitorModeCtrl *pstrMt NMI_API sint8 m2m_wifi_disable_monitoring_mode(void); /*! +@ingroup WLANMON @fn \ NMI_API sint8 m2m_wifi_send_wlan_pkt(uint8 *, uint16, uint16); @@ -3224,16 +3449,17 @@ NMI_API sint8 m2m_wifi_disable_monitoring_mode(void); The size of the whole packet in bytes. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_monitoring_mode m2m_wifi_disable_monitoring_mode */ NMI_API sint8 m2m_wifi_send_wlan_pkt(uint8 *pu8WlanPacket, uint16 u16WlanHeaderLength, uint16 u16WlanPktSize); +/**@endcond*/ //MON_DOC /*! +@ingroup WLANETH @fn \ NMI_API sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize); @@ -3258,8 +3484,7 @@ NMI_API sint8 m2m_wifi_send_wlan_pkt(uint8 *pu8WlanPacket, uint16 u16WlanHeaderL The size of the whole packet in bytes. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_mac_mcast @@ -3268,6 +3493,7 @@ NMI_API sint8 m2m_wifi_send_wlan_pkt(uint8 *pu8WlanPacket, uint16 u16WlanHeaderL NMI_API sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize); /*! +@ingroup WLANTIME @fn \ NMI_API sint8 m2m_wifi_enable_sntp(uint8); @@ -3291,9 +3517,8 @@ NMI_API sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize); '0' :disable SNTP '1' :enable SNTP -@return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_set_system_time @@ -3301,6 +3526,7 @@ NMI_API sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize); NMI_API sint8 m2m_wifi_enable_sntp(uint8 bEnable); /*! +@ingroup WLANTIME @fn \ NMI_API sint8 m2m_wifi_set_system_time(uint32); @@ -3316,8 +3542,7 @@ NMI_API sint8 m2m_wifi_enable_sntp(uint8 bEnable); Seconds elapsed since January 1, 1900 (NTP Timestamp). @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_sntp @@ -3330,6 +3555,7 @@ NMI_API sint8 m2m_wifi_enable_sntp(uint8 bEnable); NMI_API sint8 m2m_wifi_set_system_time(uint32 u32UTCSeconds); /*! +@ingroup WLANTIME @fn \ NMI_API sint8 m2m_wifi_get_system_time(void); @@ -3346,8 +3572,7 @@ NMI_API sint8 m2m_wifi_set_system_time(uint32 u32UTCSeconds); Get the system time from the SNTP client using the API @ref m2m_wifi_get_system_time. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_sntp @@ -3356,6 +3581,7 @@ NMI_API sint8 m2m_wifi_set_system_time(uint32 u32UTCSeconds); NMI_API sint8 m2m_wifi_get_system_time(void); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_set_cust_InfoElement(uint8*); @@ -3388,8 +3614,7 @@ NMI_API sint8 m2m_wifi_get_system_time(void); @endverbatim @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_sntp @@ -3430,15 +3655,15 @@ NMI_API sint8 m2m_wifi_get_system_time(void); NMI_API sint8 m2m_wifi_set_cust_InfoElement(uint8* pau8M2mCustInfoElement); /*! +@ingroup WLANPS @fn \ NMI_API sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode); @brief Change the power profile mode -@param [in] u8PwrMode - Change the WINC15x0 power profile to different mode based on the enumeration - @ref tenuM2mPwrMode. +@param [in] u8PwrMode + Change the WINC power profile to different mode based on the enumeration @ref tenuM2mPwrMode. @warning May only be called after initialization, before any connection request, and may not be used to change @@ -3454,6 +3679,7 @@ NMI_API sint8 m2m_wifi_set_cust_InfoElement(uint8* pau8M2mCustInfoElement); sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel); @@ -3476,6 +3702,7 @@ sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode); sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_set_gain_table_idx(uint8 u8GainTableIdx); @@ -3498,6 +3725,7 @@ sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel); sint8 m2m_wifi_set_gain_table_idx(uint8 u8GainTableIdx); /*! +@ingroup WLANLOG @fn \ NMI_API sint8 m2m_wifi_enable_firmware_logs(uint8 u8Enable); @@ -3505,8 +3733,7 @@ sint8 m2m_wifi_set_gain_table_idx(uint8 u8GainTableIdx); Enable or Disable logs in run time. @details - Enable or Disable logs in run time (Disable Firmware logs will enhance the firmware start-up time - and performance). + Enable or Disable logs in run time (Disable Firmware logs will enhance the firmware start-up time and performance). @param [in] u8Enable Set 1 to enable the logs, 0 for disable. @@ -3524,6 +3751,7 @@ sint8 m2m_wifi_set_gain_table_idx(uint8 u8GainTableIdx); sint8 m2m_wifi_enable_firmware_logs(uint8 u8Enable); /*! +@ingroup WLANCONF @fn \ NMI_API sint8 m2m_wifi_set_battery_voltage(uint8 u8BattVolt); @@ -3545,6 +3773,7 @@ sint8 m2m_wifi_enable_firmware_logs(uint8 u8Enable); sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100); /*! +@ingroup WLANCONF @fn \ sint8 m2m_wifi_set_gains(tstrM2mWifiGainsParams* pstrM2mGain); @@ -3558,8 +3787,7 @@ sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100); Must be called after initialization through the following function @ref m2m_wifi_init. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_init @@ -3568,6 +3796,7 @@ sint8 m2m_wifi_set_gains(tstrM2mWifiGainsParams* pstrM2mGain); #ifdef ETH_MODE /*! +@ingroup WLANETH @fn \ NMI_API sint8 m2m_wifi_enable_mac_mcast(uint8 *, uint8); @@ -3594,8 +3823,7 @@ sint8 m2m_wifi_set_gains(tstrM2mWifiGainsParams* pstrM2mGain); Make sure that the application defines ETH_MODE. @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_set_receive_buffer @@ -3604,6 +3832,7 @@ sint8 m2m_wifi_set_gains(tstrM2mWifiGainsParams* pstrM2mGain); NMI_API sint8 m2m_wifi_enable_mac_mcast(uint8* pu8MulticastMacAddress, uint8 u8AddRemove); /*! +@ingroup WLANETH @fn \ NMI_API sint8 m2m_wifi_set_receive_buffer(void *, uint16); @@ -3629,8 +3858,7 @@ NMI_API sint8 m2m_wifi_enable_mac_mcast(uint8* pu8MulticastMacAddress, uint8 u8A This function is available in the Ethernet/bypass mode ONLY. Make sure that the application defines ETH_MODE.\n @return - The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, - and a negative value otherwise. + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. @see m2m_wifi_enable_mac_mcast @@ -3641,22 +3869,25 @@ NMI_API sint8 m2m_wifi_set_receive_buffer(void* pvBuffer,uint16 u16BufferLen); #endif /* ETH_MODE */ /*! +@ingroup WLANCRYPTO @fn \ sint8 m2m_wifi_prng_get_random_bytes(uint8* pu8PrngBuff,uint16 u16PrngSize); @brief - Asynchronous function for retrieving from the firmware a pseudo-random set of bytes as specified in the size passed in as a parameter. - The registered wifi-cb function retrieves the random bytes through the response @ref M2M_WIFI_RESP_GET_PRNG + Asynchronous function for retrieving from the firmware a pseudo-random set of bytes. -@param [in] pu8PrngBuff - Pointer to a buffer to receive data. +@details + Asynchronous function for retrieving from the firmware a pseudo-random set of bytes as specified in the size passed in as a parameter. + The registered wifi-cb function retrieves the random bytes through the response @ref M2M_WIFI_RESP_GET_PRNG -@param [in] u16PrngSize - Request size in bytes +@param [in] pu8PrngBuff + Pointer to a buffer to receive data. + +@param [in] u16PrngSize + Requested size in bytes. Maximum 1580. @warning - Size greater than the maximum specified (@ref M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)) - causes a negative error @ref M2M_ERR_FAIL. + Size greater than the maximum specified (1580) causes a negative error @ref M2M_ERR_FAIL. @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. @@ -3664,7 +3895,8 @@ NMI_API sint8 m2m_wifi_set_receive_buffer(void* pvBuffer,uint16 u16BufferLen); sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize); /*! -@fn \ +@ingroup WLANCONF +@fn \ NMI_API sint8 m2m_wifi_conf_auto_rate(tstrConfAutoRate * pstrConfAutoRate); @brief @@ -3687,6 +3919,7 @@ sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize); NMI_API sint8 m2m_wifi_conf_auto_rate(tstrConfAutoRate * pstrConfAutoRate); /*! +@ingroup WLANROAMING @fn \ sint8 m2m_wifi_enable_roaming(uint8 bEnableDhcp); @@ -3717,6 +3950,7 @@ NMI_API sint8 m2m_wifi_conf_auto_rate(tstrConfAutoRate * pstrConfAutoRate); */ sint8 m2m_wifi_enable_roaming(uint8 bEnableDhcp); /*! +@ingroup WLANROAMING @fn \ sint8 m2m_wifi_disable_roaming(void); @@ -3735,6 +3969,7 @@ sint8 m2m_wifi_enable_roaming(uint8 bEnableDhcp); sint8 m2m_wifi_disable_roaming(void); /*! +@ingroup WLANINIT @fn \ NMI_API uint8 m2m_wifi_get_state(void); @@ -3755,11 +3990,8 @@ sint8 m2m_wifi_disable_roaming(void); */ NMI_API uint8 m2m_wifi_get_state(void); -/**@}*/ //WLANAPI - - -/** @addtogroup VERSION Version -@brief +/** @defgroup VERSION Version + @brief Describes the APIs for reading the version information of the WINC firmware. @{ @defgroup VERSIONDEF Defines @@ -3785,6 +4017,27 @@ NMI_API uint8 m2m_wifi_get_state(void); */ NMI_API sint8 m2m_wifi_get_firmware_version(tstrM2mRev* pstrRev); +/*! +@ingroup WLANPS +@fn \ + sint8 m2m_wifi_enable_XO_during_sleep(uint8 bXOSleepEnable); + +@brief + Specifies whether the crystal oscillator is left on or off during deep sleep (defaults to off). + +@details + m2m_wifi_enable_XO_during_sleep controls the state of the crystal oscillator during deep sleep. + +@param[in] bXOSleepEnable + 0 : The XO will be switched off during deep sleep + 1 : The XO will be kept on during deep sleep + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +*/ +sint8 m2m_wifi_enable_XO_during_sleep(uint8 bXOSleepEnable); + #ifdef __cplusplus } #endif diff --git a/src/drivers/winc1500/include/socket/include/m2m_socket_host_if.h b/src/drivers/winc1500/include/socket/include/m2m_socket_host_if.h index 470d2321f..31415f634 100644 --- a/src/drivers/winc1500/include/socket/include/m2m_socket_host_if.h +++ b/src/drivers/winc1500/include/socket/include/m2m_socket_host_if.h @@ -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; - 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. + 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{ diff --git a/src/drivers/winc1500/include/socket/include/socket.h b/src/drivers/winc1500/include/socket/include/socket.h index 95a83ad86..56264f818 100644 --- a/src/drivers/winc1500/include/socket/include/socket.h +++ b/src/drivers/winc1500/include/socket/include/socket.h @@ -4,7 +4,7 @@ * * \brief WINC 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 * @@ -71,10 +71,10 @@ MACROS * HOSTNAME_MAX_SIZE is defined here and also in host_drv/socket/include/m2m_socket_host_if.h * The two definitions must match. */ -#define HOSTNAME_MAX_SIZE 64 -/*!< - Maximum allowed size for a host domain name passed to the function gethostbyname @ref gethostbyname. - command value. Used with the setsockopt function. +#define HOSTNAME_MAX_SIZE 64 +/*!< + Maximum allowed size for a host domain name passed to the function gethostbyname @ref gethostbyname. + command value. Used with the @ref setsockopt function. */ #define SOCKET_BUFFER_MAX_LENGTH 1400 @@ -102,12 +102,36 @@ MACROS Passed to the @ref socket function for the socket creation operation. */ -#define SOCKET_FLAGS_SSL 0x01 -/*!< - This flag shall be passed to the socket API for SSL session. +#define SOCKET_FLAGS_SSL 0x01 +/*!< + This flag may be set in the u8Config parameter of @ref socket, to create a + TLS socket.\n + Note that the number of TLS sockets is limited to 4.\n + This flag is kept for legacy purposes. It is recommended that applications + use @ref SOCKET_CONFIG_SSL_ON instead. */ -#define TCP_SOCK_MAX (7) +#define SOCKET_CONFIG_SSL_OFF 0 +/*!< + This value may be passed in the u8Config parameter of @ref socket, to + create a socket not capable of TLS. +*/ +#define SOCKET_CONFIG_SSL_ON 1 +/*!< + This value may be passed in the u8Config parameter of @ref socket, to + create a TLS socket.\n + Note that the number of TLS sockets is limited to 4. +*/ +#define SOCKET_CONFIG_SSL_DELAY 2 +/*!< + This value may be passed in the u8Config parameter of @ref socket, to + create a TCP socket which has the potential to upgrade to a TLS socket + later (by calling @ref secure).\n + Note that the total number of TLS sockets and potential TLS sockets is + limited to 4. +*/ + +#define TCP_SOCK_MAX (7) /*!< Maximum number of simultaneous TCP sockets. */ @@ -136,9 +160,17 @@ MACROS #define SO_SET_UDP_SEND_CALLBACK 0x00 /*!< - Socket option used by the application to enable/disable - the use of UDP send callbacks. - Used with the @ref setsockopt function. + Socket option used by the application to enable/disable + the use of UDP send callbacks.\n + Used with the @ref setsockopt function.\n + The option value should be cast to int type.\n + 0: disable UDP send callbacks.\n + 1: enable UDP send callbacks.\n + Default setting is enable. + + @warning @ref connect and @ref bind cause this setting to + be lost, so the application should only set this option + after calling @ref connect or @ref bind. */ #define IP_ADD_MEMBERSHIP 0x01 @@ -153,76 +185,147 @@ MACROS Used with the @ref setsockopt function. */ -#define SO_KEEPALIVE 0x04 +#define SO_TCP_KEEPALIVE 0x04 /*!< - Enable or disable TCP keep-alive. - Used with the @ref setsockopt function. + Socket option to enable or disable TCP keep-alive.\n + Used with the @ref setsockopt function.\n + The option value should be cast to int type.\n + 0: disable TCP keep-alive.\n + 1: enable TCP keep-alive.\n + Default setting is disable. + + @warning @ref connect and @ref bind cause this setting to + be lost, so the application should only set this option + after calling @ref connect or @ref bind. */ -#define TCP_KEEPIDLE 0x05 +#define SO_TCP_KEEPIDLE 0x05 /*!< - Duration between two keepalive transmissions in idle condition (in 500ms increments, so 4 would be 2 seconds). Max 2^32. - Used with the @ref setsockopt function. + Socket option to set the time period after which the socket will trigger keep-alive transmissions.\n + Used with the @ref setsockopt function.\n + The option value should be cast to int type.\n + Option value is the time period in units of 500ms. Maximum 2^32 - 1. + Default setting is 120 (60 seconds). + + @warning @ref connect and @ref bind cause this setting to + be lost, so the application should only set this option + after calling @ref connect or @ref bind. */ -#define TCP_KEEPINTVL 0x06 +#define SO_TCP_KEEPINTVL 0x06 /*!< - Duration between two successive keepalive retransmissions, if acknowledgment to the previous keepalive - transmission is not received (in 500ms increments, so 4 would be 2 seconds). Max 255 (127.5 seconds). - Used with the @ref setsockopt function. + Socket option to set the time period between keep-alive retransmissions.\n + Used with the @ref setsockopt function.\n + The option value should be cast to int type.\n + Option value is the time period in units of 500ms. Maximum 255. + Default setting is 1 (0.5 seconds). + + @warning @ref connect and @ref bind cause this setting to + be lost, so the application should only set this option + after calling @ref connect or @ref bind. */ -#define TCP_KEEPCNT 0x07 +#define SO_TCP_KEEPCNT 0x07 /*!< - Number of retransmissions to be carried out before declaring that the remote end is not available. Max 255. - Used with the @ref setsockopt function. + Socket option to set the number of keep-alive retransmissions to be carried out before declaring that the remote end is not available.\n + Used with the @ref setsockopt function.\n + The option value should be cast to int type.\n + Maximum 255. + Default setting is 20. + + @warning @ref connect and @ref bind cause this setting to + be lost, so the application should only set this option + after calling @ref connect or @ref bind. */ /**@}*/ //IPDefines + +/**@addtogroup TLSDefines + * @{ + */ +#define ALPN_LIST_MAX_APP_LENGTH 30 +/*!< + Maximum length of ALPN list that can be specified by the application. + This length includes separators (spaces) and terminator (NUL). +*/ +/**@}*/ // TLSDefines + /** - * @defgroup TLSDefines TLS Defines - * @ingroup SocketDefines + * @defgroup TLSDefines TLS Defines + * @ingroup SOCKETDEF * @ingroup SSLAPI */ -/** @defgroup SSLSocketOptions TLS Socket Options +/**@defgroup SSLSocketOptions TLS Socket Options * @ingroup TLSDefines * The following list of macros are used to define SSL Socket options. * @{ * @sa setsockopt */ -#define SO_SSL_BYPASS_X509_VERIF 0x01 +#define SO_SSL_BYPASS_X509_VERIF 0x01 /*!< - Allow an opened SSL socket to bypass the X509 certificate - verification process. - It is highly required NOT to use this socket option in production - software applications. It is supported for debugging and testing - purposes. - The option value should be casted to int type and it is handled - as a boolean flag. + Allow an opened SSL socket to bypass the X509 certificate verification + process. + It is recommended NOT to use this socket option in production software + applications. It is supported for debugging and testing purposes.\n + The option value should be casted to int type.\n + 0: do not bypass the X509 certificate verification process (default, + recommended).\n + 1: bypass the X509 certificate verification process.\n + + This option only takes effect if it is set after calling @ref socket and + before calling @ref connect or @ref secure. */ -#define SO_SSL_SNI 0x02 +#define SO_SSL_SNI 0x02 /*!< - Set the Server Name Indicator (SNI) for an SSL socket. The - SNI is a NULL terminated string containing the server name - associated with the connection. It must not exceed the size - of HOSTNAME_MAX_SIZE. + Set the Server Name Indicator (SNI) for an SSL socket. The SNI is a NULL- + terminated string containing the server name associated with the + connection. Its size must not exceed @ref HOSTNAME_MAX_SIZE. If the SNI is + not a null string, then TLS Client Hello messages will include the SNI + extension.\n + + This option only takes effect if it is set after calling @ref socket and + before calling @ref connect or @ref secure. */ -#define SO_SSL_ENABLE_SESSION_CACHING 0x03 +#define SO_SSL_ENABLE_SESSION_CACHING 0x03 /*!< - This option allow the TLS to cache the session information for fast - TLS session establishment in future connections using the - TLS Protocol session resume features. + This option allow the TLS to cache the session information for fast TLS + session establishment in future connections using the TLS Protocol session + resume features.\n + The option value should be casted to int type.\n + 0: disable TLS session caching (default).\n + 1: enable TLS session caching.\n + Note that TLS session caching is always enabled in TLS Server Mode and this + option is ignored.\n + + This option only takes effect if it is set after calling @ref socket and + before calling @ref connect or @ref secure. */ -#define SO_SSL_ENABLE_SNI_VALIDATION 0x04 +#define SO_SSL_ENABLE_SNI_VALIDATION 0x04 /*!< - Enable SNI validation against the server's certificate subject - common name. If there is no SNI provided (via the SO_SSL_SNI - option), setting this option does nothing. + Enable internal validation of server name against the server's + certificate subject common name. If there is no server name + provided (via the @ref SO_SSL_SNI option), setting this option + does nothing.\n + The option value should be casted to int type.\n + 0: disable server certificate name validation (default).\n + 1: enable server certificate name validation (recommended).\n + + This option only takes effect if it is set after calling @ref socket and + before calling @ref connect or @ref secure. +*/ + +#define SO_SSL_ALPN 0x05 +/*!< + Set the list to use for Application-Layer Protocol Negotiation + for an SSL socket. \n + This option is intended for internal use and should not be + used by the application. Applications should use the API @ref + set_alpn_list. */ /**@}*/ //SSLSocketOptions @@ -425,20 +528,19 @@ Socket Errors #define SOCK_ERR_INVALID_ARG -6 /*!< - An invalid argument is passed to a function. + An invalid argument is passed to a socket function. Identifies that @ref socket operation failed */ #define SOCK_ERR_MAX_LISTEN_SOCK -7 /*!< - Exceeded the maximum number of TCP passive listening sockets. - Identifies Identifies that @ref listen operation failed. + Exceeded the maximum number of TCP passive listening sockets. + Identifies that @ref listen operation failed. */ #define SOCK_ERR_INVALID -9 /*!< - The requested socket operation is not valid in the - current socket state. - For example: @ref accept is called on a TCP socket before @ref bind or @ref listen. + The requested socket operation is not valid in the current socket state. + For example: @ref accept is called on a TCP socket before @ref bind or @ref listen. */ #define SOCK_ERR_ADDR_IS_REQUIRED -11 @@ -463,8 +565,10 @@ Socket Errors */ /**@}*/ //SocketErrorCode -/** @addtogroup SocketDefines - * @{ +/**@addtogroup SOCKETBYTEORDER Byte Order + * @ingroup SocketHeader + * The following list of macros are used to convert between host representation and network byte order. + * @{ */ #ifdef _NM_BSP_BIG_END #define _htonl(m) (m) @@ -493,7 +597,7 @@ Socket Errors /*!< Convert a 2-byte integer from the Network byte order representation to the host representation . */ -/**@}*/ //SocketDefines +/**@}*/ //SOCKETBYTEORDER /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* DATA TYPES @@ -501,22 +605,48 @@ DATA TYPES /** @defgroup SocketEnums DataTypes * @ingroup SocketHeader * Specific Enumeration-typedefs used for socket operations - * @{ */ - + * @{ + */ /*! @typedef \ SOCKET @brief - Definition for socket handler data type. - Socket ID,used with all socket operations to uniquely identify the socket handler. - Such an ID is uniquely assigned at socket creation when calling @ref socket operation. + Definition for socket handler data type. + Socket ID,used with all socket operations to uniquely identify the socket handler. + The ID is uniquely assigned at socket creation when calling @ref socket operation. */ typedef sint8 SOCKET; /*! -@struct \ - in_addr +@enum \ + tenuSockErrSource + +@brief + Source of socket error (local, remote or unknown). + +@see tstrSockErr +*/ + +typedef enum { + SOCKET_ERR_UNKNOWN = 0, + /*!< + No detail available (also used when there is no error). + */ + SOCKET_ERR_TLS_REMOTE, + /*!< + TLS Error Alert received from peer. + */ + SOCKET_ERR_TLS_LOCAL + /*!< + TLS Error Alert generated locally. + */ +} tenuSockErrSource; + + +/*! +@struct \ + in_addr @brief IPv4 address representation. @@ -559,34 +689,53 @@ Socket address family. sockaddr_in @brief - Socket address structure for IPV4 addresses. Used to specify socket address information to which to connect to. - Can be cast to @ref sockaddr structure. + Socket address structure for IPV4 addresses. Used to specify socket address information to connect to. + Can be cast to @ref sockaddr structure. */ -struct sockaddr_in{ - uint16 sin_family; - /*!< - Specifies the address family(AF). - Members of AF_INET address family are IPv4 addresses. - Hence,the only supported value for this is AF_INET. - */ - uint16 sin_port; - /*!< - Port number of the socket. - Network sockets are identified by a pair of IP addresses and port number. - It must be set in the Network Byte Order format , _htons (e.g. _htons(80)). - Can NOT have zero value. - */ - in_addr sin_addr; - /*!< - IP Address of the socket. - The IP address is of type @ref in_addr structure. - Can be set to "0" to accept any IP address for server operation. non zero otherwise. - */ - uint8 sin_zero[8]; - /*!< - Padding to make structure the same size as @ref sockaddr. - */ +struct sockaddr_in { + uint16 sin_family; + /*!< + Specifies the address family(AF). + Members of AF_INET address family are IPv4 addresses. + Hence,the only supported value for this is AF_INET. + */ + uint16 sin_port; + /*!< + Port number of the socket. + Network sockets are identified by a pair of IP addresses and port number. + It must be set in the Network Byte Order format , @ref _htons (e.g. _htons(80)). + Can NOT have zero value. + */ + in_addr sin_addr; + /*!< + IP Address of the socket. + The IP address is of type @ref in_addr structure. + Can be set to "0" to accept any IP address for server operation. + */ + uint8 sin_zero[8]; + /*!< + Padding to make structure the same size as @ref sockaddr. + */ }; + +/*! +@struct \ + tstrSockErr + +@brief + Detail about socket failures. Used with @ref get_error_detail. +*/ +typedef struct { + tenuSockErrSource enuErrSource; + /*!< + Source of socket error (local, remote or unknown). + */ + uint8 u8ErrCode; + /*!< + TLS Alert code as defined in + https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6. + */ +} tstrSockErr; /**@}*/ //SocketEnums /**@defgroup AsyncCallback Asynchronous Events @@ -614,45 +763,49 @@ struct sockaddr_in{ @see send @see recv */ - -typedef enum{ - SOCKET_MSG_BIND = 1, - /*!< - Bind socket event. - */ - SOCKET_MSG_LISTEN, - /*!< - Listen socket event. - */ - SOCKET_MSG_DNS_RESOLVE, - /*!< - DNS Resolution event. - */ - SOCKET_MSG_ACCEPT, - /*!< - Accept socket event. - */ - SOCKET_MSG_CONNECT, - /*!< - Connect socket event. - */ - SOCKET_MSG_RECV, - /*!< - Receive socket event. - */ - SOCKET_MSG_SEND, - /*!< - Send socket event. - */ - SOCKET_MSG_SENDTO, - /*!< - sendto socket event. - */ - SOCKET_MSG_RECVFROM - /*!< - Recvfrom socket event. - */ -}tenuSocketCallbackMsgType; + +typedef enum { + SOCKET_MSG_BIND = 1, + /*!< + Bind socket event. + */ + SOCKET_MSG_LISTEN, + /*!< + Listen socket event. + */ + SOCKET_MSG_DNS_RESOLVE, + /*!< + DNS Resolution event. + */ + SOCKET_MSG_ACCEPT, + /*!< + Accept socket event. + */ + SOCKET_MSG_CONNECT, + /*!< + Connect socket event. + */ + SOCKET_MSG_RECV, + /*!< + Receive socket event. + */ + SOCKET_MSG_SEND, + /*!< + Send socket event. + */ + SOCKET_MSG_SENDTO, + /*!< + Sendto socket event. + */ + SOCKET_MSG_RECVFROM, + /*!< + Recvfrom socket event. + */ + SOCKET_MSG_SECURE +/*!< + Existing socket made secure event. +*/ +} tenuSocketCallbackMsgType; /*! @@ -666,33 +819,33 @@ typedef enum{ @see bind */ -typedef struct{ - sint8 status; - /*!< - The result of the bind operation. - Holding a value of ZERO for a successful bind or otherwise a negative - error code corresponding to the type of error. - */ -}tstrSocketBindMsg; +typedef struct { + sint8 status; + /*!< + The result of the bind operation. + Holding a value of ZERO for a successful bind or otherwise a negative + error code corresponding to @ref SocketErrorCode. + */ +} tstrSocketBindMsg; /*! -@struct \ - tstrSocketListenMsg +@struct \ + tstrSocketListenMsg -@brief Socket listen status. +@brief Socket listen status. - Socket listen information is returned through this structure in response to the asynchronous call to the @ref listen function. - This structure together with the event @ref SOCKET_MSG_LISTEN are passed-in parameters to the callback function. + Socket listen information is returned through this structure in response to the asynchronous call to the @ref listen function. + This structure together with the event @ref SOCKET_MSG_LISTEN are passed-in parameters to the callback function. @see listen */ -typedef struct{ - sint8 status; - /*!< - Holding a value of ZERO for a successful listen or otherwise a negative - error code corresponding to the type of error. - */ -}tstrSocketListenMsg; +typedef struct { + sint8 status; + /*!< + Holding a value of ZERO for a successful listen or otherwise a negative + error code corresponding to @ref SocketErrorCode. + */ +} tstrSocketListenMsg; /*! @struct \ @@ -721,71 +874,73 @@ typedef struct{ @brief Socket connect status. - Socket connect information is returned through this structure in response to the asynchronous call to the @ref connect socket function. - This structure together with the event @ref SOCKET_MSG_CONNECT are passed-in parameters to the callback function. - If the application receives this structure with a negative value in s8Error, the application should call @ref close(). + Socket connect information is returned through this structure in response to an asynchronous call to the @ref connect socket function + or the @ref secure socket function. + This structure and the event @ref SOCKET_MSG_CONNECT or @ref SOCKET_MSG_SECURE are passed in parameters to the callback function. + If the application receives this structure with a negative value in s8Error, the application should call @ref close(). */ -typedef struct{ - SOCKET sock; - /*!< - Socket ID referring to the socket passed to the connect function call. - */ - sint8 s8Error; - /*!< - Connect error code. - Holding a value of ZERO for a successful connect or otherwise a negative - error code corresponding to the type of error. - */ -}tstrSocketConnectMsg; +typedef struct { + SOCKET sock; + /*!< + Socket ID referring to the socket passed to the @ref connect or @ref secure function call. + */ + sint8 s8Error; + /*!< + Connect error code:\n + - ZERO for a successful connect or successful secure. \n + - Otherwise a negative error code corresponding to the type of error. + */ +} tstrSocketConnectMsg; /*! -@struct \ - tstrSocketRecvMsg +@struct \ + tstrSocketRecvMsg -@brief Socket recv status. +@brief Socket recv status. - Socket receive information is returned through this structure in response to the asynchronous call to the recv or recvfrom socket functions. - This structure together with the events @ref SOCKET_MSG_RECV or @ref SOCKET_MSG_RECVFROM are passed-in parameters to the callback function. -@remark - In case the received data from the remote peer is larger than the USER buffer size defined during the asynchronous call to the @ref recv function, - delivered to the user in a number of consecutive chunks according to the USER Buffer size. - A negative or zero buffer size indicates an error with the following code: - @ref SOCK_ERR_NO_ERROR : Socket connection closed. The application should now call @ref close(). - @ref SOCK_ERR_CONN_ABORTED : Socket connection aborted. The application should now call @ref close(). - @ref SOCK_ERR_TIMEOUT : Socket receive timed out. The socket connection remains open. + Socket receive information is returned through this structure in response to the asynchronous call to the @ref recv or @ref recvfrom socket functions. + This structure, together with the events @ref SOCKET_MSG_RECV or @ref SOCKET_MSG_RECVFROM, is passed-in parameters to the callback function. +@remark + After receiving this structure, the application should issue a new call to @ref recv or @ref recvfrom in order to receive subsequent data.\n + In the case of @ref SOCKET_MSG_RECVFROM (UDP), any further data in the same datagram is dropped, then subsequent datagrams are buffered on the WINC until the application provides a buffer via a new call to @ref recvfrom.\n + In the case of @ref SOCKET_MSG_RECV (TCP), all subsequent data is buffered on the WINC until the application provides a buffer via a new call to @ref recv.\n + A negative or zero buffer size indicates an error with the following code: + @ref SOCK_ERR_NO_ERROR : Socket connection closed. The application should now call @ref close(). + @ref SOCK_ERR_CONN_ABORTED : Socket connection aborted. The application should now call @ref close(). + @ref SOCK_ERR_TIMEOUT : Socket receive timed out. The socket connection remains open. */ -typedef struct{ - uint8 *pu8Buffer; - /*!< - Pointer to the USER buffer (passed to @ref recv and @ref recvfrom function) containing the received data chunk. - */ - sint16 s16BufferSize; - /*!< - The received data chunk size. - Holds a negative value if there is a receive error or ZERO on success upon reception of close socket message. - */ - uint16 u16RemainingSize; - /*!< - The number of bytes remaining in the current @ref recv operation. - */ - struct sockaddr_in strRemoteAddr; - /*!< - Socket address structure for the remote peer. It is valid for @ref SOCKET_MSG_RECVFROM event. - */ -}tstrSocketRecvMsg; +typedef struct { + uint8 *pu8Buffer; + /*!< + Pointer to the USER buffer (passed to @ref recv and @ref recvfrom function) containing the received data chunk. + */ + sint16 s16BufferSize; + /*!< + The received data chunk size. + Holds a negative value if there is a receive error or ZERO on success upon reception of close socket message. + */ + uint16 u16RemainingSize; + /*!< + This field is used internally by the driver. In normal operation, this field will be 0 when the application receives this structure. + */ + struct sockaddr_in strRemoteAddr; + /*!< + Socket address structure for the remote peer. It is valid for @ref SOCKET_MSG_RECVFROM event. + */ +} tstrSocketRecvMsg; /**@}*/ //AsyncCallback -/** @defgroup SocketCallbacks Callbacks - * @ingroup SocketHeader +/**@defgroup SocketCallbacks Callbacks + * @ingroup SocketHeader + * @{ */ -/**@{*/ /*! @typedef \ tpfAppSocketCb @brief - The main socket application callback function. Applications register their main socket application callback through this function by calling @ref registerSocketCallback. - In response to events received, the following callback function is called to handle the corresponding asynchronous function called. Example: @ref bind, @ref connect,...etc. + The main socket application callback function. Applications register their main socket application callback through this function by calling @ref registerSocketCallback. + In response to events received, the following callback function is called to handle the corresponding asynchronous function called. Example: @ref bind, @ref connect,...etc. @param [in] sock Socket ID for the callback. @@ -794,16 +949,17 @@ typedef struct{ to socket operations. @param [in] u8Msg - Socket event type. Possible values are: - - @ref SOCKET_MSG_BIND - - @ref SOCKET_MSG_LISTEN - - @ref SOCKET_MSG_ACCEPT - - @ref SOCKET_MSG_CONNECT - - @ref SOCKET_MSG_RECV - - @ref SOCKET_MSG_SEND - - @ref SOCKET_MSG_SENDTO - - @ref SOCKET_MSG_RECVFROM - + Socket event type. Possible values are: + - @ref SOCKET_MSG_BIND + - @ref SOCKET_MSG_LISTEN + - @ref SOCKET_MSG_ACCEPT + - @ref SOCKET_MSG_CONNECT + - @ref SOCKET_MSG_RECV + - @ref SOCKET_MSG_SEND + - @ref SOCKET_MSG_SENDTO + - @ref SOCKET_MSG_RECVFROM + - @ref SOCKET_MSG_SECURE + @param [in] pvMsg Pointer to message structure. Existing types are: - tstrSocketBindMsg @@ -827,15 +983,15 @@ typedef void (*tpfAppSocketCb) (SOCKET sock, uint8 u8Msg, void * pvMsg); tpfAppResolveCb @brief - DNS resolution callback function. - Applications requiring DNS resolution should register their callback through this function by calling @ref registerSocketCallback. - The following callback is triggered in response to asynchronous call to the @ref gethostbyname function (DNS Resolution callback). + DNS resolution callback function. + Applications requiring DNS resolution should register their callback through this function by calling @ref registerSocketCallback. + The following callback is triggered in response to an asynchronous call to the @ref gethostbyname function (DNS Resolution callback). @param [in] pu8DomainName Domain name of the host. -@param [in] u32ServerIP - Server IPv4 address encoded in NW byte order format. If it is Zero, then the DNS resolution failed. +@param[in] u32ServerIP + Server IPv4 address encoded in Network byte order format. If it is Zero, then the DNS resolution failed. */ typedef void (*tpfAppResolveCb) (uint8* pu8DomainName, uint32 u32ServerIP); @@ -845,8 +1001,8 @@ typedef void (*tpfAppResolveCb) (uint8* pu8DomainName, uint32 u32ServerIP); @brief PING Callback - The function delivers the ping statistics for the sent ping triggered by calling - m2m_ping_req. + The function delivers the ping statistics for the sent ping triggered by calling + @ref m2m_ping_req. @param [in] u32IPAddr Destination IP. @@ -866,8 +1022,8 @@ typedef void (*tpfPingCb)(uint32 u32IPAddr, uint32 u32RTT, uint8 u8ErrorCode); /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* FUNCTION PROTOTYPES *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ -/** \defgroup SocketAPI Function - * @ingroup SocketHeader +/** @defgroup SocketAPI Functions + * @ingroup SocketHeader */ /** @defgroup SocketInitializationFn socketInit @@ -886,11 +1042,11 @@ FUNCTION PROTOTYPES @return void -@remarks - This initialization function must be invoked before any socket operation is performed. - No error codes from this initialization function since the socket array is statically allocated based in the maximum number of - sockets @ref MAX_SOCKET based on the systems capability. -\section socketinit example +@remarks + This initialization function must be invoked before any socket operation is performed. + No error codes from this initialization function since the socket array is statically allocated based in the maximum number of + sockets @ref MAX_SOCKET based on the systems capability. +\section socketInit_Ex Example This example demonstrates the use of the socketinit for socket initialization for an mqtt chat application. \code tstrWifiInitParam param; @@ -928,19 +1084,28 @@ This example demonstrates the use of the socketinit for socket initialization fo \endcode */ NMI_API void socketInit(void); +/** @} */ //SocketInitializationFn - +/** @defgroup SocketDeInitializationFn socketDeInit + * @ingroup SocketAPI + */ +/**@{*/ /*! @fn \ NMI_API void socketDeinit(void); @brief Socket Layer De-initialization - The function performs the necessary cleanup for the socket library static data - It must be invoked as the last any socket operation is performed on any active sockets. + The function performs the necessary cleanup for the socket library static data + It must be invoked only after all desired socket operations have been performed on any active sockets. */ NMI_API void socketDeinit(void); +/** @} */ //SocketDeInitializationFn +/** @defgroup SocketStateFn socketState + * @ingroup SocketAPI + */ +/**@{*/ /*! @fn \ uint8 IsSocketReady(void); @@ -951,7 +1116,7 @@ NMI_API void socketDeinit(void); Should return 1 after @ref socketInit and 0 after @ref socketDeinit */ NMI_API uint8 IsSocketReady(void); -/** @} */ //SocketInitializationFn +/** @} */ //SocketStateFn /** @defgroup SocketCallbackFn registerSocketCallback * @ingroup SocketAPI @@ -962,28 +1127,28 @@ NMI_API uint8 IsSocketReady(void); /*! -@fn \ - NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb resolve_cb); - -@param [in] socket_cb tpfAppSocketCb - Assignment of callback function to the global callback @ref tpfAppSocketCb gpfAppSocketCb. Delivers - socket messages to the host application. In response to the asynchronous function calls, such as @ref bind - @ref listen @ref accept @ref connect - -@param [in] resolve_cb tpfAppResolveCb - Assignment of callback function to the global callback @ref tpfAppResolveCb gpfAppResolveCb. - Used for DNS resolving functionalities. The DNS resolving technique is determined by the application - registering the callback. - NULL is assigned when, DNS resolution is not required. - -@return void -@remarks - If any of the socket functionalities is not to be used, NULL is passed in as a parameter. - It must be invoked after socketinit and before other socket layer operations. - -\section registerSocketCallback example - This example demonstrates the use of the registerSocketCallback to register a socket callback function with DNS resolution CB set to null - for a simple UDP server example. +@fn \ + NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb resolve_cb); + +@param[in] socket_cb tpfAppSocketCb + Assignment of callback function to the global callback @ref tpfAppSocketCb gpfAppSocketCb. Delivers + socket messages to the host application. In response to the asynchronous function calls, such as @ref bind + @ref listen @ref accept @ref connect + +@param[in] resolve_cb tpfAppResolveCb + Assignment of callback function to the global callback @ref tpfAppResolveCb gpfAppResolveCb. + Used for DNS resolving. The DNS resolving technique is determined by the application + registering the callback. + NULL is assigned when, DNS resolution is not required. + +@return void +@remarks + If the socket functionality is not to be used, NULL is passed in as a parameter. + It must be invoked after socketinit and before other socket layer operations. + +\section registerSocketCallback_Ex Example + This example demonstrates the use of the registerSocketCallback to register a socket callback function with DNS resolution CB set to null + for a simple UDP server example. \code tstrWifiInitParam param; tstrNetworkId strNetworkId; @@ -1045,8 +1210,8 @@ NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb re */ /**@{*/ /*! -@fn \ - NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags); +@fn \ + NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Config); @param [in] u16Domain @@ -1057,38 +1222,46 @@ NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb re - @ref SOCK_STREAM - @ref SOCK_DGRAM -@param [in] u8Flags - Used to specify the socket creation flags. It shall be set to zero for normal TCP/UDP sockets. - It could be @ref SOCKET_FLAGS_SSL if the socket is used for SSL session. The use of the flag - @ref SOCKET_FLAGS_SSL has no meaning in case of UDP sockets. +@param[in] u8Config + Used to specify the socket configuration. The following + configuration values are defined:\n + - @ref SOCKET_CONFIG_SSL_OFF : The socket is not secured by TLS.\n + - @ref SOCKET_CONFIG_SSL_ON : The socket is secured by TLS. + This value has no effect if u8Type is @ref SOCK_DGRAM. + - @ref SOCKET_CONFIG_SSL_DELAY : The socket is not secured by + TLS, but may be secured later, by calling @ref secure. + This value has no effect if u8Type is @ref SOCK_DGRAM.\n + All other configuration values are reserved and should not be + used. @pre - The @ref socketInit function must be called once at the beginning of the application to initialize the socket handler. - before any call to the socket function can be made. + The @ref socketInit function must be called once at the beginning of the application to initialize the socket handler. + before any call to the @ref socket function can be made. @see - connect - bind - listen - accept - recv - recvfrom - send - sendto - close - setsockopt - getsockopt - -@return - On successful socket creation, a non-blocking socket type is created and a socket ID is returned - In case of failure the function returns a negative value, identifying one of the socket error codes defined. + connect + secure + bind + listen + accept + recv + recvfrom + send + sendto + close + setsockopt + getsockopt + +@return + On successful socket creation, a non-blocking socket type is created and a socket ID is returned + In case of failure the function returns a negative value, identifying one of the socket error codes defined. For example: @ref SOCK_ERR_INVALID for invalid argument or @ref SOCK_ERR_MAX_TCP_SOCK if the number of TCP allocated sockets exceeds the number of available sockets. @remarks - The socket function must be called a priori to any other related socket functions "e.g. send, recv, close ..etc" -\section Socket allocation example - This example demonstrates the use of the socket function to allocate the socket, returning the socket handler to be used for other + The socket function must be called a priori to any other related socket functions "e.g. send, recv, close ..etc" +\section Socket_Ex Allocation example + This example demonstrates the use of the socket function to allocate the socket, returning the socket handler to be used for other socket operations. Socket creation is dependent on the socket type. UDP example @@ -1116,7 +1289,7 @@ static SOCKET ssl_socket = -1; ssl_socket = socket(AF_INET, SOCK_STREAM, SOCK_FLAGS_SSL)); @endcode */ -NMI_API SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Flags); +NMI_API SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Config); /** @} */ //SocketFn /** @defgroup BindFn bind @@ -1162,9 +1335,9 @@ NMI_API SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8F Indicating passing invalid arguments such as negative socket ID or NULL socket address structure. - @ref SOCK_ERR_INVALID - Indicate socket bind failure. -\section bind example - This example demonstrates the call of the bind socket operation after a successful socket operation. + Indicate socket bind failure. +\section bind_Ex Example + This example demonstrates the call of the bind socket operation after a successful socket operation. @code struct sockaddr_in addr; SOCKET udpServerSocket =-1; @@ -1242,8 +1415,8 @@ NMI_API sint8 WINC1500_EXPORT(bind)(SOCKET sock, struct sockaddr *pstrAddr, uint Indicating passing invalid arguments such as negative socket ID. - @ref SOCK_ERR_INVALID - Indicate socket listen failure. -\section listen example + Indicate socket listen failure. +\section listen_Ex Example This example demonstrates the call of the listen socket operation after a successful socket operation. @code static void TCP_Socketcallback(SOCKET sock, uint8 u8Msg, void * pvMsg) @@ -1346,17 +1519,18 @@ NMI_API sint8 WINC1500_EXPORT(listen)(SOCKET sock, uint8 backlog); Indicating passing invalid arguments such as negative socket ID. */ NMI_API sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8 *addrlen); -/** @} */ +/** @} */ //AcceptFn + /** @defgroup ConnectFn connect @ingroup SocketAPI - Establishes a TCP connection with a remote server. - The asynchronous connect function must be called after receiving a valid socket ID from the @ref socket function. - The application socket callback function is notified of the result of the connection attempt through the event @ref SOCKET_MSG_CONNECT, - along with a structure @ref tstrSocketConnectMsg. - If socket connection fails, the application should call @ref close(). - A successful connect means the TCP session is active. The application is then required to make a call to the @ref recv - to receive any packets transmitted by the remote server, unless the application is interrupted by a notification of socket connection - termination. + Establishes a TCP connection with a remote server. + The asynchronous connect function must be called after receiving a valid socket ID from the @ref socket function. + The application socket callback function is notified of the result of the connection attempt through the event @ref SOCKET_MSG_CONNECT, + along with a structure @ref tstrSocketConnectMsg. + If socket connection fails, the application should call @ref close(). + A successful connect means the TCP session is active. The application is then required to make a call to the @ref recv + to receive any packets transmitted by the remote server, unless the application is interrupted by a notification of socket connection + termination. */ /**@{*/ /*! @@ -1397,9 +1571,9 @@ NMI_API sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8 Indicating passing invalid arguments such as negative socket ID or NULL socket address structure. - @ref SOCK_ERR_INVALID - Indicate socket connect failure. -\section connect example - The example demonstrates a TCP application, showing how the asynchronous call to the connect function is made through the main function and how the + Indicate socket connect failure. +\section connect_Ex Example + The example demonstrates a TCP application, showing how the asynchronous call to the connect function is made through the main function and how the callback function handles the @ref SOCKET_MSG_CONNECT event. Main Function @@ -1457,7 +1631,49 @@ Socket Callback @endcode */ NMI_API sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen); -/**@}*/ //AcceptFn + +/**@}*/ //ConnectFn + +/** @defgroup SecureFn secure + @ingroup SocketAPI + Converts an (insecure) TCP connection with a remote server into a secure TLS-over-TCP connection. + It may be called after both of the following:\n + - a TCP socket has been created by the @ref socket function, with u8Config parameter set to + @ref SOCKET_CONFIG_SSL_DELAY.\n + - a successful connection has been made on the socket via the @ref connect function. + This is an asynchronous API; the application socket callback function is notified of the result + of the attempt to make the connection secure through the event @ref SOCKET_MSG_SECURE, along + with a structure @ref tstrSocketConnectMsg. + If the attempt to make the connection secure fails, the application should call @ref close(). + */ +/**@{*/ +/*! +@fn \ + sint8 secure(SOCKET sock); + +@param[in] sock + Socket ID, corresponding to a connected TCP socket. + +@pre + @ref socket and @ref connect must be called to connect a TCP socket before passing the socket ID to this function. + Value @ref SOCKET_CONFIG_SSL_DELAY must have been set in the u8Config parameter that was passed to @ref socket. + +@see + socket + connect + +@return + The function returns SOCK_ERR_NO_ERROR for successful operations and a negative error value otherwise. + The possible error values are: + - @ref SOCK_ERR_INVALID_ARG + Indicating passing invalid arguments such as negative socket ID. + + - @ref SOCK_ERR_INVALID + Indicating failure to process the request. +*/ +sint8 secure(SOCKET sock); + +/**@}*/ //SecureFn /** @defgroup ReceiveFn recv @ingroup SocketAPI @@ -1517,9 +1733,9 @@ NMI_API sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, u Indicating passing invalid arguments such as negative socket ID or NULL Receive buffer. - @ref SOCK_ERR_BUFFER_FULL - Indicate socket receive failure. -\section recv example - The example demonstrates a code snippet for the calling of the recv function in the socket callback upon notification of the accept or connect events, and the parsing of the + Indicate socket receive failure. +\section recv_Ex Example + The example demonstrates a code snippet for the calling of the recv function in the socket callback upon notification of the accept or connect events, and the parsing of the received data when the @ref SOCKET_MSG_RECV event is received. @code switch(u8Msg) @@ -1623,9 +1839,9 @@ NMI_API sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16Buf Indicating passing invalid arguments such as negative socket ID or NULL Receive buffer. - @ref SOCK_ERR_BUFFER_FULL - Indicate socket receive failure. -\section recvfrom example - The example demonstrates a code snippet for the calling of the recvfrom function in the socket callback upon notification of a successful bind event, and the parsing of the + Indicate socket receive failure. +\section recvfrom_Ex Example + The example demonstrates a code snippet for the calling of the recvfrom function in the socket callback upon notification of a successful bind event, and the parsing of the received data when the @ref SOCKET_MSG_RECVFROM event is received. @code switch(u8Msg) @@ -1906,87 +2122,50 @@ NMI_API sint8 WINC1500_EXPORT(sslEnableCertExpirationCheck)(tenuSslCertExpSettin /** @defgroup SetSocketOptionFn setsockopt * @ingroup SocketAPI -*The setsockopt() function shall set the option specified by the option_name -* argument, at the protocol level specified by the level argument, to the value -* pointed to by the option_value argument for the socket specified by the socket argument. -* -*

Possible protocol level values supported are @ref SOL_SOCKET and @ref SOL_SSL_SOCKET. -* Possible options when the protocol level is @ref SOL_SOCKET :

-* -* -* -* -* -* -* -* -* -* -* -* -* -*
@ref SO_SET_UDP_SEND_CALLBACKEnable/Disable callback messages for sendto(). -* Since UDP is unreliable by default the user maybe interested (or not) in -* receiving a message of @ref SOCKET_MSG_SENDTO for each call of sendto(). -* Enabled if option value equals TRUE, disabled otherwise.
@ref IP_ADD_MEMBERSHIPValid for UDP sockets. This option is used to receive frames sent to -* a multicast group. option_value shall be a pointer to Unsigned 32-bit -* integer containing the multicast IPv4 address.
@ref IP_DROP_MEMBERSHIPValid for UDP sockets. This option is used to stop receiving frames -* sent to a multicast group. option_value shall be a pointer to Unsigned -* 32-bit integer containing the multicast IPv4 address.
-*

Possible options when the protocol level  is @ref SOL_SSL_SOCKET

-* -* -* -* -* -* -* -* -* -* -* -* -* -*
-* @ref SO_SSL_BYPASS_X509_VERIFAllow an opened SSL socket to bypass the X509 -* certificate verification process. It is highly recommended NOT to use -* this socket option in production software applications. The option is -* supported for debugging and testing purposes. The option value should be -* casted to int type and it is handled as a boolean flag.
@ref SO_SSL_SNISet the Server Name Indicator (SNI) for an SSL socket. The SNI is a -* null terminated string containing the server name associated with the -* connection. It must not exceed the size of @ref HOSTNAME_MAX_SIZE.
@ref SO_SSL_ENABLE_SESSION_CACHINGThis option allow the TLS to cache the session information for fast -* TLS session establishment in future connections using the TLS Protocol -* session resume features.
+ * The setsockopt() function shall set the option specified by the option_name + * argument, at the protocol level specified by the level argument, to the value + * pointed to by the option_value argument for the socket specified by the socket argument. */ - /**@{*/ +/**@{*/ /*! -@fn \ - NMI_API sint8 setsockopt(SOCKET socket, uint8 u8Level, uint8 option_name, +@fn \ + NMI_API sint8 setsockopt(SOCKET socket, uint8 u8Level, uint8 option_name, const void *option_value, uint16 u16OptionLen); -@param [in] socket - Socket handler. +@param[in] socket + Socket handler. -@param [in] u8Level - protocol level. See description above. +@param[in] u8Level + Protocol level.\n + Supported protocol levels are @ref SOL_SOCKET and @ref SOL_SSL_SOCKET. -@param [in] option_name - option to be set. See description above. +@param[in] option_name + Option to be set.\n + For protocol level @ref SOL_SOCKET, the supported option names are:\n + @ref SO_SET_UDP_SEND_CALLBACK\n + @ref SO_TCP_KEEPALIVE\n + @ref SO_TCP_KEEPIDLE\n + @ref SO_TCP_KEEPINTVL\n + @ref SO_TCP_KEEPCNT\n + For protocol level @ref SOL_SSL_SOCKET, the supported option names are:\n + @ref SO_SSL_BYPASS_X509_VERIF\n + @ref SO_SSL_SNI\n + @ref SO_SSL_ENABLE_SESSION_CACHING\n + @ref SO_SSL_ENABLE_SNI_VALIDATION\n + @ref SO_SSL_ALPN\n -@param [in] option_value - pointer to user provided value. +@param[in] option_value + Pointer to user provided value. -@param [in] u16OptionLen - length of the option value in bytes. +@param[in] u16OptionLen + Length of the option value in bytes. Refer to each option documentation for the required length. -@sa SOL_SOCKET, SOL_SSL_SOCKET, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP - -@return - The function shall return \ref SOCK_ERR_NO_ERROR for successful operation - and a negative value (indicating the error) otherwise. +@return + The function shall return \ref SOCK_ERR_NO_ERROR for successful operation + and a negative value (indicating the error) otherwise. */ NMI_API sint8 WINC1500_EXPORT(setsockopt)(SOCKET socket, uint8 u8Level, uint8 option_name, - const void *option_value, uint16 u16OptionLen); + const void *option_value, uint16 u16OptionLen); /**@}*/ //SetSocketOptionFn /** @defgroup GetSocketOptionsFn getsockopt @@ -1994,30 +2173,29 @@ NMI_API sint8 WINC1500_EXPORT(setsockopt)(SOCKET socket, uint8 u8Level, uint8 op * Get socket options retrieves * This Function isn't implemented yet but this is the form that will be released later. */ - /**@{*/ +/**@{*/ /*! -@fn \ - sint8 getsockopt(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 * pu8OptLen); +@fn \ + sint8 getsockopt(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 * pu8OptLen); @brief -@param [in] sock - Socket Identifier. -@param [in] u8Level - The protocol level of the option. -@param [in] u8OptName - The u8OptName argument specifies a single option to get. -@param [out] pvOptValue - The pvOptValue argument contains pointer to a buffer containing the option value. -@param [out] pu8OptLen - Option value buffer length. +@param[in] sock + Socket Identifier. +@param[in] u8Level + The protocol level of the option. +@param[in] u8OptName + The u8OptName argument specifies a single option to get. +@param[out] pvOptValue + The pvOptValue argument contains pointer to a buffer containing the option value. +@param[out] pu8OptLen + Option value buffer length. @return - The function shall return ZERO for successful operation and a negative value otherwise. + The function shall return ZERO for successful operation and a negative value otherwise. */ -NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8* pu8OptLen); +NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 *pu8OptLen); /**@}*/ //GetSocketOptionsFn -/**@}*/ /** @defgroup PingFn m2m_ping_req * @ingroup SocketAPI * The function sends ping request to the given IP Address. @@ -2035,13 +2213,123 @@ NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8Op @param [in] u8TTL IP TTL value for the ping request. If set to ZERO, the default value SHALL be used. -@param [in] fpPingCb - Callback will be called to deliver the ping statistics. +@param[in] fpPingCb + Callback will be called to deliver the ping statistics. -@see nmi_inet_addr -@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +@warning This API should only be used to request one ping at a time; calling this API invalidates callbacks + for previous ping requests. +@see nmi_inet_addr +@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. */ NMI_API sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb); + +/*! + * @fn sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList); + * + * 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) or securing (using @ref secure). + * + * @param[in] sock + * Socket ID obtained by a call to @ref socket. This is the SSL socket to which + * the ALPN list applies. + * + * @param[in] pcProtocolList + * Pointer to the list of protocols available in the application. \n + * The entries in the list must: \n + * - be separated with ' ' (space). \n + * - not contain ' ' (space) or '\0' (NUL). \n + * - be non-zero length. \n + * . + * The list itself must: \n + * - be terminated with '\0' (NUL). \n + * - be no longer than @ref ALPN_LIST_MAX_APP_LENGTH, including separators (spaces) and terminator (NUL). \n + * - contain at least one entry. + * + * @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + * + * \section SocketExample9 Example + * The example demonstrates an application using @ref set_alpn_list and @ref get_alpn_index to negotiate secure HTTP/2 + * (with fallback option of HTTP/1.1). + + * \subsection sub5 Main Function + * @code + * SOCKET TcpClientSocket = socket(AF_INET, SOCK_STREAM, SOCKET_CONFIG_SSL_ON); + * if (TcpClientSocket >= 0) + * { + * struct sockaddr_in Serv_Addr = { + * .sin_family = AF_INET, + * .sin_port = _htons(1234), + * .sin_addr.s_addr = inet_addr(SERVER) + * }; + * set_alpn_list(TcpClientSocket, "h2 http/1.1"); + * connect(TcpClientSocket, &Serv_Addr, sizeof(Serv_Addr)); + * } + * @endcode + * \subsection sub6 Socket Callback + * @code + * if(u8Msg == SOCKET_MSG_CONNECT) + * { + * tstrSocketConnectMsg *pstrConnect = (tstrSocketConnectMsg*)pvMsg; + * if(pstrConnect->s8Error == 0) + * { + * uint8 alpn_index = get_alpn_index(pstrConnect->sock); + * switch (alpn_index) + * { + * case 1: + * printf("Negotiated HTTP/2\n"); + * break; + * case 2: + * printf("Negotiated HTTP/1.1\n"); + * break; + * case 0: + * printf("Protocol negotiation did not occur\n"); + * break; + * } + * } + * } + * @endcode +*/ +sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList); +/*! + * @fn sint8 get_alpn_index(SOCKET sock); + * + * This function gets the index of the protocol negotiated via ALPN. + * It should be called when a SSL socket connection succeeds, in order to determine which + * application-layer protocol must be used. + * + * @param[in] sock + * Socket ID obtained by a call to @ref socket. This is the SSL socket to which + * the ALPN applies. + * + * @return The function returns:\n + * - >0: 1-based index of negotiated protocol with respect to the list previously provided to @ref set_alpn_list.\n + * - 0: No negotiation occurred (eg TLS peer did not support ALPN).\n + * - <0: Invalid parameters (socket is not in use, or not an SSL socket).\n + * + * @see @ref SocketExample9 +*/ +sint8 get_alpn_index(SOCKET sock); + +/*! + *@fn sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr); + * + * 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. + + * @param[in] sock + * Socket ID obtained by a call to @ref socket. + * + * @param[out] pstrErr + * Pointer to structure to be populated with the details of the socket failure. + * + * @return The function returns @ref SOCK_ERR_NO_ERROR if the request is successful. In this case pstrErr + * has been populated. + * The function returns a negative value if the request is not successful. In this case pstrErr + * has not been populated. +*/ +sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr); /**@}*/ //PingFn #ifdef __cplusplus diff --git a/src/drivers/winc1500/src/m2m_ota.c b/src/drivers/winc1500/src/m2m_ota.c index 5f0bcc158..3c691f013 100644 --- a/src/drivers/winc1500/src/m2m_ota.c +++ b/src/drivers/winc1500/src/m2m_ota.c @@ -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); - } - else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE) + gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz); + } + 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 - Period in days - -@return - The function SHALL return 0 for success and a negative value otherwise. +@fn NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period) +@brief Schedule OTA update. +@param[in] u32Period + Period in days +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. */ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period) { @@ -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 - 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. +@return Status of the read operation. +@warning Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special + mode to allow for a safe access to the Flash. This can be done by calling + @ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read. */ NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size) { static uint32 u32FlashHFDStart = 0; static uint32 u32FlashHFDSize = 0; sint8 s8Ret = M2M_ERR_INVALID_ARG; - if((u8Handler != 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,9 +467,13 @@ 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)) + (u32Size > u32FlashHFDSize) || + ((u32Offset + u32Size) >= u32FlashHFDSize)) { s8Ret = M2M_ERR_FAIL; goto EXIT; @@ -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) { diff --git a/src/drivers/winc1500/src/m2m_periph.c b/src/drivers/winc1500/src/m2m_periph.c index b58d5c406..be6e2ff0e 100644 --- a/src/drivers/winc1500/src/m2m_periph.c +++ b/src/drivers/winc1500/src/m2m_periph.c @@ -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,95 +56,52 @@ 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; + if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) goto _EXIT1; - gpio = get_gpio_idx(u8GpioNum); - if(gpio < 0) goto _EXIT1; - - if(op == GPIO_OP_DIR) { - ret = set_gpio_dir((uint8)gpio, u8InVal); - } else if(op == GPIO_OP_SET) { - ret = set_gpio_val((uint8)gpio, u8InVal); - } else if(op == GPIO_OP_GET) { - ret = get_gpio_val((uint8)gpio, pu8OutVal); - } - if(ret != M2M_SUCCESS) goto _EXIT1; + if(op == GPIO_OP_DIR) { + s8Ret = set_gpio_dir(u8GpioNum, u8InVal); + } else if(op == GPIO_OP_SET) { + s8Ret = set_gpio_val(u8GpioNum, u8InVal); + } else if(op == GPIO_OP_GET) { + s8Ret = get_gpio_val(u8GpioNum, pu8OutVal); + } _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); + return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL); } sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal) { - return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL); + return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL); } sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal) { - return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, 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); + return pullup_ctrl(pinmask, enable); } #endif /* CONF_PERIPH */ diff --git a/src/drivers/winc1500/src/m2m_ssl.c b/src/drivers/winc1500/src/m2m_ssl.c index 79b0dfb48..3c7ed3213 100644 --- a/src/drivers/winc1500/src/m2m_ssl.c +++ b/src/drivers/winc1500/src/m2m_ssl.c @@ -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 * @@ -53,8 +53,8 @@ MACROS /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* DATA TYPES *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ -static tpfAppSSLCb gpfAppSSLCb = NULL; -static uint32 gu32HIFAddr = 0; +static tpfAppSSLCb gpfAppSSLCb = NULL; +static uint32 gu32HIFAddr = 0; static tenuTlsFlashStatus genuStatus = TLS_FLASH_ERR_UNKNOWN; /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* @@ -62,348 +62,443 @@ FUNCTION PROTOTYPES *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ /*! - @fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr) - @brief SSL callback function - @param [in] u8OpCode - HIF Opcode type. - @param [in] u16DataSize - HIF data length. - @param [in] u32Addr - HIF address. +@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 + HIF data length. +@param [in] u32Addr + HIF address. */ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr) { - sint8 s8tmp = M2M_SUCCESS; - switch(u8OpCode) - { - case M2M_SSL_REQ_ECC: - { - tstrEccReqInfo strEccREQ; - s8tmp = hif_receive(u32Addr, (uint8*)&strEccREQ, sizeof(tstrEccReqInfo), 0); - if(s8tmp == M2M_SUCCESS) - { - if (gpfAppSSLCb) - { - gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo); - gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ); - } - } - } - break; - case M2M_SSL_RESP_SET_CS_LIST: - { - tstrSslSetActiveCsList strCsList; - s8tmp = hif_receive(u32Addr, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), 0); - if(s8tmp == M2M_SUCCESS) - { - if (gpfAppSSLCb) - gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList); - } - } - break; - case M2M_SSL_RESP_WRITE_OWN_CERTS: - { - tstrTlsSrvChunkHdr strTlsSrvChunkRsp; - uint8 bCallApp = 1; + sint8 s8tmp = M2M_SUCCESS; + switch(u8OpCode) + { + case M2M_SSL_REQ_ECC: + { + tstrEccReqInfo strEccREQ; + s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0); + if(s8tmp == M2M_SUCCESS) + { + if(gpfAppSSLCb) + { + gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo); + gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ); + } + } + } + break; + case M2M_SSL_RESP_SET_CS_LIST: + { + tstrSslSetActiveCsList strCsList; + s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0); + if(s8tmp == M2M_SUCCESS) + { + if(gpfAppSSLCb) + gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList); + } + } + break; + case M2M_SSL_RESP_WRITE_OWN_CERTS: + { + tstrTlsSrvChunkHdr strTlsSrvChunkRsp; + uint8 bCallApp = 1; - s8tmp = hif_receive(u32Addr, (uint8*)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0); - if(s8tmp == M2M_SUCCESS) - { - uint16 offset = strTlsSrvChunkRsp.u16Offset32; - uint16 chunk_size = strTlsSrvChunkRsp.u16Size32; - uint16 total_size = strTlsSrvChunkRsp.u16TotalSize32; - tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig); - - /* If first chunk, reset status. */ - if (offset == 0) - genuStatus = TLS_FLASH_OK_NO_CHANGE; - /* Only send status to app when processing last chunk. */ - if (offset + chunk_size != total_size) - bCallApp = 0; + s8tmp = hif_receive(u32Addr, (uint8 *)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0); + if(s8tmp == M2M_SUCCESS) + { + uint16 offset = strTlsSrvChunkRsp.u16Offset32; + uint16 chunk_size = strTlsSrvChunkRsp.u16Size32; + uint16 total_size = strTlsSrvChunkRsp.u16TotalSize32; + tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig); - switch (status) - { - case TLS_FLASH_OK: - // Good flash write. Update status if no errors yet. - if (genuStatus == TLS_FLASH_OK_NO_CHANGE) - genuStatus = status; - break; - case TLS_FLASH_OK_NO_CHANGE: - // No change, don't update status. - break; - case TLS_FLASH_ERR_CORRUPT: - // Corrupt. Always update status. - genuStatus = status; - 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)) - 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) - genuStatus = TLS_FLASH_ERR_UNKNOWN; - break; - } - } - if (bCallApp && gpfAppSSLCb) - gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus); - } - break; - } - if(s8tmp != M2M_SUCCESS) - { - M2M_ERR("Error receiving SSL from the HIF\n"); - } -} + /* If first chunk, reset status. */ + if(offset == 0) + genuStatus = TLS_FLASH_OK_NO_CHANGE; + /* Only send status to app when processing last chunk. */ + if(offset + chunk_size != total_size) + bCallApp = 0; - -/*! - @fn \ 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 - Pointer of the response data to be sent. - @param [in] u16RspDataSz - Response data size. - @return The function SHALL return 0 for success and a negative value otherwise. -*/ -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)); - - return s8Ret; + switch(status) + { + case TLS_FLASH_OK: + // Good flash write. Update status if no errors yet. + if(genuStatus == TLS_FLASH_OK_NO_CHANGE) + genuStatus = status; + break; + case TLS_FLASH_OK_NO_CHANGE: + // No change, don't update status. + break; + case TLS_FLASH_ERR_CORRUPT: + // Corrupt. Always update status. + genuStatus = status; + 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)) + 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) + genuStatus = TLS_FLASH_ERR_UNKNOWN; + break; + } + } + if(bCallApp && gpfAppSSLCb) + gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus); + } + break; + } + if(s8tmp != M2M_SUCCESS) + { + M2M_ERR("Error receiving SSL from the HIF\n"); + } } /*! - @fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size) - @brief Sends certificates to the WINC - @param [in] pu8Buffer - Pointer to the certificates. - @param [in] u32BufferSz - Size of the certificates. - @return The function SHALL return 0 for success and a negative value otherwise. -*/ -NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz) -{ - sint8 s8Ret = M2M_SUCCESS; - #define TXLIMIT (256 * 6) - - if(u32BufferSz <= TXLIMIT) - { - // set chunk header for one chunk - tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)pu8Buffer; - pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE; - pchkhdr->u16TotalSize32 = (u32BufferSz + 3) >> 2; - pchkhdr->u16Offset32 = 0; - pchkhdr->u16Size32 = (u32BufferSz + 3) >> 2; - s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0); - M2M_INFO("Transferred %lu bytes of cert data NON-CHUNKED\n", u32BufferSz); - } - else - { - // chunk it - // We are sneaking in a header - tstrTlsSrvChunkHdr - #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]; - 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_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ); - ofs += thischunksz; - - 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 = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length - pchkhdr = (tstrTlsSrvChunkHdr*)&pu8Buffer[ofs - CHUNKHDRSZ]; - 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_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ); - ofs += thischunksz; - } - } - - return s8Ret; -} - -/*! - @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. -*/ -NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key) -{ - uint8 bSetRxDone = 1; - 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; - gu32HIFAddr += 2; - - if(hif_receive(gu32HIFAddr, (uint8*)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR; - 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); - u16HashSz = _htons(u16HashSz); - u16SigSz = _htons(u16SigSz); - - if(hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS) goto __ERR; - gu32HIFAddr += (pu8Key->u16Size * 2); - - if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR; - gu32HIFAddr += u16HashSz; - - if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR; - gu32HIFAddr += u16SigSz; - - bSetRxDone = 0; - -__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. -*/ -NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz) -{ - uint8 bSetRxDone = 1; - sint8 s8Ret = M2M_SUCCESS; - - if(gu32HIFAddr == 0) return M2M_ERR_FAIL; - - if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR; - - bSetRxDone = 0; - -__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 -*/ -NMI_API void m2m_ssl_stop_processing_certs(void) -{ - hif_receive(0, NULL, 0, 1); -} - -/*! - @fn \ m2m_ssl_ecc_process_done(void) - @brief Stops receiving from the HIF -*/ -NMI_API void m2m_ssl_ecc_process_done(void) -{ - gu32HIFAddr = 0; -} - -/*! -@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 - 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. - -@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. - If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not - be changed. - -@return - - [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR) - - [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG) -*/ -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); - - 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. +@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; + 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 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] pu8RspDataBuff + Pointer of the response data to be sent. +@param[in] u16RspDataSz + Response data size. +@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) +{ + 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)); + + return s8Ret; +} + +/*! +@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 + Size of the certificates. +@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) +{ + sint8 s8Ret = M2M_SUCCESS; +#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; + pchkhdr->u16Size32 = (u32BufferSz + 3) >> 2; + s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0); + M2M_INFO("Transferred %lu bytes of cert data NON-CHUNKED\n", u32BufferSz); + } + else + { + // chunk it + // We are sneaking in a header - tstrTlsSrvChunkHdr +#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 +#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 %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) + { + // Subsequent chunks write header before and send a little more + m2m_memcpy(saveblob, &pu8Buffer[ofs-CHUNKHDRSZ], CHUNKHDRSZ); + thischunksz = min(CHUNKSZ, u32BufferSz-ofs); + thischunksz = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length +#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 %u total %u\n", thischunksz, ofs, u32BufferSz); + m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ); + ofs += thischunksz; + } + } + + return s8Ret; +} + +/*! +@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_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey) +{ + sint8 s8Ret = M2M_ERR_FAIL; + uint16 u16HashSz, u16SigSz, u16KeySz; + + if(gu32HIFAddr == 0) return M2M_ERR_FAIL; + + 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; + 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; + 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, 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, pu8Value, u16HashSz, 0) != M2M_SUCCESS) goto __ERR; + gu32HIFAddr += u16HashSz; + + if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR; + gu32HIFAddr += u16SigSz; + + return M2M_SUCCESS; + +__ERR: + hif_receive(0, NULL, 0, 1); + return s8Ret; +} + +/*! +@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_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey) +{ + 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(NULL == pu8Value) + { + s8Ret = M2M_ERR_INVALID_ARG; + goto __ERR; + } + + if(hif_receive(gu32HIFAddr, pu8Value, u16ValueSz, 0) != M2M_SUCCESS) goto __ERR; + + return M2M_SUCCESS; + +__ERR: + hif_receive(0, NULL, 0, 1); + return s8Ret; +} + +/*! +@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) +{ + hif_receive(0, NULL, 0, 1); +} + +/*! +@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) +{ + gu32HIFAddr = 0; +} + +/*! +@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. + +@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. + 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 +*/ +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); + + return s8Ret; } diff --git a/src/drivers/winc1500/src/m2m_wifi.c b/src/drivers/winc1500/src/m2m_wifi.c index 643d8b067..58b31098a 100644 --- a/src/drivers/winc1500/src/m2m_wifi.c +++ b/src/drivers/winc1500/src/m2m_wifi.c @@ -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 * @@ -44,12 +44,35 @@ * * \{ */ + +/* 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 gu8WifiState = WIFI_STATE_DEINIT; static volatile uint8 gu8ChNum; +static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT; +static tpfAppWifiCb gpfAppWifiCb = NULL; static volatile uint8 gu8scanInProgress = 0; -static tpfAppWifiCb gpfAppWifiCb = NULL; +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) { @@ -614,39 +634,9 @@ static sint8 m2m_wifi_connect_prepare_msg( } return ret; INVALID_ARG: - return M2M_ERR_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)); - } - } - return ret; - } + 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,44 +719,173 @@ sint8 m2m_wifi_connect_psk( pstrNetworkId, &strConnHdr); - if (ret == M2M_SUCCESS) - { - tstrM2mWifiPsk pstrPsk; - m2m_memset((uint8*)&pstrPsk, 0, sizeof(tstrM2mWifiPsk)); - if (pstrAuthPsk->pu8Psk != NULL) + if(ret == M2M_SUCCESS) + { + tstrM2mWifiPsk *pstrPsk = (tstrM2mWifiPsk *)fb_alloc(sizeof(tstrM2mWifiPsk), 0); + if(pstrPsk != NULL) { - if (pstrAuthPsk->pu8Passphrase != NULL) - ret = M2M_ERR_INVALID_ARG; - else + m2m_memset((uint8 *)pstrPsk, 0, sizeof(tstrM2mWifiPsk)); + if(pstrAuthPsk->pu8Psk != NULL) { - 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(pstrAuthPsk->pu8Passphrase != NULL) ret = M2M_ERR_INVALID_ARG; - m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen); + else + { + 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)) + ret = M2M_ERR_INVALID_ARG; + m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen); + } } - } - else if (pstrAuthPsk->pu8Passphrase != NULL) - { - if (pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1) - ret = M2M_ERR_INVALID_ARG; - else + else if(pstrAuthPsk->pu8Passphrase != NULL) { - pstrPsk.u8PassphraseLen = pstrAuthPsk->u8PassphraseLen; - m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk.u8PassphraseLen); + 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); + } } + else + ret = M2M_ERR_INVALID_ARG; + 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)); + } + fb_free(); } else - ret = M2M_ERR_INVALID_ARG; - 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 = M2M_ERR_MEM_ALLOC; } - } - return ret; + } + 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( @@ -807,32 +932,38 @@ sint8 m2m_wifi_connect_1x_mschap2( if (pstrAuth1xMschap2->bPrependDomain == true) pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG; - pstr1xHdr->u8DomainLength = 0; - if (pstrAuth1xMschap2->pu8Domain != NULL) - { - pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xMschap2->u16DomainLen); - m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, pstr1xHdr->u8DomainLength); - pu8AuthPtr += pstr1xHdr->u8DomainLength; - } + pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr); + pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags; + m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1)); - pstr1xHdr->u16UserNameLength = (pstrAuth1xMschap2->u16UserNameLen); - m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u16UserNameLength); - pu8AuthPtr += pstr1xHdr->u16UserNameLength; + pstr1xHdr->u8DomainLength = 0; + if(pstrAuth1xMschap2->pu8Domain != NULL) + { + pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xMschap2->u16DomainLen); + m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, pstr1xHdr->u8DomainLength); + pu8AuthPtr += pstr1xHdr->u8DomainLength; + } - pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails; - pstr1xHdr->u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen; - m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Password, pstr1xHdr->u16PrivateKeyLength); + pstr1xHdr->u8UserNameLength = (pstrAuth1xMschap2->u16UserNameLen); + m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u8UserNameLength); + pu8AuthPtr += pstr1xHdr->u8UserNameLength; - 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(); - } - } - } - } - return ret; + 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, + sizeof(tstrM2mWifiConnHdr)); + fb_free(); + } + else + ret = M2M_ERR_MEM_ALLOC; + } + } + } + return ret; } sint8 m2m_wifi_connect_1x_tls( @@ -886,49 +1017,55 @@ tstrAuth1xTls *pstrAuth1xTls if (pstrAuth1xTls->bPrependDomain == true) pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG; - pstr1xHdr->u8DomainLength = 0; - if (pstrAuth1xTls->pu8Domain != NULL) - { - pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xTls->u16DomainLen); - m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, pstr1xHdr->u8DomainLength); - pu8AuthPtr += pstr1xHdr->u8DomainLength; - } + pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr); + pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags; + m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1)); - pstr1xHdr->u16UserNameLength = (pstrAuth1xTls->u16UserNameLen); - m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u16UserNameLength); - pu8AuthPtr += pstr1xHdr->u16UserNameLength; + pstr1xHdr->u8DomainLength = 0; + if(pstrAuth1xTls->pu8Domain != NULL) + { + pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xTls->u16DomainLen); + m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, pstr1xHdr->u8DomainLength); + pu8AuthPtr += pstr1xHdr->u8DomainLength; + } - pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails; - pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen; - m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Mod, pstr1xHdr->u16PrivateKeyLength); - pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength; - m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Exp, pstr1xHdr->u16PrivateKeyLength); - pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength; + pstr1xHdr->u8UserNameLength = (pstrAuth1xTls->u16UserNameLen); + m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u8UserNameLength); + pu8AuthPtr += pstr1xHdr->u8UserNameLength; - pstr1xHdr->u16CertificateOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails; - pstr1xHdr->u16CertificateLength = pstrAuth1xTls->u16CertificateLen; + pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails; + pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen; + m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Mod, pstr1xHdr->u16PrivateKeyLength); + pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength; + m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Exp, pstr1xHdr->u16PrivateKeyLength); + pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength; - 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), - pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen, - sizeof(tstrM2mWifiAuthInfoHdr)); + pstr1xHdr->u16CertificateOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails; + pstr1xHdr->u16CertificateLength = pstrAuth1xTls->u16CertificateLen; - 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, - sizeof(tstrM2mWifiConnHdr)); - } - fb_free(); - } - } - } - } - return ret; + 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), + pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen, + sizeof(tstrM2mWifiAuthInfoHdr)); + + 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, + sizeof(tstrM2mWifiConnHdr)); + } + fb_free(); + } + else + ret = M2M_ERR_MEM_ALLOC; + } + } + } + return ret; } sint8 m2m_wifi_connect(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *pvAuthInfo, uint16 u16Ch) @@ -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. -@sa m2m_wifi_req_server_init, M2M_WIFI_RESP_CLIENT_INFO -@pre m2m_wifi_req_server_init should be called first -@warning +@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 */ 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 - Server listening channel -@return The function SHALL return 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) +@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 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/AP). */ sint8 m2m_wifi_req_server_init(uint8 ch) { @@ -1479,10 +1638,10 @@ sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn) return ret; } /*! -@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). -@param [in] u32SlpReqTime - Request Sleep in ms +@fn NMI_API sint8 m2m_wifi_request_sleep(void) +@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. @sa tenuPowerSaveModes , m2m_wifi_set_sleep_mode @warning the Function should be called in M2M_PS_MANUAL power save only @@ -1501,14 +1660,14 @@ sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime) return ret; } /*! -@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. -@param [in] pu8DeviceName - Buffer holding the device name. -@param [in] u8DeviceNameLength - Length of the device name. -@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise. -@warning The Function called once after initialization. +@fn NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength); +@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 + Length of the device name. +@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise. +@warning The Function called once after initialization. */ sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength) { @@ -1754,19 +1913,22 @@ sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100) */ 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)) - { - 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); - } - else - { - M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n",u16PrngSize); - } - return ret; + sint8 ret = M2M_ERR_FAIL; + tstrPrng strRng = {0}; + 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); + } + else + { + 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; + } +} diff --git a/src/drivers/winc1500/src/nm_bus_wrapper.c b/src/drivers/winc1500/src/nm_bus_wrapper.c index 4e78f4f7e..1cd5b0f29 100644 --- a/src/drivers/winc1500/src/nm_bus_wrapper.c +++ b/src/drivers/winc1500/src/nm_bus_wrapper.c @@ -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: diff --git a/src/drivers/winc1500/src/nm_common.c b/src/drivers/winc1500/src/nm_common.c index c626aca14..ce4ad1dc6 100644 --- a/src/drivers/winc1500/src/nm_common.c +++ b/src/drivers/winc1500/src/nm_common.c @@ -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; +} diff --git a/src/drivers/winc1500/src/nmspi.c b/src/drivers/winc1500/src/nmspi.c index 0a3167f7d..a3a4df27a 100644 --- a/src/drivers/winc1500/src/nmspi.c +++ b/src/drivers/winc1500/src/nmspi.c @@ -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); + 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) + { + M2M_ERR("[nmi spi]: Failed repeated reset\n"); + return N_FAIL; } - } 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 - { - int jj; - printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2); - for(jj=0; 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]); - } - } - printk("\n"); - - for(jj=0; 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, ®)) { + if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, ®) != 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, ®)){ + if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, ®) != 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 diff --git a/src/drivers/winc1500/src/nmuart.c b/src/drivers/winc1500/src/nmuart.c index 308a8da5a..39b8e6d43 100644 --- a/src/drivers/winc1500/src/nmuart.c +++ b/src/drivers/winc1500/src/nmuart.c @@ -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 diff --git a/src/drivers/winc1500/src/socket.c b/src/drivers/winc1500/src/socket.c index ae1df5cc0..d5de7a60e 100644 --- a/src/drivers/winc1500/src/socket.c +++ b/src/drivers/winc1500/src/socket.c @@ -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 * @@ -63,13 +63,14 @@ MACROS hif_send(M2M_REQ_GROUP_IP, reqID, reqArgs, reqSize, reqPayload, reqPayloadSize, reqPayloadOffset) -#define SSL_FLAGS_ACTIVE NBIT0 -#define SSL_FLAGS_BYPASS_X509 NBIT1 -#define SSL_FLAGS_2_RESERVD NBIT2 -#define SSL_FLAGS_3_RESERVD NBIT3 -#define SSL_FLAGS_CACHE_SESSION NBIT4 -#define SSL_FLAGS_NO_TX_COPY NBIT5 -#define SSL_FLAGS_CHECK_SNI NBIT6 +#define SSL_FLAGS_ACTIVE NBIT0 +#define SSL_FLAGS_BYPASS_X509 NBIT1 +#define SSL_FLAGS_2_RESERVD NBIT2 +#define SSL_FLAGS_3_RESERVD NBIT3 +#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,15 +90,18 @@ typedef struct{ /*! * @brief */ -typedef struct{ - uint8 *pu8UserBuffer; - uint16 u16UserBufferSize; - uint16 u16SessionID; - uint16 u16DataOffset; - uint8 bIsUsed; - uint8 u8SSLFlags; - uint8 bIsRecvPending; -}tstrSocket; +typedef struct { + uint8 *pu8UserBuffer; + uint16 u16UserBufferSize; + uint16 u16SessionID; + uint16 u16DataOffset; + uint8 bIsUsed; + uint8 u8SSLFlags; + uint8 bIsRecvPending; + uint8 u8AlpnStatus; + uint8 u8ErrSource; + uint8 u8ErrCode; +} tstrSocket; /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* GLOBALS @@ -109,10 +113,12 @@ volatile uint8 gu8OpCode; volatile uint16 gu16BufferSize; volatile uint16 gu16SessionID = 0; -volatile tpfAppSocketCb gpfAppSocketCb; -volatile tpfAppResolveCb gpfAppResolveCb; -volatile uint8 gbSocketInit = 0; -volatile tpfPingCb gfpPingCb; +volatile tpfAppSocketCb gpfAppSocketCb; +volatile tpfAppResolveCb gpfAppResolveCb; +volatile uint8 gbSocketInit = 0; + +static tpfPingCb gfpPingCb = NULL; +static uint32 gu32PingId = 0; /********************************************************************* Function @@ -144,47 +150,49 @@ NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint sint16 s16Diff; uint8 u8SetRxDone; - pstrRecv->u16RemainingSize = u16ReadCount; - do - { - u8SetRxDone = 1; - u16Read = u16ReadCount; - s16Diff = u16Read - gastrSockets[sock].u16UserBufferSize; - if(s16Diff > 0) - { - u8SetRxDone = 0; - u16Read = gastrSockets[sock].u16UserBufferSize; - } - - if(hif_receive(u32Address, gastrSockets[sock].pu8UserBuffer, u16Read, u8SetRxDone) == M2M_SUCCESS) - { - pstrRecv->pu8Buffer = gastrSockets[sock].pu8UserBuffer; - pstrRecv->s16BufferSize = u16Read; - pstrRecv->u16RemainingSize -= u16Read; + pstrRecv->u16RemainingSize = u16ReadCount; + do + { + u8SetRxDone = 1; + u16Read = u16ReadCount; + 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; + } - if (gpfAppSocketCb) - gpfAppSocketCb(sock,u8SocketMsg, pstrRecv); + if(hif_receive(u32Address, gastrSockets[sock].pu8UserBuffer, u16Read, u8SetRxDone) == M2M_SUCCESS) + { + pstrRecv->pu8Buffer = gastrSockets[sock].pu8UserBuffer; + pstrRecv->s16BufferSize = u16Read; + pstrRecv->u16RemainingSize -= u16Read; - u16ReadCount -= u16Read; - u32Address += u16Read; + if(gpfAppSocketCb) + gpfAppSocketCb(sock, u8SocketMsg, pstrRecv); - if((!gastrSockets[sock].bIsUsed) && (u16ReadCount)) - { - M2M_DBG("Application Closed Socket While Rx Is not Complete\n"); - if(hif_receive(0, NULL, 0, 1) == M2M_SUCCESS) - M2M_DBG("hif_receive Success\n"); - else - M2M_DBG("hif_receive Fail\n"); - break; - } - } - else - { - M2M_INFO("(ERRR)Current <%d>\n", u16ReadCount); - break; - } - }while(u16ReadCount != 0); - } + u16ReadCount -= u16Read; + u32Address += u16Read; + + if((!gastrSockets[sock].bIsUsed) && (u16ReadCount)) + { + M2M_DBG("Application Closed Socket While Rx Is not Complete\n"); + if(hif_receive(0, NULL, 0, 1) == M2M_SUCCESS) + M2M_DBG("hif_receive Success\n"); + else + M2M_DBG("hif_receive Fail\n"); + break; + } + } + else + { + M2M_INFO("(ERRR)Current <%d>\n", u16ReadCount); + break; + } + } while(u16ReadCount != 0); + } } /********************************************************************* Function @@ -213,35 +221,35 @@ 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) - { - strBind.status = strBindReply.s8Status; - if(gpfAppSocketCb) - 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) - { - strListen.status = strListenReply.s8Status; - if(gpfAppSocketCb) - 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(strAcceptReply.sConnectedSock >= 0) - { - gastrSockets[strAcceptReply.sConnectedSock].u8SSLFlags = gastrSockets[strAcceptReply.sListenSock].u8SSLFlags; - gastrSockets[strAcceptReply.sConnectedSock].bIsUsed = 1; - gastrSockets[strAcceptReply.sConnectedSock].u16DataOffset = strAcceptReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET; + if(hif_receive(u32Address, (uint8 *)&strBindReply, sizeof(tstrBindReply), 0) == M2M_SUCCESS) + { + strBind.status = strBindReply.s8Status; + if(gpfAppSocketCb) + 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) + { + strListen.status = strListenReply.s8Status; + if(gpfAppSocketCb) + 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((strAcceptReply.sConnectedSock >= 0) && (strAcceptReply.sConnectedSock < MAX_SOCKET)) + { + gastrSockets[strAcceptReply.sConnectedSock].u8SSLFlags = gastrSockets[strAcceptReply.sListenSock].u8SSLFlags; + gastrSockets[strAcceptReply.sConnectedSock].bIsUsed = 1; + gastrSockets[strAcceptReply.sConnectedSock].u16DataOffset = strAcceptReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET; /* The session ID is used to distinguish different socket connections by comparing the assigned session ID to the one reported by the firmware*/ @@ -249,61 +257,85 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address) if(gu16SessionID == 0) ++gu16SessionID; - gastrSockets[strAcceptReply.sConnectedSock].u16SessionID = gu16SessionID; - M2M_DBG("Socket %d session ID = %d\r\n",strAcceptReply.sConnectedSock , gu16SessionID ); - } - strAccept.sock = strAcceptReply.sConnectedSock; - strAccept.strAddr.sin_family = AF_INET; - strAccept.strAddr.sin_port = strAcceptReply.strAddr.u16Port; - strAccept.strAddr.sin_addr.s_addr = strAcceptReply.strAddr.u32IPAddr; - if(gpfAppSocketCb) - gpfAppSocketCb(strAcceptReply.sListenSock, SOCKET_MSG_ACCEPT, &strAccept); - } - } - else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT)) - { - tstrConnectReply strConnectReply; - tstrSocketConnectMsg strConnMsg; - if(hif_receive(u32Address, (uint8*)&strConnectReply, sizeof(tstrConnectReply), 0) == M2M_SUCCESS) - { - strConnMsg.sock = strConnectReply.sock; - strConnMsg.s8Error = strConnectReply.s8Error; - if(strConnectReply.s8Error == SOCK_ERR_NO_ERROR) - { - gastrSockets[strConnectReply.sock].u16DataOffset = strConnectReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET; - } - if(gpfAppSocketCb) - gpfAppSocketCb(strConnectReply.sock,SOCKET_MSG_CONNECT, &strConnMsg); - } - } - else if(u8OpCode == SOCKET_CMD_DNS_RESOLVE) - { - tstrDnsReply strDnsReply; - if(hif_receive(u32Address, (uint8*)&strDnsReply, sizeof(tstrDnsReply), 0) == M2M_SUCCESS) - { - if(gpfAppResolveCb) - gpfAppResolveCb((uint8*)strDnsReply.acHostName, strDnsReply.u32HostIP); - } - } - else if((u8OpCode == SOCKET_CMD_RECV) || (u8OpCode == SOCKET_CMD_RECVFROM) || (u8OpCode == SOCKET_CMD_SSL_RECV)) - { - SOCKET sock; - sint16 s16RecvStatus; - tstrRecvReply strRecvReply; - uint16 u16ReadSize; - tstrSocketRecvMsg strRecvMsg; - uint8 u8CallbackMsgID = SOCKET_MSG_RECV; - uint16 u16DataOffset; + gastrSockets[strAcceptReply.sConnectedSock].u16SessionID = gu16SessionID; + M2M_DBG("Socket %d session ID = %d\r\n", strAcceptReply.sConnectedSock, gu16SessionID); + } + strAccept.sock = strAcceptReply.sConnectedSock; + strAccept.strAddr.sin_family = AF_INET; + strAccept.strAddr.sin_port = strAcceptReply.strAddr.u16Port; + strAccept.strAddr.sin_addr.s_addr = strAcceptReply.strAddr.u32IPAddr; + if(gpfAppSocketCb) + gpfAppSocketCb(strAcceptReply.sListenSock, SOCKET_MSG_ACCEPT, &strAccept); + } + } + else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT_ALPN)) + { + /* Note that for successful connections the fw always sends SOCKET_CMD_CONNECT, even for SSL connections. */ + tstrConnectAlpnReply strConnectAlpnReply = {{0}}; + tstrSocketConnectMsg strConnMsg; + uint16 u16HifSz = sizeof(tstrConnectAlpnReply); + if(u8OpCode != SOCKET_CMD_SSL_CONNECT_ALPN) + u16HifSz = sizeof(tstrConnectReply); + if(hif_receive(u32Address, (uint8*)&strConnectAlpnReply, u16HifSz, 0) == M2M_SUCCESS) + { + if((strConnectAlpnReply.strConnReply.sock >= 0) && (strConnectAlpnReply.strConnReply.sock < MAX_SOCKET)) + { + 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(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(gpfAppResolveCb) + gpfAppResolveCb((uint8 *)strDnsReply.acHostName, strDnsReply.u32HostIP); + } + } + else if((u8OpCode == SOCKET_CMD_RECV) || (u8OpCode == SOCKET_CMD_RECVFROM) || (u8OpCode == SOCKET_CMD_SSL_RECV)) + { + SOCKET sock; + sint16 s16RecvStatus; + tstrRecvReply strRecvReply; + uint16 u16ReadSize; + tstrSocketRecvMsg strRecvMsg; + uint8 u8CallbackMsgID = SOCKET_MSG_RECV; + uint16 u16DataOffset; if(u8OpCode == SOCKET_CMD_RECVFROM) u8CallbackMsgID = SOCKET_MSG_RECVFROM; - /* Read RECV REPLY data structure. - */ - u16ReadSize = sizeof(tstrRecvReply); - if(hif_receive(u32Address, (uint8*)&strRecvReply, u16ReadSize, 0) == M2M_SUCCESS) - { - uint16 u16SessionID = 0; + /* Read RECV REPLY data structure. + */ + u16ReadSize = sizeof(tstrRecvReply); + if(hif_receive(u32Address, (uint8 *)&strRecvReply, u16ReadSize, 0) == M2M_SUCCESS) + { + if((strRecvReply.sock >= 0) && (strRecvReply.sock < MAX_SOCKET)) + { + uint16 u16SessionID = 0; sock = strRecvReply.sock; u16SessionID = strRecvReply.u16SessionID; @@ -326,79 +358,83 @@ 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. - */ - u16ReadSize = (uint16)s16RecvStatus; - Socket_ReadSocketData(sock, &strRecvMsg, u8CallbackMsgID, u32Address, u16ReadSize); - } - else - { - /* Don't tidy up here. Application must call close(). - */ - strRecvMsg.s16BufferSize = s16RecvStatus; - strRecvMsg.pu8Buffer = NULL; - if(gpfAppSocketCb) - gpfAppSocketCb(sock,u8CallbackMsgID, &strRecvMsg); - } - } - else - { - 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) - M2M_DBG("hif_receive Success\n"); - else - M2M_DBG("hif_receive Fail\n"); - } - } - } - } - else if((u8OpCode == SOCKET_CMD_SEND) || (u8OpCode == SOCKET_CMD_SENDTO) || (u8OpCode == SOCKET_CMD_SSL_SEND)) - { - SOCKET sock; - sint16 s16Rcvd; - tstrSendReply strReply; - uint8 u8CallbackMsgID = SOCKET_MSG_SEND; + /* Read the Application data and deliver it to the application callback in + 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); + } + else + { + /* Don't tidy up here. Application must call close(). + */ + strRecvMsg.s16BufferSize = s16RecvStatus; + strRecvMsg.pu8Buffer = NULL; + if(gpfAppSocketCb) + gpfAppSocketCb(sock, u8CallbackMsgID, &strRecvMsg); + } + } + else + { + 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) + M2M_DBG("hif_receive Success\n"); + else + M2M_DBG("hif_receive Fail\n"); + } + } + } + } + } + else if((u8OpCode == SOCKET_CMD_SEND) || (u8OpCode == SOCKET_CMD_SENDTO) || (u8OpCode == SOCKET_CMD_SSL_SEND)) + { + SOCKET sock; + sint16 s16Rcvd; + tstrSendReply strReply; + uint8 u8CallbackMsgID = SOCKET_MSG_SEND; - if(u8OpCode == SOCKET_CMD_SENDTO) - u8CallbackMsgID = SOCKET_MSG_SENDTO; + if(u8OpCode == SOCKET_CMD_SENDTO) + u8CallbackMsgID = SOCKET_MSG_SENDTO; - if(hif_receive(u32Address, (uint8*)&strReply, sizeof(tstrSendReply), 0) == M2M_SUCCESS) - { - uint16 u16SessionID = 0; - - sock = strReply.sock; - u16SessionID = strReply.u16SessionID; - M2M_DBG("send callback session ID = %d\r\n",u16SessionID); - - s16Rcvd = NM_BSP_B_L_16(strReply.s16SentBytes); + if(hif_receive(u32Address, (uint8 *)&strReply, sizeof(tstrSendReply), 0) == M2M_SUCCESS) + { + if((strReply.sock >=0) && (strReply.sock < MAX_SOCKET)) + { + uint16 u16SessionID = 0; - if(u16SessionID == gastrSockets[sock].u16SessionID) - { - if(gpfAppSocketCb) - gpfAppSocketCb(sock,u8CallbackMsgID, &s16Rcvd); - } - else - { - 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) - { - gfpPingCb = (void (*)(uint32 , uint32 , uint8))strPingReply.u32CmdPrivate; - if(gfpPingCb != NULL) - { - gfpPingCb(strPingReply.u32IPAddr, strPingReply.u32RTT, strPingReply.u8ErrorCode); - } - } - } + sock = strReply.sock; + u16SessionID = strReply.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); + } + else + { + 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((gu32PingId == strPingReply.u32CmdPrivate) && (gfpPingCb != NULL)) + { + gfpPingCb(strPingReply.u32IPAddr, strPingReply.u32RTT, strPingReply.u8ErrorCode); + } + } + } } /********************************************************************* Function @@ -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,16 +590,19 @@ 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) - { - tstrSSLSocketCreateCmd strSSLCreate; - strSSLCreate.sslSock = sock; - pstrSock->u8SSLFlags = SSL_FLAGS_ACTIVE | SSL_FLAGS_NO_TX_COPY; - SOCKET_REQUEST(SOCKET_CMD_SSL_CREATE, (uint8*)&strSSLCreate, sizeof(tstrSSLSocketCreateCmd), 0, 0, 0); - } - } - } - return sock; + 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; + if(u8Config == SOCKET_CONFIG_SSL_DELAY) + pstrSock->u8SSLFlags |= SSL_FLAGS_DELAY; + } + } + } + return sock; } /********************************************************************* Function @@ -586,15 +625,15 @@ 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)) - { - tstrBindCmd strBind; - uint8 u8CMD = SOCKET_CMD_BIND; - if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) - { - u8CMD = SOCKET_CMD_SSL_BIND; - } + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + if((pstrAddr != NULL) && (sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0)) + { + tstrBindCmd strBind; + uint8 u8CMD = SOCKET_CMD_BIND; + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8CMD = SOCKET_CMD_SSL_BIND; + } /* Build the bind request. */ strBind.sock = sock; @@ -631,11 +670,11 @@ Date *********************************************************************/ sint8 WINC1500_EXPORT(listen)(SOCKET sock, uint8 backlog) { - sint8 s8Ret = SOCK_ERR_INVALID_ARG; - - if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1)) - { - tstrListenCmd strListen; + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + + if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1)) + { + tstrListenCmd strListen; strListen.sock = sock; strListen.u8BackLog = backlog; @@ -669,13 +708,13 @@ Date *********************************************************************/ sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8 *addrlen) { - sint8 s8Ret = SOCK_ERR_INVALID_ARG; - - if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1) ) - { - s8Ret = SOCK_ERR_NO_ERROR; - } - return s8Ret; + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + + if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1)) + { + s8Ret = SOCK_ERR_NO_ERROR; + } + return s8Ret; } /********************************************************************* Function @@ -698,18 +737,18 @@ 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)) - { - tstrConnectCmd strConnect; - uint8 u8Cmd = SOCKET_CMD_CONNECT; - if((gastrSockets[sock].u8SSLFlags) & SSL_FLAGS_ACTIVE) - { - u8Cmd = SOCKET_CMD_SSL_CONNECT; - strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags; - } - strConnect.sock = sock; - m2m_memcpy((uint8 *)&strConnect.strAddr, (uint8 *)pstrAddr, sizeof(tstrSockAddr)); + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + if((sock >= 0) && (sock < MAX_SOCKET) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0)) + { + tstrConnectCmd strConnect; + uint8 u8Cmd = SOCKET_CMD_CONNECT; + if((gastrSockets[sock].u8SSLFlags) & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_CONNECT; + strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags; + } + strConnect.sock = sock; + m2m_memcpy((uint8 *)&strConnect.strAddr, (uint8 *)pstrAddr, sizeof(tstrSockAddr)); strConnect.u16SessionID = gastrSockets[sock].u16SessionID; s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strConnect,sizeof(tstrConnectCmd), NULL, 0, 0); @@ -722,7 +761,53 @@ sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8A } /********************************************************************* Function - send + 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 Description @@ -739,38 +824,41 @@ Date *********************************************************************/ sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags) { - sint16 s16Ret = SOCK_ERR_INVALID_ARG; - - if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1)) - { - uint16 u16DataOffset; - tstrSendCmd strSend; - uint8 u8Cmd; + sint16 s16Ret = SOCK_ERR_INVALID_ARG; - u8Cmd = SOCKET_CMD_SEND; - u16DataOffset = TCP_TX_PACKET_OFFSET; + if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1)) + { + uint16 u16DataOffset; + tstrSendCmd strSend; + uint8 u8Cmd; - strSend.sock = sock; - strSend.u16DataSize = NM_BSP_B_L_16(u16SendLength); - strSend.u16SessionID = gastrSockets[sock].u16SessionID; + u8Cmd = SOCKET_CMD_SEND; + u16DataOffset = TCP_TX_PACKET_OFFSET; - if(sock >= TCP_SOCK_MAX) - { - u16DataOffset = UDP_TX_PACKET_OFFSET; - } - if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) - { - u8Cmd = SOCKET_CMD_SSL_SEND; - u16DataOffset = gastrSockets[sock].u16DataOffset; - } + strSend.sock = sock; + strSend.u16DataSize = NM_BSP_B_L_16(u16SendLength); + strSend.u16SessionID = gastrSockets[sock].u16SessionID; - 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; - } - } - return s16Ret; + if(sock >= TCP_SOCK_MAX) + { + u16DataOffset = UDP_TX_PACKET_OFFSET; + } + 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); + if(s16Ret != SOCK_ERR_NO_ERROR) + { + s16Ret = SOCK_ERR_BUFFER_FULL; + } + } + return s16Ret; } /********************************************************************* Function @@ -781,7 +869,7 @@ Description Return Author - Ahmed Ezzat + Ahmed Ezzat Version 1.0 @@ -791,13 +879,13 @@ Date *********************************************************************/ sint16 WINC1500_EXPORT(sendto)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags, struct sockaddr *pstrDestAddr, uint8 u8AddrLen) { - sint16 s16Ret = SOCK_ERR_INVALID_ARG; - - if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1)) - { - if(gastrSockets[sock].bIsUsed) - { - tstrSendCmd strSendTo; + sint16 s16Ret = SOCK_ERR_INVALID_ARG; + + if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1)) + { + if(gastrSockets[sock].bIsUsed) + { + tstrSendCmd strSendTo; m2m_memset((uint8*)&strSendTo, 0, sizeof(tstrSendCmd)); @@ -846,32 +934,36 @@ Date *********************************************************************/ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec) { - sint16 s16Ret = SOCK_ERR_INVALID_ARG; - - if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1)) - { - s16Ret = SOCK_ERR_NO_ERROR; - gastrSockets[sock].pu8UserBuffer = (uint8*)pvRecvBuf; - gastrSockets[sock].u16UserBufferSize = u16BufLen; + sint16 s16Ret = SOCK_ERR_INVALID_ARG; + + 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].u16UserBufferSize = u16BufLen; if(!gastrSockets[sock].bIsRecvPending) { tstrRecvCmd strRecv; uint8 u8Cmd = SOCKET_CMD_RECV; - gastrSockets[sock].bIsRecvPending = 1; - if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) - { - u8Cmd = SOCKET_CMD_SSL_RECV; - } + gastrSockets[sock].bIsRecvPending = 1; + if( + (gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + && (!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY)) + ) + { + u8Cmd = SOCKET_CMD_SSL_RECV; + } - /* Check the timeout value. */ - if(u32Timeoutmsec == 0) - strRecv.u32Timeoutmsec = 0xFFFFFFFF; - else - strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec); - strRecv.sock = sock; - strRecv.u16SessionID = gastrSockets[sock].u16SessionID; + /* Check the timeout value. */ + if(u32Timeoutmsec == 0) + strRecv.u32Timeoutmsec = 0xFFFFFFFF; + else + 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,25 +996,25 @@ 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)) - { - uint8 u8Cmd = SOCKET_CMD_CLOSE; - tstrCloseCmd strclose; - strclose.sock = sock; - strclose.u16SessionID = gastrSockets[sock].u16SessionID; - - if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) - { - u8Cmd = SOCKET_CMD_SSL_CLOSE; - } - 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)); - } - return s8Ret; + if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1)) + { + uint8 u8Cmd = SOCKET_CMD_CLOSE; + tstrCloseCmd strclose; + strclose.sock = sock; + strclose.u16SessionID = gastrSockets[sock].u16SessionID; + + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_CLOSE; + } + 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)); + } + return s8Ret; } /********************************************************************* Function @@ -945,14 +1037,14 @@ 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(gastrSockets[sock].bIsUsed) - { - s16Ret = SOCK_ERR_NO_ERROR; - gastrSockets[sock].pu8UserBuffer = (uint8*)pvRecvBuf; - gastrSockets[sock].u16UserBufferSize = u16BufLen; + sint16 s16Ret = SOCK_ERR_NO_ERROR; + 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].u16UserBufferSize = u16BufLen; if(!gastrSockets[sock].bIsRecvPending) { @@ -960,13 +1052,14 @@ sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, gastrSockets[sock].bIsRecvPending = 1; - /* Check the timeout value. */ - if(u32Timeoutmsec == 0) - strRecv.u32Timeoutmsec = 0xFFFFFFFF; - else - strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec); - strRecv.sock = sock; - strRecv.u16SessionID = gastrSockets[sock].u16SessionID; + /* Check the timeout value. */ + if(u32Timeoutmsec == 0) + strRecv.u32Timeoutmsec = 0xFFFFFFFF; + else + 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,13 +1096,11 @@ Date *********************************************************************/ uint32 nmi_inet_addr(char *pcIpAddr) { - uint8 tmp; - uint32 u32IP = 0; - uint8 au8IP[4]; - uint8 c; - uint8 i, j; - - tmp = 0; + uint8 tmp = 0; + uint32 u32IP = 0; + uint8 au8IP[4]; + uint8 c; + uint8 i, j; for(i = 0; i < 4; ++i) { @@ -1089,87 +1180,73 @@ Date *********************************************************************/ static sint8 sslSetSockOpt(SOCKET sock, uint8 u8Opt, const void *pvOptVal, uint16 u16OptLen) { - sint8 s8Ret = SOCK_ERR_INVALID_ARG; - if(sock < TCP_SOCK_MAX) - { - if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) - { - 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; - } - 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; - } - else if(u8Opt == SO_SSL_ENABLE_SNI_VALIDATION) - { - int optVal = *((int*)pvOptVal); - if(optVal) - { - gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CHECK_SNI; - } - else - { - gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CHECK_SNI; - } - s8Ret = SOCK_ERR_NO_ERROR; - } - else if(u8Opt == SO_SSL_SNI) - { - if(u16OptLen < HOSTNAME_MAX_SIZE) - { - uint8 *pu8SNI = (uint8*)pvOptVal; - tstrSSLSetSockOptCmd strCmd; + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + if(sock < TCP_SOCK_MAX) + { + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + uint8 sslFlag = 0; - strCmd.sock = sock; - strCmd.u16SessionID = gastrSockets[sock].u16SessionID; - strCmd.u8Option = u8Opt; - strCmd.u32OptLen = u16OptLen; - m2m_memcpy(strCmd.au8OptVal, pu8SNI, HOSTNAME_MAX_SIZE); - - 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 | 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); - } - } - else - { - M2M_ERR("Not SSL Socket\n"); - } - } - return s8Ret; + s8Ret = SOCK_ERR_NO_ERROR; + if(u16OptLen == sizeof(int)) + { + if(u8Opt == SO_SSL_BYPASS_X509_VERIF) + { + sslFlag = SSL_FLAGS_BYPASS_X509; + } + else if(u8Opt == SO_SSL_ENABLE_SESSION_CACHING) + { + 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 |= sslFlag; + } + else + { + gastrSockets[sock].u8SSLFlags &= ~sslFlag; + } + } + else if( + ((u8Opt == SO_SSL_SNI) && (u16OptLen < HOSTNAME_MAX_SIZE)) + || ((u8Opt == SO_SSL_ALPN) && (u16OptLen <= ALPN_LIST_MAX_SIZE)) + ) + { + tstrSSLSetSockOptCmd strCmd = {0}; + + strCmd.sock = sock; + strCmd.u16SessionID = gastrSockets[sock].u16SessionID; + strCmd.u8Option = u8Opt; + strCmd.u32OptLen = u16OptLen; + m2m_memcpy(strCmd.au8OptVal, (uint8*)pvOptVal, u16OptLen); + + 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); + } + } + else + { + M2M_ERR("Unknown SSL Socket Option %d\n", u8Opt); + s8Ret = SOCK_ERR_INVALID_ARG; + } + } + else + { + M2M_ERR("Not SSL Socket\n"); + } + } + return s8Ret; } /********************************************************************* Function @@ -1192,30 +1269,33 @@ Date sint8 WINC1500_EXPORT(setsockopt)(SOCKET sock, uint8 u8Level, uint8 option_name, const void *option_value, uint16 u16OptionLen) { - sint8 s8Ret = SOCK_ERR_INVALID_ARG; - if((sock >= 0) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1)) - { - if(u8Level == SOL_SSL_SOCKET) - { - s8Ret = sslSetSockOpt(sock, option_name, option_value, u16OptionLen); - } - else - { - uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION; - tstrSetSocketOptCmd strSetSockOpt; - strSetSockOpt.u8Option=option_name; - strSetSockOpt.sock = sock; - strSetSockOpt.u32OptionValue = *(uint32*)option_value; - strSetSockOpt.u16SessionID = gastrSockets[sock].u16SessionID; + sint8 s8Ret = SOCK_ERR_INVALID_ARG; + 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 if(u8Level == SOL_SOCKET) + { + if(u16OptionLen == sizeof(uint32)) + { + uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION; + tstrSetSocketOptCmd strSetSockOpt; + strSetSockOpt.u8Option=option_name; + strSetSockOpt.sock = sock; + strSetSockOpt.u32OptionValue = *(uint32*)option_value; + strSetSockOpt.u16SessionID = gastrSockets[sock].u16SessionID; - s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL,0, 0); - if(s8Ret != SOCK_ERR_NO_ERROR) - { - s8Ret = SOCK_ERR_INVALID; - } - } - } - return s8Ret; + s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL, 0, 0); + if(s8Ret != SOCK_ERR_NO_ERROR) + { + s8Ret = SOCK_ERR_INVALID; + } + } + } + } + return s8Ret; } /********************************************************************* Function @@ -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 @@ -1262,22 +1342,102 @@ sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb) { sint8 s8Ret = M2M_ERR_INVALID_ARG; - if((u32DstIP != 0) && (fpPingCb != NULL)) - { - tstrPingCmd strPingCmd; + if((u32DstIP != 0) && (fpPingCb != NULL)) + { + tstrPingCmd strPingCmd; + strPingCmd.u16PingCount = 1; + strPingCmd.u32DestIPAddr = u32DstIP; + strPingCmd.u32CmdPrivate = ++gu32PingId; + strPingCmd.u8TTL = u8TTL; - strPingCmd.u16PingCount = 1; - strPingCmd.u32DestIPAddr = u32DstIP; - strPingCmd.u32CmdPrivate = (uint32)fpPingCb; - strPingCmd.u8TTL = u8TTL; + gfpPingCb = fpPingCb; + s8Ret = SOCKET_REQUEST(SOCKET_CMD_PING, (uint8 *)&strPingCmd, sizeof(tstrPingCmd), NULL, 0, 0); + } + return s8Ret; +} - 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 - sslEnableCertExpirationCheck + 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 Description Enable/Disable TLS Certificate Expiration Check. @@ -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; +} diff --git a/src/drivers/winc1500/src/spi_flash.c b/src/drivers/winc1500/src/spi_flash.c index 9b317eae1..8715de7c0 100644 --- a/src/drivers/winc1500/src/spi_flash.c +++ b/src/drivers/winc1500/src/spi_flash.c @@ -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,17 +539,16 @@ sint8 spi_flash_enable(uint8 enable) } /* GPIO15/16/17/18 */ u32Val &= ~((0x7777ul) << 12); - u32Val |= ((0x1111ul) << 12); - nm_write_reg(0x1410, u32Val); if(enable) { + u32Val |= ((0x1111ul) << 12); + nm_write_reg(0x1410, u32Val); spi_flash_leave_low_power_mode(); } else { spi_flash_enter_low_power_mode(); + /* Disable pinmux to SPI flash to minimize leakage. */ + u32Val |= ((0x0010ul) << 12); + nm_write_reg(0x1410, u32Val); } - /* Disable pinmux to SPI flash to minimize leakage. */ - u32Val &= ~((0x7777ul) << 12); - u32Val |= ((0x0010ul) << 12); - nm_write_reg(0x1410, u32Val); } ERR1: return s8Ret;