drivers/winc1500: Update host driver/firmware to version 19.7.7.

This commit is contained in:
iabdalkader 2023-10-28 15:08:41 +02:00
parent a99a8fad95
commit cfb5aa8c94
27 changed files with 8588 additions and 8011 deletions

Binary file not shown.

View File

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

View File

@ -96,6 +96,10 @@
#include "bsp/include/nm_bsp_same70.h"
#endif
#if (defined __SAMR30G18A__) || (defined __SAMR30E18A__)
#include "bsp/include/nm_bsp_samr30.h"
#endif
#ifdef CORTUS_APP
#include "crt_iface.h"
#endif

View File

@ -4,7 +4,7 @@
*
* \brief This module contains NMC1000 bus wrapper APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -164,6 +164,30 @@ sint8 nm_bus_reinit(void *);
uint8 nm_bus_get_chip_type(void);
sint8 nm_bus_break(void);
#endif
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level);
/**
* @fn spi_rw
* @brief Process SPI Read/Write operation
* @param pu8Mosi TX Data buffer
* @param pu8Miso RX Data buffer
* @param u16Sz Transfer length
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
#ifdef CONF_WINC_USE_SPI
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -4,7 +4,7 @@
*
* \brief WINC Driver Common API Declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -45,9 +45,10 @@
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_debug.h"
#define WINC1500_EXPORT(name) winc1500_ ## name
/**@addtogroup COMMONDEF
* @{
*/
/**@{*/
#define M2M_TIME_OUT_DELAY 10000
/*states*/
@ -66,24 +67,18 @@
#define M2M_ERR_FAIL ((sint8)-12)
#define M2M_ERR_FW_VER_MISMATCH ((sint8)-13)
#define M2M_ERR_SCAN_IN_PROGRESS ((sint8)-14)
/* Invalid argument */
#define M2M_ERR_INVALID_ARG ((sint8)-15)
#define M2M_ERR_INVALID ((sint8)-16)
/*i2c MAASTER ERR*/
#define I2C_ERR_LARGE_ADDRESS 0xE1UL
/*!< The address exceeds the max addressing mode in I2C flash.
*/
#define I2C_ERR_TX_ABRT 0xE2UL
/*!< NO ACK from slave.
*/
/* I2C MASTER ERR */
#define I2C_ERR_LARGE_ADDRESS 0xE1UL /*!< The address exceeds the max addressing mode in I2C flash. */
#define I2C_ERR_TX_ABRT 0xE2UL /*!< NO ACK from slave. */
#define I2C_ERR_OVER_SIZE 0xE3UL
#define ERR_PREFIX_NMIS 0xE4UL
/*!< Wrong first four bytes in flash NMIS.
*/
#define ERR_FIRMEWARE_EXCEED_SIZE 0xE5UL
/*!< Total size of firmware exceeds the max size 256k.
*/
/**/
#define ERR_PREFIX_NMIS 0xE4UL /*!< Wrong first four bytes in flash NMIS. */
#define ERR_FIRMWARE_EXCEED_SIZE 0xE5UL /*!< Total size of firmware exceeds the max size 256k. */
#define PROGRAM_START 0x26961735UL
#define BOOT_SUCCESS 0x10add09eUL
#define BOOT_START 0x12345678UL
@ -121,25 +116,46 @@
#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
/*! Most significant byte of 32bit word (LE) */
#define BYTE_0(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (LE) */
#define BYTE_1(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
/*! Third most significant byte of 32bit word (LE) */
#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
/*! Least significant byte of 32bit word (LE) */
#define BYTE_3(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
#else
/*! Most significant byte of 32bit word (BE) */
#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (BE) */
#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
/*! 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
/**@}*/
#define PASS 0
#define FAIL 1
#define LOW 0
#define HIGH 1
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) Min(a, b)
#define max(a, b) Max(a, b)
/**@}*/ //COMMONDEF
#ifdef __cplusplus
extern "C" {
#endif
@ -156,7 +172,7 @@
* Destination buffer.
* @return None
*/
NMI_API void m2m_memcpy(uint8* pDst,uint8* pSrc,uint32 sz);
NMI_API void m2m_memcpy(uint8 *pDst, const uint8 *pSrc, uint32 sz);
/*!
* @ingroup COMMONAPI
@ -218,7 +234,7 @@ 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);
@ -234,6 +250,20 @@ NMI_API uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr);
*/
NMI_API uint8 m2m_checksum(uint8 *buf, int sz);
/*!
* @ingroup COMMONAPI
* @fn sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
* @brief Converts a string of hex characters to bytes.
* @param[out] pu8Out
* Output buffer (eg {0x11, 0x12, 0x13,...})
* @param[in] pu8In
* Input buffer (eg {0x31, 0x31, 0x31, 0x32, 0x31, 0x33, ...})
* @param[in] u8SizeOut
* Length of output buffer (should be half of the length of the input buffer).
* @return @ref M2M_SUCCESS if successful, M2M_ERR_INVALID_ARG otherwise (eg unrecognised hexchar in input).
*/
sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
/*!
* @ingroup COMMONAPI
* @fn void (*at_sb_printf)(const char *_format, ...);

View File

@ -1,4 +1,4 @@
/**
/**
*
* \file
*
@ -64,10 +64,8 @@
#define M2M_PRINT(...)
#if (CONF_WINC_DEBUG == 1)
#undef M2M_LOG_LEVEL
#define M2M_LOG_LEVEL M2M_LOG_DBG
#undef M2M_PRINT
#define M2M_PRINT(...) do{CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#define M2M_PRINT(...) do{CONF_WINC_PRINTF(__VA_ARGS__);}while(0)
#if (M2M_LOG_LEVEL >= M2M_LOG_ERROR)
#undef M2M_ERR
#define M2M_ERR(...) do{CONF_WINC_PRINTF("(APP)(ERR)[%s][%d]",__FUNCTION__,__LINE__); CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)

View File

@ -34,6 +34,8 @@
#ifdef _M2M_ATE_FW_
#ifndef _M2M_ATE_MODE_H_
#define _M2M_ATE_MODE_H_

View File

@ -100,7 +100,6 @@ typedef enum{
tenuM2mCryptoCmd
*/
typedef void (*tpfAppCryproCb) (uint8 u8MsgType,void * pvResp, void * pvMsg);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

View File

@ -4,7 +4,7 @@
*
* \brief WINC OTA Upgrade API Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -35,10 +35,11 @@
/**@defgroup OTAAPI OTA
@brief
The WINC supports OTA (Over-The-Air) updates. Using the APIs described in this module,
it is possible to request an ATWINC15x0 to update its firmware, or safely rollback to
the previous firmware version.\n There are also APIs to download files and store them in
the WINC's Flash (supported by ATWINC1510 only), which can be used for Host MCU OTA
updates or accessing information stored remotely.
it is possible to request an ATWINC15x0 to update its firmware image, or safely rollback to
the previous firmware image.\n Note that it is NOT possible to update other areas of the WINC
flash (e.g. the HTTP file area) using the OTA mechanism.\n\n There are also APIs to download
files and store them in the WINC's Flash (supported by ATWINC1510 only), which can be used
for Host MCU OTA updates or accessing information stored remotely.
@{
@defgroup OTACALLBACKS Callbacks
@brief
@ -58,6 +59,11 @@
@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
@}
@}
*/
@ -72,13 +78,41 @@ INCLUDES
#include "driver/include/m2m_types.h"
#include "driver/include/nmdrv.h"
/**@addtogroup OTATYPEDEF
* @{
*/
/*!
@enum \
tenuOTASSLOption
@brief
Enumeration for OTA SSL options
The following SSL options can be set for OTA
*/
typedef enum {
WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH = 0x1,
/*!<Server authentication for OTA SSL connections. Values are of type int \n
1: Bypass server authentication.\n*/
WIFI_OTA_SSL_OPT_SNI_VALIDATION = 0x2,
/*!<Server Name Indication. The actual server name to send must be passed using option @ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
Values are of type int \n
0: Do not check the received servername against the server provided one\n
1: Check the received servername against the server provided one\n
*/
WIFI_OTA_SSL_OPT_SNI_SERVERNAME = 0x4,
/*!<The server name string to send in the SNI extension. \n
Value is a null terminated string up to 64 characters in length including the null terminator.\n*/
} tenuOTASSLOption;
/**@}*/ //OTATYPEDEF
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**@addtogroup OTACALLBACKS
* @{
*/
/**@{*/
/*!
@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *pstrOtaUpdateInfo);
@ -96,7 +130,6 @@ MACROS
*/
typedef void (*tpfOtaNotifCb)(tstrOtaUpdateInfo *pstrOtaUpdateInfo);
/*!
@typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
@ -182,16 +215,15 @@ typedef void (*tpfFileEraseCb) (uint8 u8Status);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/** @addtogroup OTAFUNCTIONS
*/
#ifdef __cplusplus
extern "C" {
#endif
/**@{*/
/*!
@ingroup OTACOMMON
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb)
sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Synchronous initialization function for the OTA layer by registering the update callback.\n
@ -210,15 +242,16 @@ FUNCTION PROTOTYPES
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA notification server URL, the functions need to be called before any check for update.\n
Set the OTA notification server URL, the function needs to be called before any check for update.\n
This functionality is not supported by WINC firmware.
@param[in] u8Url
Set the OTA notification server URL, the functions need to be called before any check for update.
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.
@ -235,8 +268,9 @@ NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNo
NMI_API sint8 m2m_ota_notif_set_url(uint8 *u8Url);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
sint8 m2m_ota_notif_check_for_update(void);
@brief
Synchronous function to check for the OTA update using the Notification Server URL.\n
@ -255,8 +289,9 @@ NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
NMI_API sint8 m2m_ota_notif_check_for_update(void);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA notification Server check for update request after specific number of days.\n
@ -279,13 +314,15 @@ NMI_API sint8 m2m_ota_notif_check_for_update(void);
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
@brief
Request OTA start update using the download URL, the OTA module will download the OTA image, ensure integrity of the image
Request OTA start update using the download URL. The OTA module will download the OTA image, ensure integrity of the image
and update the validity of the image in the control structure. On completion, a callback of type @ref tpfOtaUpdateCb is called
(callback previously provided via m2m_ota_init).
(callback previously provided via @ref m2m_ota_init ). Switching to the updated image additionally requires completion of
@ref m2m_ota_switch_firmware and @ref system_reset
@param[in] pcDownloadUrl
The download firmware URL, according to the application server.
@ -293,11 +330,11 @@ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@warning
Calling this API does not guarantee OTA WINC image update, it depends on the connection with the
download server and the validity of the image.\n
Calling this API invalidates any previous valid rollback image. When the OTA succeeds, the current
image will become the rollback image after @ref m2m_ota_switch_firmware.
Calling this API invalidates any previous valid rollback image, irrespective of the result, but when
the OTA succeeds, the current image will become the rollback image after @ref m2m_ota_switch_firmware.
@pre
@ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update().\n
@ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update \n
Switching to the newly downloaded image requires calling @ref m2m_ota_switch_firmware API.
@sa
@ -307,58 +344,85 @@ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
Note that successful operation in this context means the OTA update request has reached the firmware OTA module.
It does not indicate whether or not the image update succeeded.
\section OTAExample Example
@section OTAExample Example
This example shows how an OTA image update and switch is carried out.
It demonstrates use of the following OTA APIs:
@ref m2m_ota_init
@ref tpfOtaUpdateCb
@ref m2m_ota_start_update
@ref m2m_ota_switch_firmware
@ref m2m_ota_rollback
- @ref m2m_ota_init
- @ref tpfOtaUpdateCb
- @ref m2m_ota_start_update
- @ref m2m_ota_switch_firmware
- @ref m2m_ota_rollback
@code
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus)
{
if(u8OtaUpdateStatusType == DL_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) {
//switch to the upgraded firmware
M2M_INFO("%d %d\n", u8OtaUpdateStatusType, u8OtaUpdateStatus);
switch(u8OtaUpdateStatusType)
{
case DL_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("OTA download succeeded\n");
// In this case the application MAY WANT TO update the host driver before calling
// @ref m2m_ota_switch_firmware(). Switching firmware image and resetting without
// updating host driver may lead to suboptimal functionality.
// Switch to the upgraded firmware
M2M_INFO("Now switching active partition...\n");
m2m_ota_switch_firmware();
}
break;
case SW_STATUS:
case RB_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("Switch/Rollback succeeded\n");
// Start the host SW upgrade if required, then system reset is required (Reinitialize the driver)
M2M_INFO("Now resetting the system...\n");
system_reset();
}
else if(u8OtaUpdateStatusType == SW_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) {
M2M_INFO("Now OTA successfully done");
//start the host SW upgrade then system reset is required (Reinitialize the driver)
}
break;
}
}
void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg)
static void wifi_event_cb(uint8 u8WiFiEvent, void *pvMsg)
{
// ...
case M2M_WIFI_REQ_DHCP_CONF:
{
//after successfully connection, start the over air upgrade
// After successful connection, start the OTA upgrade
m2m_ota_start_update(OTA_URL);
}
break;
default:
break;
// ...
}
int main (void)
{
sint8 s8Ret;
tstrWifiInitParam param;
sint8 s8Ret = M2M_SUCCESS;
bool rollback_required = FALSE;
tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS;
nm_bsp_init();
// System init, etc should be here...
m2m_memset((uint8*)&param, 0, sizeof(param));
param.pfAppWifiCb = wifi_event_cb;
// Initialize the WINC Driver
s8Ret = m2m_wifi_init(&param);
if(s8Ret == M2M_ERR_FW_VER_MISMATCH)
{
M2M_ERR("Firmware version mismatch\n");
}
if (M2M_SUCCESS != s8Ret)
{
M2M_ERR("Driver Init Failed <%d>\n",s8Ret);
@ -367,14 +431,13 @@ int main (void)
// Initialize the OTA module
m2m_ota_init(OtaUpdateCb,NULL);
//connect to AP that provide connection to the OTA server
// Connect to AP that provides connection to the OTA server
m2m_wifi_default_connect();
while(1)
{
// Handle the app state machine plus the WINC event handler
while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) {
}
}
}
@ -383,21 +446,21 @@ int main (void)
NMI_API sint8 m2m_ota_start_update(unsigned char *pcDownloadUrl);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_rollback(void);
sint8 m2m_ota_rollback(void);
@brief
Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the Roll-back image
and activate it if valid. On completion, a callback of type tpfOtaUpdateCb is called (application must previously have
provided the callback via m2m_ota_init). If the callback indicates successful activation, the newly-activated image
Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the inactive image
and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb is called (application must previously have
provided the callback via @ref m2m_ota_init). If the callback indicates successful activation, the newly-activated image
will start running after next system reset.
@warning
If rollback requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this
API.\n
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware.
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@sa
m2m_ota_init
@ -409,35 +472,40 @@ NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
NMI_API sint8 m2m_ota_rollback(void);
/*!
@ingroup OTACOMMON
@fn \
NMI_API sint8 m2m_ota_abort(void);
sint8 m2m_ota_abort(void);
@brief
Request the WINC to abort an OTA or Host File download in progress.\n
If no download is in progress, the API will respond with failure.
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
The function returns @ref M2M_SUCCESS for a successful operation and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void);
/*!
@ingroup WINCOTA
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
sint8 m2m_ota_switch_firmware(void);
@brief
Request switch to the updated WINC image. The WINC firmware will check the validity of the
inactive image and activate it if it is valid. On completion, a callback of type @ref tpfOtaUpdateCb
inactive image and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb
is called (application must previously have provided the callback via @ref m2m_ota_init).
If the callback indicates successful activation, the newly-activated image will start running
after next system reset.
@warning
If switch will necessitate a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this
API.\n
If switch requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware.
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@sa
m2m_ota_init
@ -449,8 +517,9 @@ NMI_API sint8 m2m_ota_abort(void);
NMI_API sint8 m2m_ota_switch_firmware(void);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
@brief
Download a file from a remote location and store it in WINC's Flash.
@ -481,8 +550,9 @@ NMI_API sint8 m2m_ota_switch_firmware(void);
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
@brief
Read a certain amount of bytes from a file previously stored in WINC's Flash using HIF transfer.
@ -506,13 +576,13 @@ 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
reset or put in download mode, as it is the case for reading the file via SPI (see @ref m2m_ota_host_file_read_spi).\n
A valid file handler must be provided, this means that it needs to match the handler internally stored
by the WINC and must not be @ref HFD_INVALID_HANDLER.\n
by the WINC and must not be @ref HFD_INVALID_HANDLER \n
Providing a callback is mandatory.
@note
@ -528,8 +598,9 @@ NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb p
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
@brief
Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
@ -689,8 +760,9 @@ void main(void)
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
/*!
@ingroup HFD
@fn \
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
@brief
Erase any traces of file stored in WINC's Flash.
@ -719,7 +791,7 @@ NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8* pu8Buff, uint32
@warning
A valid file handler must be provided, this means that it needs to match the handler internally stored
by the WINC and must not be @ref HFD_INVALID_HANDLER.\n
by the WINC and must not be @ref HFD_INVALID_HANDLER \n
The handlers will be destroyed regardless of the call returning success or not.
@sa
@ -731,11 +803,10 @@ 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
@ -744,6 +815,71 @@ NMI_API sint8 m2m_ota_test(void);
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
@brief
Set specific SSL options to be used when the WINC performs an OTA from an https server.
@details
The following options can be set:\n
@ref WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH \n
@ref WIFI_OTA_SSL_OPT_SNI_VALIDATION \n
@ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
The setting applies to all subsequent OTA attempts via @ref m2m_ota_start_update \n
@param[in] enuOptionName
The option to set.
@param[in] pOptionValue
Pointer to a buffer containing the value to set. The buffer must be at least as long as OptionLen.
If OptionLen is 0, then pOptionValue may be NULL.
@param[in] OptionLen
The length of the option value being set (including the null terminator for strings).
@return
The function returns @ref M2M_SUCCESS if the parameters are valid and @ref M2M_ERR_INVALID_ARG otherwise.
*/
NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
@brief
Get (read) SSL options relating to OTA
@details
The following options can be read:\n
@ref WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH \n
@ref WIFI_OTA_SSL_OPT_SNI_VALIDATION \n
@ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
@param[in] enuOptionName
The option to get.
@param[out] pOptionValue
Pointer to a buffer to contain the value to get. The buffer must be at least as long as the value pointed to by pOptionLen.
@param[inout] pOptionLen
Pointer to a length.
When calling the function, this length must be the length of the buffer available for reading the option value,
and must be large enough to hold the returned option value otherwise an @ref M2M_ERR_INVALID_ARG error will be returned.
When the function returns, this length is the length of the data that has been populated by the function.
@return
The function returns @ref M2M_SUCCESS if the parameters are valid and @ref M2M_ERR_INVALID_ARG otherwise.
*/
NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen);
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -4,7 +4,7 @@
*
* \brief WINC Application Interface Internal Types.
*
* Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -60,7 +60,7 @@ INCLUDES
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/include/nmdrv.h"
#include "driver/include/ecc_types.h"
#include "ecc_types.h"
#include "socket/include/socket.h"
/*!
@ -82,7 +82,7 @@ FUNCTION PROTOTYPES
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
@param[in] pfAppSSLCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
@ -91,7 +91,7 @@ NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz);
@brief Sends ECC responses to the WINC
@brief Sends ECC responses to the WINC.
@param[in] strECCResp
ECC Response struct.
@param[in] pu8RspDataBuff
@ -105,9 +105,9 @@ 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
@brief Sends certificates to the WINC.
@param[in] pu8Buffer
Pointer to the certificates.
Pointer to the certificates. The buffer format must match the format of @ref tstrTlsSrvSecHdr.
@param[in] u32BufferSz
Size of the certificates.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@ -116,47 +116,114 @@ 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.
@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.
@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.
@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);
@ -171,14 +238,10 @@ NMI_API void m2m_ssl_ecc_process_done(void);
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination, except for combinations involving both RSA
and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
change.
@return
- @ref SOCK_ERR_NO_ERROR
- @ref SOCK_ERR_INVALID_ARG
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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
*
@ -56,8 +56,7 @@ INCLUDES
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @defgroup SocketDefines Defines
/**@defgroup SocketDefines Defines
* @ingroup SocketHeader
*/
@ -74,7 +73,7 @@ MACROS
#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.
command value. Used with the @ref setsockopt function.
*/
#define SOCKET_BUFFER_MAX_LENGTH 1400
@ -89,7 +88,6 @@ MACROS
(It is the only supported type for the current implementation.)
*/
#define SOCK_STREAM 1
/*!<
One of the IPv4 supported socket types for reliable connection-oriented stream connection.
@ -104,7 +102,31 @@ MACROS
#define SOCKET_FLAGS_SSL 0x01
/*!<
This flag shall be passed to the socket API for SSL session.
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 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)
@ -137,8 +159,16 @@ 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.
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,35 +183,74 @@ 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
* @ingroup SOCKETDEF
* @ingroup SSLAPI
*/
@ -194,35 +263,67 @@ MACROS
#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
/*!<
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
/*!<
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
/*!<
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,19 +526,18 @@ 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.
Identifies that @ref listen operation failed.
*/
#define SOCK_ERR_INVALID -9
/*!<
The requested socket operation is not valid in the
current socket state.
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.
*/
@ -463,7 +563,9 @@ 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
@ -493,7 +595,7 @@ Socket Errors
/*!<
Convert a 2-byte integer from the Network byte order representation to the host representation .
*/
/**@}*/ //SocketDefines
/**@}*/ //SOCKETBYTEORDER
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
@ -501,8 +603,8 @@ DATA TYPES
/**@defgroup SocketEnums DataTypes
* @ingroup SocketHeader
* Specific Enumeration-typedefs used for socket operations
* @{ */
* @{
*/
/*!
@typedef \
SOCKET
@ -510,10 +612,36 @@ DATA TYPES
@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.
The ID is uniquely assigned at socket creation when calling @ref socket operation.
*/
typedef sint8 SOCKET;
/*!
@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
@ -559,7 +687,7 @@ Socket address family.
sockaddr_in
@brief
Socket address structure for IPV4 addresses. Used to specify socket address information to which to connect to.
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 {
@ -573,20 +701,39 @@ struct sockaddr_in{
/*!<
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)).
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. non zero otherwise.
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
@ -646,15 +793,18 @@ typedef enum{
*/
SOCKET_MSG_SENDTO,
/*!<
sendto socket event.
Sendto socket event.
*/
SOCKET_MSG_RECVFROM
SOCKET_MSG_RECVFROM,
/*!<
Recvfrom socket event.
*/
SOCKET_MSG_SECURE
/*!<
Existing socket made secure event.
*/
} tenuSocketCallbackMsgType;
/*!
@struct \
tstrSocketBindMsg
@ -671,7 +821,7 @@ typedef struct{
/*!<
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.
error code corresponding to @ref SocketErrorCode.
*/
} tstrSocketBindMsg;
@ -690,7 +840,7 @@ 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.
error code corresponding to @ref SocketErrorCode.
*/
} tstrSocketListenMsg;
@ -721,20 +871,21 @@ 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.
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.
Socket ID referring to the socket passed to the @ref connect or @ref secure 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.
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;
@ -744,11 +895,12 @@ typedef struct{
@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.
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
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.
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().
@ -766,7 +918,7 @@ typedef struct{
*/
uint16 u16RemainingSize;
/*!<
The number of bytes remaining in the current @ref recv operation.
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;
/*!<
@ -777,8 +929,8 @@ typedef struct{
/**@defgroup SocketCallbacks Callbacks
* @ingroup SocketHeader
* @{
*/
/**@{*/
/*!
@typedef \
tpfAppSocketCb
@ -803,6 +955,7 @@ typedef struct{
- @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:
@ -829,13 +982,13 @@ typedef void (*tpfAppSocketCb) (SOCKET sock, uint8 u8Msg, void * pvMsg);
@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).
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.
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);
@ -846,7 +999,7 @@ 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.
@ref m2m_ping_req.
@param[in] u32IPAddr
Destination IP.
@ -866,7 +1019,7 @@ typedef void (*tpfPingCb)(uint32 u32IPAddr, uint32 u32RTT, uint8 u8ErrorCode);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/** \defgroup SocketAPI Function
/** @defgroup SocketAPI Functions
* @ingroup SocketHeader
*/
@ -890,7 +1043,7 @@ FUNCTION PROTOTYPES
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
\section socketInit_Ex Example
This example demonstrates the use of the socketinit for socket initialization for an mqtt chat application.
\code
tstrWifiInitParam param;
@ -928,8 +1081,12 @@ 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);
@ -937,10 +1094,15 @@ NMI_API void socketInit(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.
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 +1113,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
@ -959,8 +1121,6 @@ NMI_API uint8 IsSocketReady(void);
* The registered callback functions are used to retrieve information in response to the asynchronous socket functions called.
*/
/**@{*/
/*!
@fn \
NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb resolve_cb);
@ -972,16 +1132,16 @@ NMI_API uint8 IsSocketReady(void);
@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
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 any of the socket functionalities is not to be used, NULL is passed in as a parameter.
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 example
\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
@ -1046,7 +1206,7 @@ NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb re
/**@{*/
/*!
@fn \
NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags);
NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Config);
@param [in] u16Domain
@ -1057,17 +1217,25 @@ 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.
before any call to the @ref socket function can be made.
@see
connect
secure
bind
listen
accept
@ -1087,7 +1255,7 @@ NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb re
@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
\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.
@ -1116,7 +1284,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
@ -1163,7 +1331,7 @@ NMI_API SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8F
- @ref SOCK_ERR_INVALID
Indicate socket bind failure.
\section bind example
\section bind_Ex Example
This example demonstrates the call of the bind socket operation after a successful socket operation.
@code
struct sockaddr_in addr;
@ -1243,7 +1411,7 @@ NMI_API sint8 WINC1500_EXPORT(bind)(SOCKET sock, struct sockaddr *pstrAddr, uint
- @ref SOCK_ERR_INVALID
Indicate socket listen failure.
\section listen example
\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,7 +1514,8 @@ 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.
@ -1367,9 +1536,6 @@ NMI_API sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8
Socket ID, must hold a non negative value.
A negative value will return a socket error @ref SOCK_ERR_INVALID_ARG. Indicating that an invalid argument is passed in.
@param [in] pstrAddr
Address of the remote server.
@param[in] pstrAddr
Pointer to socket address structure @ref sockaddr_in.
@ -1398,7 +1564,7 @@ NMI_API sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8
- @ref SOCK_ERR_INVALID
Indicate socket connect failure.
\section connect example
\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.
@ -1457,7 +1623,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 WINC1500_EXPORT(secure)(SOCKET sock);
/**@}*/ //SecureFn
/** @defgroup ReceiveFn recv
@ingroup SocketAPI
@ -1518,7 +1726,7 @@ NMI_API sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, u
- @ref SOCK_ERR_BUFFER_FULL
Indicate socket receive failure.
\section recv example
\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
@ -1624,7 +1832,7 @@ NMI_API sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16Buf
- @ref SOCK_ERR_BUFFER_FULL
Indicate socket receive failure.
\section recvfrom example
\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
@ -1722,11 +1930,11 @@ NMI_API sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u1
@warning
u16SendLength must not exceed @ref SOCKET_BUFFER_MAX_LENGTH.\n
u16SendLength must not exceed @ref SOCKET_BUFFER_MAX_LENGTH \n
Use a valid socket identifier through the a prior call to the @ref socket function.
Must use a valid buffer pointer.
Successful completion of a call to send() does not guarantee delivery of the message,
A negative return value indicates only locally-detected errors
A negative return value indicates only locally-detected errors.
@see
socketInit
@ -1786,7 +1994,7 @@ NMI_API sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16
Use a valid socket (returned from socket ).
A valid buffer pointer must be used (not NULL).\n
Successful completion of a call to sendto() does not guarantee delivery of the message,
A negative return value indicates only locally-detected errors
A negative return value indicates only locally-detected errors.
@see
socketInit
@ -1909,54 +2117,6 @@ NMI_API sint8 WINC1500_EXPORT(sslEnableCertExpirationCheck)(tenuSslCertExpSettin
* 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.
*
* <p>Possible protocol level values supported are @ref SOL_SOCKET and @ref SOL_SSL_SOCKET.
* Possible options when the protocol level is @ref SOL_SOCKET :</p>
* <table style="width: 100%">
* <tr>
* <td style="height: 22px"><strong>@ref SO_SET_UDP_SEND_CALLBACK</strong></td>
* <td style="height: 22px">Enable/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.</td>
* </tr>
* <tr>
* <td><strong>@ref IP_ADD_MEMBERSHIP</strong></td>
* <td>Valid 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. </td>
* </tr>
* <tr>
* <td><strong>@ref IP_DROP_MEMBERSHIP</strong></td>
* <td>Valid 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.</td>
* </tr>
* </table>
* <p>Possible options when the protocol level&nbsp; is @ref SOL_SSL_SOCKET</p>
* <table style="width: 100%">
* <tr>
* <td style="height: 22px"><strong>
* @ref SO_SSL_BYPASS_X509_VERIF</strong></td>
* <td style="height: 22px">Allow an opened SSL socket to bypass the X509
* certificate verification process. It is highly recommended <strong>NOT</strong> 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.</td>
* </tr>
* <tr>
* <td><strong>@ref SO_SSL_SNI</strong></td>
* <td>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 @ref HOSTNAME_MAX_SIZE.</td>
* </tr>
* <tr>
* <td><strong>@ref SO_SSL_ENABLE_SESSION_CACHING</strong></td>
* <td>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.</td>
* </tr>
* </table>
*/
/**@{*/
/*!
@ -1968,18 +2128,29 @@ NMI_API sint8 WINC1500_EXPORT(sslEnableCertExpirationCheck)(tenuSslCertExpSettin
Socket handler.
@param[in] u8Level
protocol level. See description above.
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.
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.
Pointer to user provided value.
@param[in] u16OptionLen
length of the option value in bytes.
@sa SOL_SOCKET, SOL_SSL_SOCKET, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP
Length of the option value in bytes. Refer to each option documentation for the required length.
@return
The function shall return \ref SOCK_ERR_NO_ERROR for successful operation
@ -2017,7 +2188,6 @@ NMI_API sint8 WINC1500_EXPORT(setsockopt)(SOCKET socket, uint8 u8Level, uint8 op
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.
@ -2038,10 +2208,120 @@ NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8Op
@param[in] fpPingCb
Callback will be called to deliver the ping statistics.
@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

View File

@ -4,7 +4,7 @@
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -32,12 +32,11 @@
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include <stdbool.h>
#include <stddef.h>
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/include/m2m_ota.h"
@ -48,6 +47,7 @@ INCLUDES
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
@ -65,20 +65,27 @@ typedef struct {
static FileBlockDescriptor FileBlock;
static uint8 gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
static uint8 gu8OTASSLOpts = 0;
static uint8 gu8SNIServerName[64] = {0};
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
/* Map OTA SSL flags to SSL socket options */
#define WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH NBIT1
#define WIFI_OTA_SSL_FLAG_SNI_VALIDATION NBIT6
/*=*=*=*=*=*=*=*=*=*=*=*=
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
* @brief 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,7 +147,7 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
if(gpfHFDReadCb)
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.FileBlockSz);
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz);
}
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
{
@ -160,26 +167,19 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
M2M_ERR("Invalid OTA resp %d ?\n", u8OpCode);
}
}
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Initialize the OTA layer.
@fn NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
@brief Initialize the OTA layer.
@param[in] pfOtaUpdateCb
OTA Update callback function
OTA Update callback function.
@param[in] pfOtaNotifCb
OTA Notify callback function
@return
The function SHALL return 0 for success and a negative value otherwise.
OTA Notify callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
{
sint8 ret = M2M_SUCCESS;
if(pfOtaUpdateCb) {
gpfOtaUpdateCb = pfOtaUpdateCb;
} else {
@ -196,18 +196,13 @@ 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
@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.
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)
{
@ -218,18 +213,12 @@ NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
*/
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_SET_URL, u8Url, u16UrlSize, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@brief
check for ota update
@return
The function 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 +228,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
@fn NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
@brief Schedule OTA update.
@param[in] u32Period
Period in days
@return
The function SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
@ -259,39 +242,42 @@ 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
@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.
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)
{
sint8 ret = M2M_SUCCESS;
uint16 u16DurlSize = m2m_strlen(pcDownloadUrl) + 1;
/*Todo: we may change it to data pkt but we need to give it higher priority
but the priority is not implemented yet in data pkt
*/
ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_START_FW_UPDATE,pcDownloadUrl,u16DurlSize,NULL,0,0);
return ret;
tstrOtaStart strOtaStart;
uint16 u16UrlLen = m2m_strlen(pcDownloadUrl);
if (u16UrlLen >= 255)
{
return M2M_ERR_INVALID_ARG;
}
m2m_memset((uint8*)&strOtaStart, 0, sizeof(strOtaStart));
m2m_memcpy((uint8*)&strOtaStart.acUrl, (uint8*)pcDownloadUrl, u16UrlLen);
/* Convert SSL options to flags */
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH)
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH;
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_SNI_VALIDATION)
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_SNI_VALIDATION;
m2m_memcpy((uint8*)&strOtaStart.acSNI, gu8SNIServerName, m2m_strlen(gu8SNIServerName));
strOtaStart.u32TotalLen = sizeof(strOtaStart);
return hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_FW_UPDATE_V2 | M2M_REQ_DATA_PKT, (uint8*)&strOtaStart, strOtaStart.u32TotalLen, NULL, 0, 0);
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@brief
Request OTA Rollback image
@return
The function 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 +287,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 +298,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 +311,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)
{
@ -356,76 +326,16 @@ NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
}
return ret;
}
#if 0
#define M2M_OTA_FILE "../../../m2m_ota.dat"
NMI_API sint8 m2m_ota_test(void)
{
uint32 page = 0;
uint8 buffer[1500];
uint32 u32Sz = 0;
sint8 ret = M2M_SUCCESS;
FILE *fp =NULL;
fp = fopen(M2M_OTA_FILE,"rb");
if(fp)
{
fseek(fp, 0L, SEEK_END);
u32Sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
while(u32Sz > 0)
{
{
page = (rand()%1400);
if((page<100)||(page>1400)) page = 1400;
}
if(u32Sz>page)
{
u32Sz-=page;
}
else
{
page = u32Sz;
u32Sz = 0;
}
printf("page %d\n", (int)page);
fread(buffer,page,1,fp);
ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_TEST|M2M_REQ_DATA_PKT,NULL,0,(uint8*)&buffer,page,0);
if(ret != M2M_SUCCESS)
{
M2M_ERR("\n");
}
nm_bsp_sleep(1);
}
}
else
{
M2M_ERR("nO err\n");
}
return ret;
}
#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,28 +367,18 @@ 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.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in bytes).
@param[in] pfHFDReadCb
Callback to be executed when the read operation completes.
@return
Status of the read operation
@warning 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,38 +396,27 @@ 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.
@param[in] pu8Buff
Pointer to a buffer to store the data being read. Must be valid.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in Bytes).
@return
Status of the read operation
@warning 1. Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
@return Status of the read operation.
@warning Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
mode to allow for a safe access to the Flash. This can be done by calling
@ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read.
2. This functionality is only supported from WINC release 19.6.0 onwards.
*/
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
{
static uint32 u32FlashHFDStart = 0;
static uint32 u32FlashHFDSize = 0;
sint8 s8Ret = M2M_ERR_INVALID_ARG;
if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pu8Buff)) goto EXIT;
if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT;
if(WIFI_STATE_INIT != m2m_wifi_get_state())
{
@ -542,6 +431,10 @@ NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32
if(M2M_SUCCESS != s8Ret) goto EXIT;
}
s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart, 4);
if((M2M_SUCCESS != s8Ret) || (pu8Buff[0] != u8Handler)) goto EXIT;
if((u32Offset >= u32FlashHFDSize) ||
(u32Size > u32FlashHFDSize) ||
((u32Offset + u32Size) >= u32FlashHFDSize))
@ -560,20 +453,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 +467,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)
{
@ -597,3 +481,95 @@ NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDErase
EXIT:
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
@brief Sets SSL related options for OTA via https connections
@param[in] enuOptionName
The SSL option to set, from the set defined in tenuOTASSLOption
@param[in] pOptionValue
Pointer to the option value to set. Either a pointer to a uint32 with the value of 0 or 1, or a pointer to a string for the
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
@param[in] OptionLen
The size of the option referred to in pOptionValue
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
{
if((pOptionValue == NULL) && (OptionLen > 0))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
if(OptionLen > 64)
return M2M_ERR_INVALID_ARG;
if (m2m_strlen((uint8*)pOptionValue)+1 != OptionLen)
return M2M_ERR_INVALID_ARG;
m2m_memcpy(gu8SNIServerName, (uint8*)pOptionValue, OptionLen);
break;
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu8OTASSLOpts |= enuOptionName;
break;
case 0:
gu8OTASSLOpts &= ~enuOptionName;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
/*!
@fn NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *OptionLen)
@brief Gets the status of SSL related options for OTA via https connections
@param[in] enuOptionName
The SSL option to obtain the status of, from the set defined in tenuOTASSLOption
@param[in] pOptionValue
Pointer to the option value to be updated by the function. Either a pointer to a uint32, or a pointer to a buffer for the
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
@param[in] OptionLen
A pointer to a size_t type variable which will be updated to contain the size of the returned option.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
{
if((pOptionValue == NULL) || (pOptionLen == NULL))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu8OTASSLOpts & enuOptionName) ? 1 : 0;
break;
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
{
uint16 sni_len = m2m_strlen(gu8SNIServerName)+1;
if(*pOptionLen < sni_len)
return M2M_ERR_INVALID_ARG;
*pOptionLen = sni_len;
m2m_memcpy((uint8*)pOptionValue, gu8SNIServerName, sni_len);
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}

View File

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

View File

@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi SSL APIs implementation.
*
* Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -32,8 +32,6 @@
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
@ -41,10 +39,6 @@ INCLUDES
#include "driver/include/m2m_ssl.h"
#include "driver/include/m2m_hif.h"
#include "driver/include/nmasic.h"
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
@ -62,8 +56,8 @@ FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief SSL callback function
@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
@ -158,17 +152,37 @@ static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
}
}
/*!
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
genuStatus = TLS_FLASH_ERR_UNKNOWN;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
if(s8Ret != M2M_SUCCESS)
{
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC
@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC.
@param[in] strECCResp
ECC Response struct.
@param [in] pu8RspDataBuffe
@param[in] pu8RspDataBuff
Pointer of the response data to be sent.
@param[in] u16RspDataSz
Response data size.
@return The function SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
{
@ -180,13 +194,13 @@ NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDat
}
/*!
@fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
@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 SHALL return 0 for success and a negative value otherwise.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
{
@ -196,7 +210,10 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
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;
@ -217,14 +234,16 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
// 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 %lu bytes of cert data CHUNKED to offset %lu total %lu\n", thischunksz, ofs, u32BufferSz);
M2M_INFO("Transferred %u bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
@ -234,13 +253,16 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
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 %lu total %lu\n", thischunksz, ofs, u32BufferSz);
M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
}
@ -250,104 +272,195 @@ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
}
/*!
@fn \ m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
@brief Retrieve the certificate to be verified from the WINC
@param [in] pu16CurveType
Pointer to the certificate curve type.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] pu8Sig
Pointer to the certificate signature.
@param [in] pu8Key
Pointer to the certificate Key.
@return The function SHALL return 0 for success and a negative value otherwise.
@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] penuCurve
The named curve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
@param[inout] pu16ValueSz
in: Size of value buffer provided by caller.
out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
@param[out] pu8Sig
Signature retrieved for verification.
@param[inout] pu16SigSz
in: Size of signature buffer provided by caller.
out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey)
{
uint8 bSetRxDone = 1;
sint8 s8Ret = M2M_ERR_FAIL;
uint16 u16HashSz, u16SigSz, u16KeySz;
sint8 s8Ret = M2M_SUCCESS;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if(hif_receive(gu32HIFAddr, (uint8*)pu16CurveType, 2, 0) != M2M_SUCCESS) goto __ERR;
if((NULL == penuCurve) || (NULL == pu8Value) || (NULL == pu16ValueSz) || (NULL == pu8Sig) || (NULL == pu16SigSz) || (NULL == pstrKey))
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
*penuCurve = _htons(u16KeySz);
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
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;
(*pu16CurveType)= _htons((*pu16CurveType));
pu8Key->u16Size = _htons(u16KeySz);
u16HashSz = _htons(u16HashSz);
u16SigSz = _htons(u16SigSz);
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, 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;
if(hif_receive(gu32HIFAddr, pu8Value, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16HashSz;
if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16SigSz;
bSetRxDone = 0;
return M2M_SUCCESS;
__ERR:
if(bSetRxDone)
{
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
return s8Ret;
}
/*!
@fn \ m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
@brief Retrieve the certificate hash
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] u16HashSz
Hash size.
@return The function SHALL return 0 for success and a negative value otherwise.
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] pu16Curve
The named curve, to be cast to type @ref tenuEcNamedCurve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
@param[out] pu8Sig
Signature retrieved for verification.
The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz)
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey)
{
uint8 bSetRxDone = 1;
sint8 s8Ret = M2M_SUCCESS;
uint16 u16ValueSz = 32, u16SigSz = 64;
return m2m_ssl_retrieve_next_for_verifying((tenuEcNamedCurve *)pu16Curve, pu8Value, &u16ValueSz, pu8Sig, &u16SigSz, pstrKey);
}
/*!
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
@brief Retrieve the value from the WINC for ECDSA signing.
@param[out] pu8Value
Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
@param[in] u16ValueSz
Size of value to be retrieved. (The application should obtain this information,
along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
signing information is ready via @ref ECC_REQ_SIGN_GEN.
@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz)
{
sint8 s8Ret = M2M_ERR_FAIL;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
if(NULL == pu8Value)
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
bSetRxDone = 0;
if(hif_receive(gu32HIFAddr, pu8Value, u16ValueSz, 0) != M2M_SUCCESS) goto __ERR;
return M2M_SUCCESS;
__ERR:
if(bSetRxDone)
{
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
return s8Ret;
}
/*!
@fn \ m2m_ssl_stop_processing_certs(void)
@brief Stops receiving from the HIF
@fn NMI_API void m2m_ssl_stop_retrieving(void);
@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
information.
@return None.
@warning The application must call this function if it has been notified (via
@ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
retrieving from the WINC, but chooses not to retrieve it all.
The application must not call this function if it has retrieved all the available
information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
remaining information has been lost.
@see m2m_ssl_retrieve_next_for_verifying\n
m2m_ssl_retrieve_cert\n
m2m_ssl_retrieve_hash
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
NMI_API void m2m_ssl_stop_retrieving(void)
{
hif_receive(0, NULL, 0, 1);
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
}
/*!
@fn \ m2m_ssl_ecc_process_done(void)
@brief Stops receiving from the HIF
@fn NMI_API void m2m_ssl_stop_processing_certs(void);
@brief Allow SSL driver to tidy up in case application does not read all available certificates.
@return None.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_stop_retrieving is used instead.
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
{
m2m_ssl_stop_retrieving();
}
/*!
@fn NMI_API void m2m_ssl_ecc_process_done(void);
@brief Allow SSL driver to tidy up after application has finished processing ECC message.
@return None.
@warning The application should call this function after receiving an SSL callback with message
type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
calling @ref m2m_ssl_handshake_rsp.
*/
NMI_API void m2m_ssl_ecc_process_done(void)
{
@ -355,9 +468,9 @@ NMI_API void m2m_ssl_ecc_process_done(void)
}
/*!
@fn \
m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
@fn NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
@brief Sets the active ciphersuites.
@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
a bitmap containing the required ciphers to be on.
There is no need to call this function if the application will not change the default ciphersuites.
@ -365,16 +478,15 @@ NMI_API void m2m_ssl_ecc_process_done(void)
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination, except for combinations involving both RSA
and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
be changed.
change.
@return
- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
- @ref SOCK_ERR_NO_ERROR
- @ref SOCK_ERR_INVALID_ARG
*/
sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
{
sint8 s8Ret = M2M_SUCCESS;
tstrSslSetActiveCsList strCsList;
@ -384,26 +496,3 @@ sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
return s8Ret;
}
/*!
@fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
genuStatus = TLS_FLASH_ERR_UNKNOWN;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL,m2m_ssl_cb);
if (s8Ret != M2M_SUCCESS)
{
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}

View File

@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -39,17 +39,34 @@
#include "driver/include/m2m_hif.h"
#include "driver/include/nmasic.h"
/**
* \defgroup winc1500_group WINC1500 (Wi-Fi)
*
* \{
*/
/* 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 gu8scanInProgress = 0;
static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT;
static tpfAppWifiCb gpfAppWifiCb = NULL;
static volatile uint8 gu8scanInProgress = 0;
static uint32 gu321xTlsHsFlags = WIFI_1X_TLS_HS_FLAGS_DEFAULT;
static uint8 gau81xRootSha1[20] = {0};
#ifdef ETH_MODE
static tpfAppEthCb gpfAppEthCb = NULL;
@ -58,19 +75,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)
{
@ -150,7 +164,6 @@ static void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
BYTE_0(u32ConflictedIP), BYTE_1(u32ConflictedIP), BYTE_2(u32ConflictedIP), BYTE_3(u32ConflictedIP));
if(gpfAppWifiCb)
gpfAppWifiCb(M2M_WIFI_RESP_IP_CONFLICT, NULL);
}
}
else if(u8OpCode == M2M_WIFI_RESP_SCAN_DONE)
@ -233,7 +246,7 @@ static void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
uint8 u8SetRxDone;
tstrM2mIpRsvdPkt strM2mRsvd;
if(hif_receive(u32Addr, (uint8 *)&strM2mRsvd ,sizeof(tstrM2mIpRsvdPkt), 0) == M2M_SUCCESS)
if(hif_receive(u32Addr, &strM2mRsvd, sizeof(tstrM2mIpRsvdPkt), 0) == M2M_SUCCESS)
{
tstrM2mIpCtrlBuf strM2mIpCtrlBuf;
uint16 u16Offset = strM2mRsvd.u16PktOffset;
@ -329,30 +342,10 @@ static sint8 m2m_validate_ap_parameters(CONST tstrM2MAPModeConfig* pstrM2MAPMode
}
else if(pstrM2MAPModeConfig->strApConfig.u8SecType == M2M_WIFI_SEC_WEP)
{
/* Check for WEP Key index */
if((pstrM2MAPModeConfig->strApConfig.u8KeyIndx == 0) || (pstrM2MAPModeConfig->strApConfig.u8KeyIndx > WEP_KEY_MAX_INDEX))
{
M2M_ERR("INVALID KEY INDEX\n");
/* As of 19.7.5 the WEP protocol is deprecated */
s8Ret = M2M_ERR_FAIL;
goto ERR1;
}
/* Check for WEP Key size */
if( (pstrM2MAPModeConfig->strApConfig.u8KeySz != WEP_40_KEY_STRING_SIZE) &&
(pstrM2MAPModeConfig->strApConfig.u8KeySz != WEP_104_KEY_STRING_SIZE)
)
{
M2M_ERR("INVALID KEY STRING SIZE\n");
s8Ret = M2M_ERR_FAIL;
goto ERR1;
}
if((m2m_strlen((uint8 *)pstrM2MAPModeConfig->strApConfig.au8WepKey) <= 0) || (m2m_strlen((uint8 *)pstrM2MAPModeConfig->strApConfig.au8WepKey) > WEP_104_KEY_STRING_SIZE))
{
M2M_ERR("INVALID KEY SIZE\n");
s8Ret = M2M_ERR_FAIL;
goto ERR1;
}
}
else if(pstrM2MAPModeConfig->strApConfig.u8SecType == M2M_WIFI_SEC_WPA_PSK)
{
/* Check for WPA Key size */
@ -373,6 +366,7 @@ static sint8 m2m_validate_ap_parameters(CONST tstrM2MAPModeConfig* pstrM2MAPMode
ERR1:
return s8Ret;
}
static sint8 m2m_validate_scan_options(tstrM2MScanOption *ptstrM2MScanOption)
{
sint8 s8Ret = M2M_SUCCESS;
@ -422,16 +416,15 @@ sint8 m2m_wifi_send_crl(tstrTlsCrlInfo* pCRL)
return s8Ret;
}
sint8 m2m_wifi_init_hold()
sint8 m2m_wifi_init_hold(void)
{
sint8 ret = M2M_ERR_FAIL;
/* Apply device specific initialization. */
ret = nm_drv_init_hold();
if(M2M_SUCCESS == ret) {
if(M2M_SUCCESS == ret)
gu8WifiState = WIFI_STATE_INIT;
}
return ret;
}
@ -617,36 +610,6 @@ INVALID_ARG:
return M2M_ERR_INVALID_ARG;
}
/* Convert hexchar to value 0-15 */
static uint8 hexchar_2_val(uint8 ch)
{
ch -= 0x30;
if (ch <= 9)
return ch;
ch |= 0x20;
ch -= 0x31;
if (ch <= 5)
return ch + 10;
return 0xFF;
}
/* Convert hexstring to bytes */
static sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
{
while (u8SizeOut--)
{
uint8 u8Out = hexchar_2_val(*pu8In++);
if (u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out = u8Out * 0x10;
u8Out = hexchar_2_val(*pu8In++);
if (u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out += u8Out;
pu8Out++;
}
return M2M_SUCCESS;
}
/*************************************************************************************************/
/* WIFI CONNECT APIS */
/*************************************************************************************************/
@ -674,35 +637,8 @@ sint8 m2m_wifi_connect_wep(
tstrAuthWep *pstrAuthWep
)
{
sint8 ret = M2M_ERR_INVALID_ARG;
if (
(pstrAuthWep != NULL) && (pstrAuthWep->pu8WepKey != NULL)
&& (pstrAuthWep->u8KeyIndx > 0) && (pstrAuthWep->u8KeyIndx <= WEP_KEY_MAX_INDEX)
&& ((pstrAuthWep->u8KeySz == WEP_104_KEY_STRING_SIZE) || (pstrAuthWep->u8KeySz == WEP_40_KEY_STRING_SIZE))
)
{
tstrM2mWifiConnHdr strConnHdr;
ret = m2m_wifi_connect_prepare_msg( enuCredStoreOption,
M2M_WIFI_SEC_WEP,
sizeof(tstrM2mWifiWep),
pstrNetworkId,
&strConnHdr);
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);
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;
/* As of 19.7.5 the WEP protocol is deprecated */
return M2M_ERR_INVALID;
}
sint8 m2m_wifi_connect_psk(
@ -725,19 +661,21 @@ sint8 m2m_wifi_connect_psk(
if(ret == M2M_SUCCESS)
{
tstrM2mWifiPsk pstrPsk;
m2m_memset((uint8*)&pstrPsk, 0, sizeof(tstrM2mWifiPsk));
tstrM2mWifiPsk *pstrPsk = (tstrM2mWifiPsk *) fb_alloc(sizeof(tstrM2mWifiPsk), 0);
if(pstrPsk != NULL)
{
m2m_memset((uint8 *)pstrPsk, 0, sizeof(tstrM2mWifiPsk));
if(pstrAuthPsk->pu8Psk != NULL)
{
if(pstrAuthPsk->pu8Passphrase != NULL)
ret = M2M_ERR_INVALID_ARG;
else
{
pstrPsk.u8PassphraseLen = M2M_MAX_PSK_LEN-1;
pstrPsk->u8PassphraseLen = M2M_MAX_PSK_LEN-1;
/* Use hexstr_2_bytes to verify pu8Psk input. */
if (M2M_SUCCESS != hexstr_2_bytes(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen/2))
if(M2M_SUCCESS != hexstr_2_bytes(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen/2))
ret = M2M_ERR_INVALID_ARG;
m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen);
m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen);
}
}
else if(pstrAuthPsk->pu8Passphrase != NULL)
@ -746,8 +684,8 @@ sint8 m2m_wifi_connect_psk(
ret = M2M_ERR_INVALID_ARG;
else
{
pstrPsk.u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk.u8PassphraseLen);
pstrPsk->u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk->u8PassphraseLen);
}
}
else
@ -756,13 +694,141 @@ sint8 m2m_wifi_connect_psk(
{
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));
(uint8 *)pstrPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr));
}
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
return ret;
}
sint8 m2m_wifi_1x_set_option(tenu1xOption enuOptionName, const void *pOptionValue, size_t OptionLen)
{
if((pOptionValue == NULL) && (OptionLen > 0))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_1X_BYPASS_SERVER_AUTH:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
break;
case 0:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_TIME_VERIF_MODE:
if(OptionLen != sizeof(tenuSslCertExpSettings))
return M2M_ERR_INVALID_ARG;
switch(*(tenuSslCertExpSettings*)pOptionValue)
{
case SSL_CERT_EXP_CHECK_DISABLE:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
case SSL_CERT_EXP_CHECK_ENABLE:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
case SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_SESSION_CACHING:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
break;
case 0:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
case WIFI_1X_SPECIFIC_ROOTCERT:
switch(OptionLen)
{
case 20:
gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
m2m_memcpy(gau81xRootSha1, (uint8*)pOptionValue, sizeof(gau81xRootSha1));
break;
case 0:
gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
m2m_memset(gau81xRootSha1, 0, sizeof(gau81xRootSha1));
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
sint8 m2m_wifi_1x_get_option(tenu1xOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
{
if(pOptionValue == NULL)
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_1X_BYPASS_SERVER_AUTH:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_AUTH) ? 0 : 1;
break;
case WIFI_1X_TIME_VERIF_MODE:
if(*pOptionLen < sizeof(tenuSslCertExpSettings))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(tenuSslCertExpSettings);
if(!(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK))
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_DISABLE;
else if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME)
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_ENABLE;
else
*(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME;
break;
case WIFI_1X_SESSION_CACHING:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING) ? 1 : 0;
break;
case WIFI_1X_SPECIFIC_ROOTCERT:
if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT)
{
if(*pOptionLen < sizeof(gau81xRootSha1))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(gau81xRootSha1);
m2m_memcpy((uint8*)pOptionValue, gau81xRootSha1, sizeof(gau81xRootSha1));
}
else
*pOptionLen = 0;
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
sint8 m2m_wifi_connect_1x_mschap2(
tenuCredStoreOption enuCredStoreOption,
tstrNetworkId *pstrNetworkId,
@ -807,6 +873,10 @@ sint8 m2m_wifi_connect_1x_mschap2(
if(pstrAuth1xMschap2->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
pstr1xHdr->u8DomainLength = 0;
if(pstrAuth1xMschap2->pu8Domain != NULL)
{
@ -815,9 +885,9 @@ sint8 m2m_wifi_connect_1x_mschap2(
pu8AuthPtr += pstr1xHdr->u8DomainLength;
}
pstr1xHdr->u16UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u16UserNameLength);
pu8AuthPtr += pstr1xHdr->u16UserNameLength;
pstr1xHdr->u8UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u8UserNameLength);
pu8AuthPtr += pstr1xHdr->u8UserNameLength;
pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
pstr1xHdr->u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen;
@ -829,6 +899,8 @@ sint8 m2m_wifi_connect_1x_mschap2(
sizeof(tstrM2mWifiConnHdr));
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
}
@ -886,6 +958,10 @@ tstrAuth1xTls *pstrAuth1xTls
if(pstrAuth1xTls->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
pstr1xHdr->u8DomainLength = 0;
if(pstrAuth1xTls->pu8Domain != NULL)
{
@ -894,9 +970,9 @@ tstrAuth1xTls *pstrAuth1xTls
pu8AuthPtr += pstr1xHdr->u8DomainLength;
}
pstr1xHdr->u16UserNameLength = (pstrAuth1xTls->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u16UserNameLength);
pu8AuthPtr += pstr1xHdr->u16UserNameLength;
pstr1xHdr->u8UserNameLength = (pstrAuth1xTls->u16UserNameLen);
m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u8UserNameLength);
pu8AuthPtr += pstr1xHdr->u8UserNameLength;
pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen;
@ -925,6 +1001,8 @@ tstrAuth1xTls *pstrAuth1xTls
}
fb_free();
}
else
ret = M2M_ERR_MEM_ALLOC;
}
}
}
@ -947,11 +1025,9 @@ sint8 m2m_wifi_connect_sc(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *
* to strlen(pcSsid) and continue. This is to avoid a change from the behaviour of previously
* released drivers. */
if(u8SsidLen < M2M_MAX_SSID_LEN)
{
while(u8SsidLen--)
if (strNetworkId.pu8Ssid[u8SsidLen] == 0){
strNetworkId.u8SsidLen = u8SsidLen;}
}
if(strNetworkId.pu8Ssid[u8SsidLen] == 0)
strNetworkId.u8SsidLen = u8SsidLen;
switch((tenuM2mSecType)u8SecType)
{
@ -1042,6 +1118,7 @@ sint8 m2m_wifi_request_dhcp_server(uint8* addr)
/*legacy API should be removed */
return 0;
}
/*!
@fn NMI_API sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt * pstrM2mLsnInt);
@brief Set the Wi-Fi listen interval for power save operation. It is represented in units
@ -1055,12 +1132,9 @@ sint8 m2m_wifi_request_dhcp_server(uint8* addr)
*/
sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn)
{
uint8 u8Req;
u8Req = u8DhcpEn ? M2M_IP_REQ_ENABLE_DHCP : M2M_IP_REQ_DISABLE_DHCP;
return hif_send(M2M_REQ_GROUP_IP, u8Req, NULL, 0, NULL, 0, 0);
}
sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt)
@ -1070,7 +1144,6 @@ sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt* pstrM2mLsnInt)
sint8 m2m_wifi_set_cust_InfoElement(uint8 *pau8M2mCustInfoElement)
{
sint8 ret = M2M_ERR_FAIL;
if(pau8M2mCustInfoElement != NULL)
{
@ -1091,6 +1164,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;
@ -1216,20 +1312,19 @@ sint8 m2m_wifi_wps_disable(void)
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_WPS, NULL, 0, NULL, 0, 0);
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
@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 SHALL return M2M_SUCCESS for success and a negative value otherwise.
Control command sent from PS Server to PS Client (command values defined by the application).
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa m2m_wifi_req_server_init, M2M_WIFI_RESP_CLIENT_INFO
@pre m2m_wifi_req_server_init should be called first
@warning
*/
sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
{
sint8 ret = M2M_SUCCESS;
#ifdef _PS_SERVER_
tstrM2Mservercmd strCmd;
@ -1240,15 +1335,16 @@ sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
#endif
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
@fn NMI_API sint8 m2m_wifi_req_server_init(uint8 ch)
@brief Initialize the PS Server, The WINC support non secure communication with another WINC,
(SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup.
@param[in] ch
Server listening channel
@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@sa m2m_wifi_req_client_ctrl
@warning The server mode can't be used with any other modes (STA/P2P/AP)
@warning The server mode can't be used with any other modes (STA/AP).
*/
sint8 m2m_wifi_req_server_init(uint8 ch)
{
@ -1262,6 +1358,7 @@ sint8 m2m_wifi_req_server_init(uint8 ch)
#endif
return ret;
}
sint8 m2m_wifi_p2p(uint8 u8Channel)
{
sint8 ret = M2M_SUCCESS;
@ -1278,6 +1375,7 @@ sint8 m2m_wifi_p2p(uint8 u8Channel)
}
return ret;
}
sint8 m2m_wifi_p2p_disconnect(void)
{
sint8 ret = M2M_SUCCESS;
@ -1290,9 +1388,9 @@ sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig)
tstrM2MAPModeConfig strM2MAPModeConfig;
m2m_memcpy((uint8 *)&strM2MAPModeConfig.strApConfig, (uint8 *)pstrM2MAPConfig, sizeof(tstrM2MAPConfig));
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DefRouterIP, pstrM2MAPConfig->au8DHCPServerIP, 4);
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DNSServerIP, pstrM2MAPConfig->au8DHCPServerIP, 4);
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DefRouterIP, (uint8 *)pstrM2MAPConfig->au8DHCPServerIP, 4);
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DNSServerIP, (uint8 *)pstrM2MAPConfig->au8DHCPServerIP, 4);
strM2MAPModeConfig.strApConfigExt.au8SubnetMask[0] = 0;
return m2m_wifi_enable_ap_ext(&strM2MAPModeConfig);
@ -1317,12 +1415,14 @@ sint8 m2m_wifi_set_gains(tstrM2mWifiGainsParams* pstrM2mGain)
}
return ret;
}
sint8 m2m_wifi_disable_ap(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_AP, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_req_curr_rssi(void);
@brief Request the current RSSI for the current connected AP,
@ -1350,6 +1450,7 @@ sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize)
}
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid);
@brief Request the MAC address stored on the OTP (one time programmable) memory of the device.
@ -1377,6 +1478,7 @@ sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8* pu8IsValid)
}
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr)
@brief Request the current MAC address of the device (the working mac address).
@ -1399,9 +1501,9 @@ sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr)
ret = hif_chip_sleep();
}
}
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_req_scan_result(uint8 index);
@brief Reads the AP information from the Scan Result list with the given index,
@ -1418,7 +1520,6 @@ sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr)
which mean if large delay occur between the scan request and the scan result request,
the result will not be up-to-date
*/
sint8 m2m_wifi_req_scan_result(uint8 index)
{
sint8 ret = M2M_SUCCESS;
@ -1427,6 +1528,7 @@ sint8 m2m_wifi_req_scan_result(uint8 index)
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN_RESULT, (uint8 *) &strReqScanRlt, sizeof(tstrM2mReqScanResult), NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API uint8 m2m_wifi_get_num_ap_found(void);
@brief Reads the number of AP's found in the last Scan Request,
@ -1443,6 +1545,7 @@ uint8 m2m_wifi_get_num_ap_found(void)
{
return gu8ChNum;
}
/*!
@fn NMI_API uint8 m2m_wifi_get_sleep_mode(void);
@brief Get the current Power save mode.
@ -1453,6 +1556,7 @@ uint8 m2m_wifi_get_sleep_mode(void)
{
return hif_get_sleep_mode();
}
/*!
@fn NMI_API sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn);
@brief Set the power saving mode for the WINC1500.
@ -1478,9 +1582,10 @@ sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn)
hif_set_sleep_mode(PsTyp);
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).
@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.
@ -1500,9 +1605,10 @@ 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.
@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
@ -1544,7 +1650,6 @@ sint8 m2m_wifi_configure_sntp(uint8 *pu8NTPServerName, uint8 u8NTPServerNameLeng
m2m_memcpy((uint8 *)strSNTPConfig.acNTPServer, pu8NTPServerName, u8NTPServerNameLength);
strSNTPConfig.acNTPServer[u8NTPServerNameLength] = '\0';
strSNTPConfig.enuUseDHCP = useDHCP;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONFIG_SNTP,
@ -1568,9 +1673,9 @@ sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrM2MAPConfig, char *pcHt
tstrM2MAPModeConfig strM2MAPModeConfig;
m2m_memcpy((uint8 *)&strM2MAPModeConfig.strApConfig, (uint8 *)pstrM2MAPConfig, sizeof(tstrM2MAPConfig));
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DefRouterIP, pstrM2MAPConfig->au8DHCPServerIP, 4);
m2m_memcpy(strM2MAPModeConfig.strApConfigExt.au8DNSServerIP, pstrM2MAPConfig->au8DHCPServerIP, 4);
strM2MAPModeConfig.strApConfigExt.au8SubnetMask[0] = 0;
return m2m_wifi_start_provision_mode_ext(&strM2MAPModeConfig, pcHttpServerDomainName, bEnableHttpRedirect);
@ -1643,10 +1748,10 @@ sint8 m2m_wifi_get_system_time(void)
sint8 m2m_wifi_enable_sntp(uint8 bEnable)
{
uint8 u8Req;
u8Req = bEnable ? M2M_WIFI_REQ_ENABLE_SNTP_CLIENT : M2M_WIFI_REQ_DISABLE_SNTP_CLIENT;
return hif_send(M2M_REQ_GROUP_WIFI, u8Req, NULL, 0, NULL, 0, 0);
}
/*!
@fn NMI_API sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode);
@brief Change the power profile mode
@ -1666,6 +1771,7 @@ sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode)
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_POWER_PROFILE, (uint8 *)&strM2mPwrMode, sizeof(tstrM2mPwrMode), NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel);
@brief set the TX power tenuM2mTxPwrLevel
@ -1743,6 +1849,7 @@ sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100)
ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_BATTERY_VOLTAGE, (uint8 *)&strM2mBattVol, sizeof(tstrM2mBatteryVoltage), NULL, 0, 0);
return ret;
}
/*!
@fn sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
@brief Get random bytes using the PRNG bytes.
@ -1756,7 +1863,10 @@ sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
{
sint8 ret = M2M_ERR_FAIL;
tstrPrng strRng = {0};
if((u16PrngSize < (M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)))&&(pu8PrngBuff != NULL))
if(
(u16PrngSize <= (M2M_HIF_MAX_PACKET_SIZE - (M2M_HIF_HDR_OFFSET + sizeof(tstrPrng))))
&& (pu8PrngBuff != NULL)
)
{
strRng.u16PrngSize = u16PrngSize;
strRng.pu8RngBuff = pu8PrngBuff;
@ -1780,8 +1890,14 @@ sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
@param [in] pstrConfAutoRate
The Auto rate configuration parameters as listed in tstrConfAutoRate.
@warning
The application will be responsible for keeping track of what values are set and, if required,
going back to default values. Changes will become permanent until the chip is power-cycled.
@sa
tstrConfAutoRate
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
@ -1789,7 +1905,6 @@ sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
NMI_API sint8 m2m_wifi_conf_auto_rate(tstrConfAutoRate *pstrConfAutoRate)
{
sint8 s8ret = M2M_ERR_FAIL;
s8ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONG_AUTO_RATE, (uint8 *)pstrConfAutoRate, sizeof(tstrConfAutoRate), NULL, 0, 0);
return s8ret;
@ -1899,9 +2014,26 @@ sint8 m2m_wifi_enable_roaming(uint8 bEnableDhcp)
return M2M_ERR_INVALID_ARG;
}
}
sint8 m2m_wifi_disable_roaming(void)
{
tstrM2mWiFiRoaming strWiFiRoaming;
strWiFiRoaming.u8EnableRoaming = 0;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ROAMING, (uint8 *) &strWiFiRoaming, sizeof(tstrM2mWiFiRoaming), NULL, 0, 0);
}
sint8 m2m_wifi_enable_XO_during_sleep(uint8 bXOSleepEnable)
{
tstrM2mWiFiXOSleepEnable strM2mWiFiXOSleepEnable;
if(0 == bXOSleepEnable || 1 == bXOSleepEnable)
{
strM2mWiFiXOSleepEnable.u8EnableXODuringSleep = bXOSleepEnable;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_XO_SLEEP_ENABLE,
(uint8 *) &strM2mWiFiXOSleepEnable, sizeof(strM2mWiFiXOSleepEnable), NULL, 0, 0);
}
else
{
return M2M_ERR_INVALID_ARG;
}
}

View File

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

View File

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

View File

@ -310,6 +310,8 @@ sint8 chip_wake(void)
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, clk_status_reg = 0,trials = 0;
nm_bus_speed(LOW);
ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
@ -353,6 +355,7 @@ sint8 chip_wake(void)
nm_bus_reset();
_WAKE_EXIT:
nm_bus_speed(HIGH);
return ret;
}
sint8 cpu_halt(void)

View File

@ -297,8 +297,8 @@ sint8 nm_drv_init_hold(void)
return ret;
#ifdef NO_HW_CHIP_EN
ERR2:
nm_bus_iface_deinit();
#endif
nm_bus_iface_deinit();
ERR1:
return ret;
}

View File

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

View File

@ -4,7 +4,7 @@
*
* \brief BSD compatible socket interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -70,6 +70,7 @@ MACROS
#define SSL_FLAGS_CACHE_SESSION NBIT4
#define SSL_FLAGS_NO_TX_COPY NBIT5
#define SSL_FLAGS_CHECK_SNI NBIT6
#define SSL_FLAGS_DELAY NBIT7
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
PRIVATE DATA TYPES
@ -97,6 +98,9 @@ typedef struct{
uint8 bIsUsed;
uint8 u8SSLFlags;
uint8 bIsRecvPending;
uint8 u8AlpnStatus;
uint8 u8ErrSource;
uint8 u8ErrCode;
} tstrSocket;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
@ -112,7 +116,9 @@ volatile uint16 gu16SessionID = 0;
volatile tpfAppSocketCb gpfAppSocketCb;
volatile tpfAppResolveCb gpfAppResolveCb;
volatile uint8 gbSocketInit = 0;
volatile tpfPingCb gfpPingCb;
static tpfPingCb gfpPingCb = NULL;
static uint32 gu32PingId = 0;
/*********************************************************************
Function
@ -136,56 +142,42 @@ Date
*********************************************************************/
NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv, uint8 u8SocketMsg,
uint32 u32StartAddress, uint16 u16ReadCount)
{
if((u16ReadCount > 0) && (gastrSockets[sock].pu8UserBuffer != NULL) && (gastrSockets[sock].u16UserBufferSize > 0) && (gastrSockets[sock].bIsUsed == 1))
{
uint32 u32Address = u32StartAddress;
uint16 u16Read;
sint16 s16Diff;
uint8 u8SetRxDone;
pstrRecv->u16RemainingSize = u16ReadCount;
do
if((u16ReadCount > 0) && (gastrSockets[sock].pu8UserBuffer != NULL) && (gastrSockets[sock].u16UserBufferSize > 0) && (gastrSockets[sock].bIsUsed == 1))
{
u8SetRxDone = 1;
u16Read = u16ReadCount;
s16Diff = u16Read - gastrSockets[sock].u16UserBufferSize;
if(s16Diff > 0)
{
u8SetRxDone = 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. */
u16Read = gastrSockets[sock].u16UserBufferSize;
}
if(hif_receive(u32Address, gastrSockets[sock].pu8UserBuffer, u16Read, u8SetRxDone) == M2M_SUCCESS)
if(hif_receive(u32Address, gastrSockets[sock].pu8UserBuffer, u16Read, 1) == M2M_SUCCESS)
{
pstrRecv->pu8Buffer = gastrSockets[sock].pu8UserBuffer;
pstrRecv->s16BufferSize = u16Read;
pstrRecv->u16RemainingSize -= u16Read;
gastrSockets[sock].u16UserBufferSize = 0;
gastrSockets[sock].pu8UserBuffer = NULL;
if(gpfAppSocketCb)
gpfAppSocketCb(sock, u8SocketMsg, pstrRecv);
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);
M2M_ERR("Current <%d>\n", u16ReadCount);
}
}
}
/*********************************************************************
Function
m2m_ip_cb
@ -237,7 +229,7 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
tstrSocketAcceptMsg strAccept;
if(hif_receive(u32Address, (uint8 *)&strAcceptReply, sizeof(tstrAcceptReply), 0) == M2M_SUCCESS)
{
if(strAcceptReply.sConnectedSock >= 0)
if((strAcceptReply.sConnectedSock >= 0) && (strAcceptReply.sConnectedSock < MAX_SOCKET))
{
gastrSockets[strAcceptReply.sConnectedSock].u8SSLFlags = gastrSockets[strAcceptReply.sListenSock].u8SSLFlags;
gastrSockets[strAcceptReply.sConnectedSock].bIsUsed = 1;
@ -260,20 +252,42 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
gpfAppSocketCb(strAcceptReply.sListenSock, SOCKET_MSG_ACCEPT, &strAccept);
}
}
else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT))
else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT_ALPN))
{
tstrConnectReply strConnectReply;
/* Note that for successful connections the fw always sends SOCKET_CMD_CONNECT, even for SSL connections. */
tstrConnectAlpnReply strConnectAlpnReply = {{0}};
tstrSocketConnectMsg strConnMsg;
if(hif_receive(u32Address, (uint8*)&strConnectReply, sizeof(tstrConnectReply), 0) == M2M_SUCCESS)
uint16 u16HifSz = sizeof(tstrConnectAlpnReply);
if(u8OpCode != SOCKET_CMD_SSL_CONNECT_ALPN)
u16HifSz = sizeof(tstrConnectReply);
if(hif_receive(u32Address, (uint8*)&strConnectAlpnReply, u16HifSz, 0) == M2M_SUCCESS)
{
strConnMsg.sock = strConnectReply.sock;
strConnMsg.s8Error = strConnectReply.s8Error;
if(strConnectReply.s8Error == SOCK_ERR_NO_ERROR)
if((strConnectAlpnReply.strConnReply.sock >= 0) && (strConnectAlpnReply.strConnReply.sock < MAX_SOCKET))
{
gastrSockets[strConnectReply.sock].u16DataOffset = strConnectReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET;
uint8 u8Msg = SOCKET_MSG_CONNECT;
strConnMsg.sock = strConnectAlpnReply.strConnReply.sock;
strConnMsg.s8Error = strConnectAlpnReply.strConnReply.s8Error;
/* If the SOCKET_CMD_SSL_CONNECT op code is received and the socket was already connected, then the
callback corresponds to an attempt to make the socket secure. */
if(0 != gastrSockets[strConnMsg.sock].u16DataOffset)
{
u8Msg = SOCKET_MSG_SECURE;
}
if(strConnectAlpnReply.strConnReply.s8Error == SOCK_ERR_NO_ERROR)
{
gastrSockets[strConnMsg.sock].u16DataOffset = strConnectAlpnReply.strConnReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET;
gastrSockets[strConnMsg.sock].u8AlpnStatus = strConnectAlpnReply.u8AppProtocolIdx;
}
else
{
gastrSockets[strConnMsg.sock].u8ErrSource = strConnectAlpnReply.strConnReply.u8ErrSource;
gastrSockets[strConnMsg.sock].u8ErrCode = strConnectAlpnReply.strConnReply.u8ErrCode;
}
if(gpfAppSocketCb)
gpfAppSocketCb(strConnectReply.sock,SOCKET_MSG_CONNECT, &strConnMsg);
gpfAppSocketCb(strConnMsg.sock, u8Msg, &strConnMsg);
}
}
}
else if(u8OpCode == SOCKET_CMD_DNS_RESOLVE)
@ -302,6 +316,8 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
*/
u16ReadSize = sizeof(tstrRecvReply);
if(hif_receive(u32Address, (uint8 *)&strRecvReply, u16ReadSize, 0) == M2M_SUCCESS)
{
if((strRecvReply.sock >= 0) && (strRecvReply.sock < MAX_SOCKET))
{
uint16 u16SessionID = 0;
@ -327,8 +343,9 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
u32Address += u16DataOffset;
/* Read the Application data and deliver it to the application callback in
the given application buffer. If the buffer is smaller than the received data,
the data is passed to the application in chunks according to its buffer size.
the given application buffer. Firmware since 19.6.4 only sends data up to
the size of the application buffer. For TCP, a new call to recv is needed
in order to retrieve any outstanding data from firmware.
*/
u16ReadSize = (uint16)s16RecvStatus;
Socket_ReadSocketData(sock, &strRecvMsg, u8CallbackMsgID, u32Address, u16ReadSize);
@ -347,11 +364,8 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
{
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");
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS)
M2M_ERR("hif rx done failed\n");
}
}
}
@ -367,6 +381,8 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
u8CallbackMsgID = SOCKET_MSG_SENDTO;
if(hif_receive(u32Address, (uint8 *)&strReply, sizeof(tstrSendReply), 0) == M2M_SUCCESS)
{
if((strReply.sock >=0) && (strReply.sock < MAX_SOCKET))
{
uint16 u16SessionID = 0;
@ -387,19 +403,20 @@ static void m2m_ip_cb(uint8 u8OpCode, uint16 u16BufferSize,uint32 u32Address)
}
}
}
}
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)
if((gu32PingId == strPingReply.u32CmdPrivate) && (gfpPingCb != NULL))
{
gfpPingCb(strPingReply.u32IPAddr, strPingReply.u32RTT, strPingReply.u8ErrorCode);
}
}
}
}
/*********************************************************************
Function
socketInit
@ -428,6 +445,7 @@ void socketInit(void)
gu16SessionID = 0;
}
}
/*********************************************************************
Function
socketDeinit
@ -498,7 +516,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,17 +572,21 @@ SOCKET WINC1500_EXPORT(socket)(uint16 u16Domain, uint8 u8Type, uint8 u8Flags)
pstrSock->u16SessionID = gu16SessionID;
M2M_INFO("Socket %d session ID = %d\r\n", sock, gu16SessionID);
if(u8Flags & SOCKET_FLAGS_SSL)
if((u8Type == SOCK_STREAM) && (u8Config != SOCKET_CONFIG_SSL_OFF))
{
tstrSSLSocketCreateCmd strSSLCreate;
strSSLCreate.sslSock = sock;
pstrSock->u8SSLFlags = SSL_FLAGS_ACTIVE | SSL_FLAGS_NO_TX_COPY;
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
bind
@ -587,7 +609,7 @@ Date
sint8 WINC1500_EXPORT(bind)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((pstrAddr != NULL) && (sock >= 0) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
if((pstrAddr != NULL) && (sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
{
tstrBindCmd strBind;
uint8 u8CMD = SOCKET_CMD_BIND;
@ -610,6 +632,7 @@ sint8 WINC1500_EXPORT(bind)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8Addr
}
return s8Ret;
}
/*********************************************************************
Function
listen
@ -633,7 +656,7 @@ sint8 WINC1500_EXPORT(listen)(SOCKET sock, uint8 backlog)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
tstrListenCmd strListen;
@ -671,7 +694,7 @@ sint8 WINC1500_EXPORT(accept)(SOCKET sock, struct sockaddr *addr, uint8 *addrlen
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1) )
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
s8Ret = SOCK_ERR_NO_ERROR;
}
@ -699,7 +722,7 @@ Date
sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
if((sock >= 0) && (sock < MAX_SOCKET) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0))
{
tstrConnectCmd strConnect;
uint8 u8Cmd = SOCKET_CMD_CONNECT;
@ -721,6 +744,52 @@ sint8 WINC1500_EXPORT(connect)(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8A
return s8Ret;
}
/*********************************************************************
Function
secure
Description
Make secure (TLS) an open TCP client connection.
Return
Author
Matthew Gunton
Version
1.0
Date
7 November 2019
*********************************************************************/
sint8 WINC1500_EXPORT(secure)(SOCKET sock)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY)
&& (gastrSockets[sock].u16DataOffset != 0)
)
{
tstrConnectCmd strConnect = {0};
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_DELAY;
strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags;
strConnect.sock = sock;
strConnect.u16SessionID = gastrSockets[sock].u16SessionID;
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SECURE, (uint8*)&strConnect, sizeof(tstrConnectCmd), NULL, 0, 0);
if(s8Ret != SOCK_ERR_NO_ERROR)
{
s8Ret = SOCK_ERR_INVALID;
}
}
}
return s8Ret;
}
/*********************************************************************
Function
send
@ -741,7 +810,7 @@ sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLeng
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
{
uint16 u16DataOffset;
tstrSendCmd strSend;
@ -758,7 +827,10 @@ sint16 WINC1500_EXPORT(send)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLeng
{
u16DataOffset = UDP_TX_PACKET_OFFSET;
}
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY))
)
{
u8Cmd = SOCKET_CMD_SSL_SEND;
u16DataOffset = gastrSockets[sock].u16DataOffset;
@ -793,7 +865,7 @@ sint16 WINC1500_EXPORT(sendto)(SOCKET sock, void *pvSendBuffer, uint16 u16SendLe
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1))
{
if(gastrSockets[sock].bIsUsed)
{
@ -848,7 +920,7 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
{
sint16 s16Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
{
s16Ret = SOCK_ERR_NO_ERROR;
gastrSockets[sock].pu8UserBuffer = (uint8 *)pvRecvBuf;
@ -860,7 +932,10 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
uint8 u8Cmd = SOCKET_CMD_RECV;
gastrSockets[sock].bIsRecvPending = 1;
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
if(
(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
&& (!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_DELAY))
)
{
u8Cmd = SOCKET_CMD_SSL_RECV;
}
@ -872,6 +947,7 @@ sint16 WINC1500_EXPORT(recv)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uin
strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec);
strRecv.sock = sock;
strRecv.u16SessionID = gastrSockets[sock].u16SessionID;
strRecv.u16BufLen = u16BufLen;
s16Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strRecv, sizeof(tstrRecvCmd), NULL , 0, 0);
if(s16Ret != SOCK_ERR_NO_ERROR)
@ -904,7 +980,7 @@ sint8 WINC1500_EXPORT(close)(SOCKET sock)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
M2M_INFO("Sock to delete <%d>\n", sock);
if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (gastrSockets[sock].bIsUsed == 1))
{
uint8 u8Cmd = SOCKET_CMD_CLOSE;
tstrCloseCmd strclose;
@ -946,7 +1022,7 @@ Date
sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec)
{
sint16 s16Ret = SOCK_ERR_NO_ERROR;
if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1))
{
if(gastrSockets[sock].bIsUsed)
{
@ -957,7 +1033,6 @@ sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen,
if(!gastrSockets[sock].bIsRecvPending)
{
tstrRecvCmd strRecv;
gastrSockets[sock].bIsRecvPending = 1;
/* Check the timeout value. */
@ -967,6 +1042,7 @@ sint16 WINC1500_EXPORT(recvfrom)(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen,
strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec);
strRecv.sock = sock;
strRecv.u16SessionID = gastrSockets[sock].u16SessionID;
strRecv.u16BufLen = u16BufLen;
s16Ret = SOCKET_REQUEST(SOCKET_CMD_RECVFROM, (uint8*)&strRecv, sizeof(tstrRecvCmd), NULL , 0, 0);
if(s16Ret != SOCK_ERR_NO_ERROR)
@ -1003,14 +1079,12 @@ Date
*********************************************************************/
uint32 nmi_inet_addr(char *pcIpAddr)
{
uint8 tmp;
uint8 tmp = 0;
uint32 u32IP = 0;
uint8 au8IP[4];
uint8 c;
uint8 i, j;
tmp = 0;
for(i = 0; i < 4; ++i)
{
j = 0;
@ -1041,6 +1115,7 @@ uint32 nmi_inet_addr(char *pcIpAddr)
m2m_memcpy((uint8 *)&u32IP, au8IP, 4);
return u32IP;
}
/*********************************************************************
Function
gethostbyname
@ -1069,6 +1144,7 @@ sint8 WINC1500_EXPORT(gethostbyname)(uint8 * pcHostName)
}
return s8Err;
}
/*********************************************************************
Function
setsockopt
@ -1093,75 +1169,61 @@ static sint8 sslSetSockOpt(SOCKET sock, uint8 u8Opt, const void *pvOptVal, uint
if(sock < TCP_SOCK_MAX)
{
if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)
{
uint8 sslFlag = 0;
s8Ret = SOCK_ERR_NO_ERROR;
if(u16OptLen == sizeof(int))
{
if(u8Opt == SO_SSL_BYPASS_X509_VERIF)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_BYPASS_X509;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_BYPASS_X509;
}
s8Ret = SOCK_ERR_NO_ERROR;
sslFlag = SSL_FLAGS_BYPASS_X509;
}
else if(u8Opt == SO_SSL_ENABLE_SESSION_CACHING)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CACHE_SESSION;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CACHE_SESSION;
}
s8Ret = SOCK_ERR_NO_ERROR;
sslFlag = SSL_FLAGS_CACHE_SESSION;
}
else if(u8Opt == SO_SSL_ENABLE_SNI_VALIDATION)
{
sslFlag = SSL_FLAGS_CHECK_SNI;
}
}
if(sslFlag)
{
int optVal = *((int*)pvOptVal);
if(optVal)
{
gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CHECK_SNI;
gastrSockets[sock].u8SSLFlags |= sslFlag;
}
else
{
gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CHECK_SNI;
gastrSockets[sock].u8SSLFlags &= ~sslFlag;
}
s8Ret = SOCK_ERR_NO_ERROR;
}
else if(u8Opt == SO_SSL_SNI)
else if(
((u8Opt == SO_SSL_SNI) && (u16OptLen < HOSTNAME_MAX_SIZE))
|| ((u8Opt == SO_SSL_ALPN) && (u16OptLen <= ALPN_LIST_MAX_SIZE))
)
{
if(u16OptLen < HOSTNAME_MAX_SIZE)
{
uint8 *pu8SNI = (uint8*)pvOptVal;
tstrSSLSetSockOptCmd strCmd;
tstrSSLSetSockOptCmd strCmd = {0};
strCmd.sock = sock;
strCmd.u16SessionID = gastrSockets[sock].u16SessionID;
strCmd.u8Option = u8Opt;
strCmd.u32OptLen = u16OptLen;
m2m_memcpy(strCmd.au8OptVal, pu8SNI, HOSTNAME_MAX_SIZE);
m2m_memcpy(strCmd.au8OptVal, (uint8*)pvOptVal, u16OptLen);
if(SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd),
0, 0, 0) == M2M_ERR_MEM_ALLOC)
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0);
if(s8Ret == M2M_ERR_MEM_ALLOC)
{
s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT | M2M_REQ_DATA_PKT,
(uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0);
}
s8Ret = SOCK_ERR_NO_ERROR;
}
else
{
M2M_ERR("SNI Exceeds Max Length\n");
}
}
else
{
M2M_ERR("Unknown SSL Socket Option %d\n", u8Opt);
s8Ret = SOCK_ERR_INVALID_ARG;
}
}
else
@ -1171,6 +1233,7 @@ static sint8 sslSetSockOpt(SOCKET sock, uint8 u8Opt, const void *pvOptVal, uint
}
return s8Ret;
}
/*********************************************************************
Function
setsockopt
@ -1193,13 +1256,15 @@ sint8 WINC1500_EXPORT(setsockopt)(SOCKET sock, uint8 u8Level, uint8 option_nam
const void *option_value, uint16 u16OptionLen)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1))
if((sock >= 0) && (sock < MAX_SOCKET) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1))
{
if(u8Level == SOL_SSL_SOCKET)
{
s8Ret = sslSetSockOpt(sock, option_name, option_value, u16OptionLen);
}
else
else if(u8Level == SOL_SOCKET)
{
if(u16OptionLen == sizeof(uint32))
{
uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION;
tstrSetSocketOptCmd strSetSockOpt;
@ -1215,8 +1280,10 @@ sint8 WINC1500_EXPORT(setsockopt)(SOCKET sock, uint8 u8Level, uint8 option_nam
}
}
}
}
return s8Ret;
}
/*********************************************************************
Function
getsockopt
@ -1237,9 +1304,10 @@ 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
m2m_ping_req
@ -1265,16 +1333,96 @@ sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb)
if((u32DstIP != 0) && (fpPingCb != NULL))
{
tstrPingCmd strPingCmd;
strPingCmd.u16PingCount = 1;
strPingCmd.u32DestIPAddr = u32DstIP;
strPingCmd.u32CmdPrivate = (uint32)fpPingCb;
strPingCmd.u32CmdPrivate = ++gu32PingId;
strPingCmd.u8TTL = u8TTL;
gfpPingCb = fpPingCb;
s8Ret = SOCKET_REQUEST(SOCKET_CMD_PING, (uint8 *)&strPingCmd, sizeof(tstrPingCmd), NULL, 0, 0);
}
return s8Ret;
}
/*********************************************************************
Function
set_alpn_protocol_list
Description
This function sets the protocol list used for application-layer protocol negotiation (ALPN).
If used, it must be called after creating a SSL socket (using @ref socket) and before
connecting/binding (using @ref connect or @ref bind).
Return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*********************************************************************/
sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList)
{
sint8 s8Ret = SOCK_ERR_INVALID_ARG;
if((sock >= 0) && (sock < TCP_SOCK_MAX) && (pcProtocolList != NULL))
{
uint8 u8Length = m2m_strlen((uint8 *)pcProtocolList);
if((u8Length > 0) && (u8Length < ALPN_LIST_MAX_APP_LENGTH))
{
/*
ALPN socket option requires Alpn list in this format:
0 1 2 3 ... (bytes)
+-------+-------+-------+ ... +-------+ ... +-------+ ...
| Length L (BE) | len1 | name1... | len2 | name2... | len3 | name3...
+-------+-------+-------+ ... +-------+ ... +-------+ ...
Length fields do not include themselves.
*/
uint8 au8AlpnList[ALPN_LIST_MAX_SIZE] = {0};
uint8 *pu8Ptr = &au8AlpnList[3] + u8Length;
uint8 u8Len = 0;
m2m_memcpy(&au8AlpnList[3], (uint8 *)pcProtocolList, u8Length);
u8Length++;
au8AlpnList[1] = u8Length;
au8AlpnList[2] = ' ';
/* Convert space characters into length fields. */
while(u8Length--)
{
if(*--pu8Ptr == ' ')
{
if(u8Len == 0) goto ERR;
*pu8Ptr = u8Len;
u8Len = 0;
}
else u8Len++;
}
s8Ret = WINC1500_EXPORT(setsockopt)(sock, SOL_SSL_SOCKET, SO_SSL_ALPN, au8AlpnList, sizeof(au8AlpnList));
}
}
ERR:
return s8Ret;
}
/*********************************************************************
Function
get_alpn_protocol_index
Description
This function gets the protocol list used for application-layer protocol negotiation (ALPN).
If used, it must be called after creating a SSL socket (using @ref socket) and before
connecting/binding (using @ref connect or @ref bind).
Return
The function returns the index of the selected application-layer protocol.
Special values:
0: no negotiation has occurred.
<0: error.
*********************************************************************/
sint8 get_alpn_index(SOCKET sock)
{
if(sock >= TCP_SOCK_MAX || sock < 0)
return SOCK_ERR_INVALID_ARG;
if(!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) || !gastrSockets[sock].bIsUsed)
return SOCK_ERR_INVALID_ARG;
return gastrSockets[sock].u8AlpnStatus;
}
/*********************************************************************
Function
sslEnableCertExpirationCheck
@ -1293,7 +1441,7 @@ Version
Date
*********************************************************************/
sint8 WINC1500_EXPORT(sslEnableCertExpirationCheck)(tenuSslCertExpSettings enuValidationSetting)
sint8 sslEnableCertExpirationCheck(tenuSslCertExpSettings enuValidationSetting)
{
tstrSslCertExpSettings strSettings;
strSettings.u32CertExpValidationOpt = (uint32)enuValidationSetting;
@ -1322,3 +1470,27 @@ uint8 IsSocketReady(void)
{
return gbSocketInit;
}
/*********************************************************************
Function
get_error_detail
Description
This function gets detail about a socket failure.
The application can call this when notified of a socket failure via
@ref SOCKET_MSG_CONNECT or @ref SOCKET_MSG_RECV.
If used, it must be called before @ref close.
Return
The function returns @ref SOCK_ERR_NO_ERROR if the request is successful
and a negative value otherwise.
*********************************************************************/
sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr)
{
if((sock >= TCP_SOCK_MAX) || (sock < 0) || (pstrErr == NULL))
return SOCK_ERR_INVALID_ARG;
if(!gastrSockets[sock].bIsUsed)
return SOCK_ERR_INVALID_ARG;
pstrErr->enuErrSource = gastrSockets[sock].u8ErrSource;
pstrErr->u8ErrCode = gastrSockets[sock].u8ErrCode;
return SOCK_ERR_NO_ERROR;
}

View File

@ -4,7 +4,7 @@
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@ -539,18 +539,17 @@ sint8 spi_flash_enable(uint8 enable)
}
/* GPIO15/16/17/18 */
u32Val &= ~((0x7777ul) << 12);
if(enable) {
u32Val |= ((0x1111ul) << 12);
nm_write_reg(0x1410, u32Val);
if(enable) {
spi_flash_leave_low_power_mode();
} else {
spi_flash_enter_low_power_mode();
}
/* Disable pinmux to SPI flash to minimize leakage. */
u32Val &= ~((0x7777ul) << 12);
u32Val |= ((0x0010ul) << 12);
nm_write_reg(0x1410, u32Val);
}
}
ERR1:
return s8Ret;
}
@ -724,8 +723,8 @@ uint32 spi_flash_get_size(void)
if(!gu32InternalFlashSize)
{
u32FlashId = spi_flash_rdid();//spi_flash_probe();
if(u32FlashId != 0xffffffff)
u32FlashId = spi_flash_rdid();
if((u32FlashId != 0xffffffff) && (u32FlashId !=0))
{
/*flash size is the third byte from the FLASH RDID*/
u32FlashPwr = ((u32FlashId>>16)&0xff) - 0x11; /*2MBIT is the min*/