Possible protocol level values supported are @ref SOL_SOCKET and @ref SOL_SSL_SOCKET.
-* Possible options when the protocol level is @ref SOL_SOCKET :
-*
-*
-*
-* @ref SO_SSL_BYPASS_X509_VERIF |
-* Allow an opened SSL socket to bypass the X509
-* certificate verification process. It is highly recommended NOT to use
-* this socket option in production software applications. The option is
-* supported for debugging and testing purposes. The option value should be
-* casted to int type and it is handled as a boolean flag. |
-*
-*
-* @ref SO_SSL_SNI |
-* 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. |
-*
-*
-* @ref SO_SSL_ENABLE_SESSION_CACHING |
-* 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. |
-*
-*
+ * The setsockopt() function shall set the option specified by the option_name
+ * argument, at the protocol level specified by the level argument, to the value
+ * pointed to by the option_value argument for the socket specified by the socket argument.
*/
- /**@{*/
+/**@{*/
/*!
-@fn \
- NMI_API sint8 setsockopt(SOCKET socket, uint8 u8Level, uint8 option_name,
+@fn \
+ NMI_API sint8 setsockopt(SOCKET socket, uint8 u8Level, uint8 option_name,
const void *option_value, uint16 u16OptionLen);
-@param [in] socket
- Socket handler.
+@param[in] socket
+ Socket handler.
-@param [in] u8Level
- protocol level. See description above.
+@param[in] u8Level
+ Protocol level.\n
+ Supported protocol levels are @ref SOL_SOCKET and @ref SOL_SSL_SOCKET.
-@param [in] option_name
- option to be set. See description above.
+@param[in] option_name
+ Option to be set.\n
+ For protocol level @ref SOL_SOCKET, the supported option names are:\n
+ @ref SO_SET_UDP_SEND_CALLBACK\n
+ @ref SO_TCP_KEEPALIVE\n
+ @ref SO_TCP_KEEPIDLE\n
+ @ref SO_TCP_KEEPINTVL\n
+ @ref SO_TCP_KEEPCNT\n
+ For protocol level @ref SOL_SSL_SOCKET, the supported option names are:\n
+ @ref SO_SSL_BYPASS_X509_VERIF\n
+ @ref SO_SSL_SNI\n
+ @ref SO_SSL_ENABLE_SESSION_CACHING\n
+ @ref SO_SSL_ENABLE_SNI_VALIDATION\n
+ @ref SO_SSL_ALPN\n
-@param [in] option_value
- pointer to user provided value.
+@param[in] option_value
+ Pointer to user provided value.
-@param [in] u16OptionLen
- length of the option value in bytes.
+@param[in] u16OptionLen
+ Length of the option value in bytes. Refer to each option documentation for the required length.
-@sa SOL_SOCKET, SOL_SSL_SOCKET, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP
-
-@return
- The function shall return \ref SOCK_ERR_NO_ERROR for successful operation
- and a negative value (indicating the error) otherwise.
+@return
+ The function shall return \ref SOCK_ERR_NO_ERROR for successful operation
+ and a negative value (indicating the error) otherwise.
*/
NMI_API sint8 WINC1500_EXPORT(setsockopt)(SOCKET socket, uint8 u8Level, uint8 option_name,
- const void *option_value, uint16 u16OptionLen);
+ const void *option_value, uint16 u16OptionLen);
/**@}*/ //SetSocketOptionFn
/** @defgroup GetSocketOptionsFn getsockopt
@@ -1994,30 +2173,29 @@ NMI_API sint8 WINC1500_EXPORT(setsockopt)(SOCKET socket, uint8 u8Level, uint8 op
* Get socket options retrieves
* This Function isn't implemented yet but this is the form that will be released later.
*/
- /**@{*/
+/**@{*/
/*!
-@fn \
- sint8 getsockopt(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 * pu8OptLen);
+@fn \
+ sint8 getsockopt(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 * pu8OptLen);
@brief
-@param [in] sock
- Socket Identifier.
-@param [in] u8Level
- The protocol level of the option.
-@param [in] u8OptName
- The u8OptName argument specifies a single option to get.
-@param [out] pvOptValue
- The pvOptValue argument contains pointer to a buffer containing the option value.
-@param [out] pu8OptLen
- Option value buffer length.
+@param[in] sock
+ Socket Identifier.
+@param[in] u8Level
+ The protocol level of the option.
+@param[in] u8OptName
+ The u8OptName argument specifies a single option to get.
+@param[out] pvOptValue
+ The pvOptValue argument contains pointer to a buffer containing the option value.
+@param[out] pu8OptLen
+ Option value buffer length.
@return
- The function shall return ZERO for successful operation and a negative value otherwise.
+ The function shall return ZERO for successful operation and a negative value otherwise.
*/
-NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8* pu8OptLen);
+NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8OptName, const void *pvOptValue, uint8 *pu8OptLen);
/**@}*/ //GetSocketOptionsFn
-/**@}*/
/** @defgroup PingFn m2m_ping_req
* @ingroup SocketAPI
* The function sends ping request to the given IP Address.
@@ -2035,13 +2213,123 @@ NMI_API sint8 WINC1500_EXPORT(getsockopt)(SOCKET sock, uint8 u8Level, uint8 u8Op
@param [in] u8TTL
IP TTL value for the ping request. If set to ZERO, the default value SHALL be used.
-@param [in] fpPingCb
- Callback will be called to deliver the ping statistics.
+@param[in] fpPingCb
+ Callback will be called to deliver the ping statistics.
-@see nmi_inet_addr
-@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
+@warning This API should only be used to request one ping at a time; calling this API invalidates callbacks
+ for previous ping requests.
+@see nmi_inet_addr
+@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb);
+
+/*!
+ * @fn sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList);
+ *
+ * This function sets the protocol list used for application-layer protocol negotiation (ALPN).
+ * If used, it must be called after creating a SSL socket (using @ref socket) and before
+ * connecting/binding (using @ref connect or @ref bind) or securing (using @ref secure).
+ *
+ * @param[in] sock
+ * Socket ID obtained by a call to @ref socket. This is the SSL socket to which
+ * the ALPN list applies.
+ *
+ * @param[in] pcProtocolList
+ * Pointer to the list of protocols available in the application. \n
+ * The entries in the list must: \n
+ * - be separated with ' ' (space). \n
+ * - not contain ' ' (space) or '\0' (NUL). \n
+ * - be non-zero length. \n
+ * .
+ * The list itself must: \n
+ * - be terminated with '\0' (NUL). \n
+ * - be no longer than @ref ALPN_LIST_MAX_APP_LENGTH, including separators (spaces) and terminator (NUL). \n
+ * - contain at least one entry.
+ *
+ * @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
+ *
+ * \section SocketExample9 Example
+ * The example demonstrates an application using @ref set_alpn_list and @ref get_alpn_index to negotiate secure HTTP/2
+ * (with fallback option of HTTP/1.1).
+
+ * \subsection sub5 Main Function
+ * @code
+ * SOCKET TcpClientSocket = socket(AF_INET, SOCK_STREAM, SOCKET_CONFIG_SSL_ON);
+ * if (TcpClientSocket >= 0)
+ * {
+ * struct sockaddr_in Serv_Addr = {
+ * .sin_family = AF_INET,
+ * .sin_port = _htons(1234),
+ * .sin_addr.s_addr = inet_addr(SERVER)
+ * };
+ * set_alpn_list(TcpClientSocket, "h2 http/1.1");
+ * connect(TcpClientSocket, &Serv_Addr, sizeof(Serv_Addr));
+ * }
+ * @endcode
+ * \subsection sub6 Socket Callback
+ * @code
+ * if(u8Msg == SOCKET_MSG_CONNECT)
+ * {
+ * tstrSocketConnectMsg *pstrConnect = (tstrSocketConnectMsg*)pvMsg;
+ * if(pstrConnect->s8Error == 0)
+ * {
+ * uint8 alpn_index = get_alpn_index(pstrConnect->sock);
+ * switch (alpn_index)
+ * {
+ * case 1:
+ * printf("Negotiated HTTP/2\n");
+ * break;
+ * case 2:
+ * printf("Negotiated HTTP/1.1\n");
+ * break;
+ * case 0:
+ * printf("Protocol negotiation did not occur\n");
+ * break;
+ * }
+ * }
+ * }
+ * @endcode
+*/
+sint8 set_alpn_list(SOCKET sock, const char *pcProtocolList);
+/*!
+ * @fn sint8 get_alpn_index(SOCKET sock);
+ *
+ * This function gets the index of the protocol negotiated via ALPN.
+ * It should be called when a SSL socket connection succeeds, in order to determine which
+ * application-layer protocol must be used.
+ *
+ * @param[in] sock
+ * Socket ID obtained by a call to @ref socket. This is the SSL socket to which
+ * the ALPN applies.
+ *
+ * @return The function returns:\n
+ * - >0: 1-based index of negotiated protocol with respect to the list previously provided to @ref set_alpn_list.\n
+ * - 0: No negotiation occurred (eg TLS peer did not support ALPN).\n
+ * - <0: Invalid parameters (socket is not in use, or not an SSL socket).\n
+ *
+ * @see @ref SocketExample9
+*/
+sint8 get_alpn_index(SOCKET sock);
+
+/*!
+ *@fn sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr);
+ *
+ * This function gets detail about a socket failure. The application can call this when notified
+ * of a socket failure via @ref SOCKET_MSG_CONNECT or @ref SOCKET_MSG_RECV.
+ * If used, it must be called before @ref close.
+
+ * @param[in] sock
+ * Socket ID obtained by a call to @ref socket.
+ *
+ * @param[out] pstrErr
+ * Pointer to structure to be populated with the details of the socket failure.
+ *
+ * @return The function returns @ref SOCK_ERR_NO_ERROR if the request is successful. In this case pstrErr
+ * has been populated.
+ * The function returns a negative value if the request is not successful. In this case pstrErr
+ * has not been populated.
+*/
+sint8 get_error_detail(SOCKET sock, tstrSockErr *pstrErr);
/**@}*/ //PingFn
#ifdef __cplusplus
diff --git a/src/drivers/winc1500/src/m2m_ota.c b/src/drivers/winc1500/src/m2m_ota.c
index 5f0bcc158..3c691f013 100644
--- a/src/drivers/winc1500/src/m2m_ota.c
+++ b/src/drivers/winc1500/src/m2m_ota.c
@@ -4,7 +4,7 @@
*
* \brief NMC1500 IoT OTA Interface.
*
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -71,14 +71,14 @@ FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
-* @fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
-* @brief OTA call back function
-* @param [in] u8OpCode
-* HIF Opcode type.
-* @param [in] u16DataSize
-* HIF data length.
-* @param [in] u32Addr
-* HIF address.
+@fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
+@brief Internal OTA call back function.
+@param[in] u8OpCode
+ HIF Opcode type.
+@param[in] u16DataSize
+ HIF data length.
+@param[in] u32Addr
+ HIF address.
*/
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
@@ -140,9 +140,9 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
s8Ret = hif_receive(u32Addr, (uint8*)&strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
if(gpfHFDReadCb)
- gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.FileBlockSz);
- }
- else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
+ gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz);
+ }
+ else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
{
tstrOtaHostFileEraseStatusResp strOtaHostFileEraseStatusResp = {0};
s8Ret = hif_receive(u32Addr, (uint8*)&strOtaHostFileEraseStatusResp, sizeof(tstrOtaHostFileEraseStatusResp), 1);
@@ -161,20 +161,13 @@ static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
}
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
-
-@brief
- Initialize the OTA layer.
-
-@param [in] pfOtaUpdateCb
- OTA Update callback function
-
-@param [in] pfOtaNotifCb
- OTA Notify callback function
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
+@brief Initialize the OTA layer.
+@param[in] pfOtaUpdateCb
+ OTA Update callback function.
+@param[in] pfOtaNotifCb
+ OTA Notify callback function.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
{
@@ -197,17 +190,11 @@ NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNot
return ret;
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
-
-@brief
- Set the OTA url
-
-@param [in] u8Url
- The url server address
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
+@brief Set the OTA url.
+@param[in] u8Url
+ The url server address.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
{
@@ -222,14 +209,9 @@ NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_notif_check_for_update(void);
-
-@brief
- check for ota update
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_notif_check_for_update(void)
+@brief Check for OTA update.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void)
{
@@ -239,17 +221,11 @@ NMI_API sint8 m2m_ota_notif_check_for_update(void)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
-
-@brief
- Schedule OTA update
-
-@param [in] u32Period
- Period in days
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
+@brief Schedule OTA update.
+@param[in] u32Period
+ Period in days
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
@@ -259,18 +235,11 @@ NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
-
-@brief
- Request OTA start update using the downloaded url
-
-@param [in] pcDownloadUrl
- The download firmware url, you get it from device info
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
-
+@fn NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
+@brief Request OTA start update using the downloaded URL.
+@param[in] pcDownloadUrl
+ The download firmware URL, you get it from device info.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
{
@@ -284,14 +253,9 @@ NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_rollback(void);
-
-@brief
- Request OTA Rollback image
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_rollback(void)
+@brief Request OTA Rollback image.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void)
{
@@ -301,14 +265,9 @@ NMI_API sint8 m2m_ota_rollback(void)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_abort(void);
-
-@brief
- Request OTA Abort
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_abort(void)
+@brief Request OTA Abort.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void)
{
@@ -317,16 +276,10 @@ NMI_API sint8 m2m_ota_abort(void)
return ret;
}
-
/*!
-@fn \
- NMI_API sint8 m2m_ota_switch_firmware(void);
-
-@brief
- Switch to the upgraded Firmware
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_switch_firmware(void)
+@brief Switch to the upgraded Firmware.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void)
{
@@ -336,14 +289,9 @@ NMI_API sint8 m2m_ota_switch_firmware(void)
}
/*!
-@fn \
- NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev);
-
-@brief
- Get the OTA Firmware version.
-
-@return
- The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
+@brief Get the OTA Firmware version.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
{
@@ -409,23 +357,15 @@ NMI_API sint8 m2m_ota_test(void)
#endif
/*!
-@fn \
- NMI_API m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
-
-@brief
- Download a file from a remote location and store it in the WINC's Flash.
-
+@fn NMI_API m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
+@brief Download a file from a remote location and store it in the WINC's Flash.
@param[in] pcDownloadUrl
Url pointing to the remote file. HTTP/HTTPS only.
@param[in] pfHFDGetCb
Pointer to a callback to be executed when the download finishes.
-
-@return
- Status of the get operation
-
-@warning 1. Providing a callback is mandatory.
- 2. This functionality is only supported from WINC release 19.6.0 onwards.
+@return Status of the get operation.
+@warning Providing a callback is mandatory.
*/
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
{
@@ -457,11 +397,8 @@ EXIT:
}
/*!
-@fn \
- NMI_API m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
-@brief
- Read a certain amount of bytes from a file in WINC's Flash using HIF transfer.
-
+@fn NMI_API m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
+@brief Read a certain amount of bytes from a file in WINC's Flash using HIF transfer.
@param[in] u8Handler
ID of the file we are trying to read from. Must be valid.
@@ -473,12 +410,8 @@ EXIT:
@param[in] pfHFDReadCb
Callback to be executed when the read operation completes.
-
-@return
- Status of the read operation
-
-@warning 1. Providing a callback is mandatory.
- 2. This functionality is only supported from WINC release 19.6.0 onwards.
+@return Status of the read operation.
+@warning Providing a callback is mandatory.
*/
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
{
@@ -496,11 +429,8 @@ EXIT:
}
/*!
-@fn \
- NMI_API m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
-@brief
- Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
-
+@fn NMI_API m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
+@brief Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
@param[in] u8Handler
ID of the file we are trying to read from. Must be valid.
@@ -512,22 +442,17 @@ EXIT:
@param[in] u32Size
The amount of data to read (in Bytes).
-
-@return
- Status of the read operation
-
-@warning 1. Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
- mode to allow for a safe access to the Flash. This can be done by calling
- @ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read.
-
- 2. This functionality is only supported from WINC release 19.6.0 onwards.
+@return Status of the read operation.
+@warning Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
+ mode to allow for a safe access to the Flash. This can be done by calling
+ @ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read.
*/
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
{
static uint32 u32FlashHFDStart = 0;
static uint32 u32FlashHFDSize = 0;
sint8 s8Ret = M2M_ERR_INVALID_ARG;
- if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pu8Buff)) goto EXIT;
+ if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT;
if(WIFI_STATE_INIT != m2m_wifi_get_state())
{
@@ -542,9 +467,13 @@ NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32
if(M2M_SUCCESS != s8Ret) goto EXIT;
}
+ s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart, 4);
+
+ if((M2M_SUCCESS != s8Ret) || (pu8Buff[0] != u8Handler)) goto EXIT;
+
if((u32Offset >= u32FlashHFDSize) ||
- (u32Size > u32FlashHFDSize) ||
- ((u32Offset + u32Size) >= u32FlashHFDSize))
+ (u32Size > u32FlashHFDSize) ||
+ ((u32Offset + u32Size) >= u32FlashHFDSize))
{
s8Ret = M2M_ERR_FAIL;
goto EXIT;
@@ -560,20 +489,13 @@ EXIT:
}
/*!
-@fn \
- NMI_API m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
-@brief
- Erase any traces of an existing file, this means from host driver and WINC firmware.
-
+@fn NMI_API m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
+@brief Erase any traces of an existing file, this means from host driver and WINC firmware.
@param[in] u8Handler
ID of the file we are trying to erase. Must be valid.
-
@param[in] pfHFDEraseCb
Pointer to callback to execute when the file erase in the WINC completes.
-
-@return
- Status of the erase operation
-
+@return Status of the erase operation.
@note Providing a callback is optional.
If the current handler is invalid at this point, it means one of the three:
1. The file never existed;
@@ -581,8 +503,6 @@ EXIT:
3. The request to get the file hasn't fully completed.
For 1. and 2. there is no need to signal the WINC to erase the file in Flash.
For 3. the Flash can't be erased while a file download is ongoing.
-
-@warning This functionality is only supported from WINC release 19.6.0 onwards.
*/
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
{
diff --git a/src/drivers/winc1500/src/m2m_periph.c b/src/drivers/winc1500/src/m2m_periph.c
index b58d5c406..be6e2ff0e 100644
--- a/src/drivers/winc1500/src/m2m_periph.c
+++ b/src/drivers/winc1500/src/m2m_periph.c
@@ -4,7 +4,7 @@
*
* \brief NMC1500 Peripherials Application Interface.
*
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -56,95 +56,52 @@ DATA TYPES
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-static sint8 get_gpio_idx(uint8 u8GpioNum)
-{
- if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) return -1;
- if(u8GpioNum == M2M_PERIPH_GPIO15) { return 15;
- } else if(u8GpioNum == M2M_PERIPH_GPIO16) { return 16;
- } else if(u8GpioNum == M2M_PERIPH_GPIO18) { return 18;
- } else if(u8GpioNum == M2M_PERIPH_GPIO3) { return 3;
- } else if(u8GpioNum == M2M_PERIPH_GPIO4) { return 4;
- } else if(u8GpioNum == M2M_PERIPH_GPIO5) { return 5;
- } else if(u8GpioNum == M2M_PERIPH_GPIO6) { return 6;
- } else {
- return -2;
- }
-}
/*
* GPIO read/write skeleton with wakeup/sleep capability.
*/
static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 * pu8OutVal)
{
- sint8 ret, gpio;
+ sint8 s8Ret = hif_chip_wake();
+ if(s8Ret != M2M_SUCCESS) goto _EXIT;
- ret = hif_chip_wake();
- if(ret != M2M_SUCCESS) goto _EXIT;
+ if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) goto _EXIT1;
- gpio = get_gpio_idx(u8GpioNum);
- if(gpio < 0) goto _EXIT1;
-
- if(op == GPIO_OP_DIR) {
- ret = set_gpio_dir((uint8)gpio, u8InVal);
- } else if(op == GPIO_OP_SET) {
- ret = set_gpio_val((uint8)gpio, u8InVal);
- } else if(op == GPIO_OP_GET) {
- ret = get_gpio_val((uint8)gpio, pu8OutVal);
- }
- if(ret != M2M_SUCCESS) goto _EXIT1;
+ if(op == GPIO_OP_DIR) {
+ s8Ret = set_gpio_dir(u8GpioNum, u8InVal);
+ } else if(op == GPIO_OP_SET) {
+ s8Ret = set_gpio_val(u8GpioNum, u8InVal);
+ } else if(op == GPIO_OP_GET) {
+ s8Ret = get_gpio_val(u8GpioNum, pu8OutVal);
+ }
_EXIT1:
- ret = hif_chip_sleep();
+ s8Ret = hif_chip_sleep();
+
_EXIT:
- return ret;
+ return s8Ret;
}
+
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-
-sint8 m2m_periph_init(tstrPerphInitParam * param)
-{
- return M2M_SUCCESS;
-}
-
sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir)
{
- return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL);
+ return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL);
}
sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal)
{
- return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL);
+ return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL);
}
sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal)
{
- return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal);
+ return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal);
}
-sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn)
-{
- return M2M_SUCCESS;
-}
-
-sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param)
-{
- return M2M_SUCCESS;
-}
-
-sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags)
-{
- return M2M_SUCCESS;
-}
-
-sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags)
-{
- return M2M_SUCCESS;
-}
-
-
sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable)
{
- return pullup_ctrl(pinmask, enable);
+ return pullup_ctrl(pinmask, enable);
}
#endif /* CONF_PERIPH */
diff --git a/src/drivers/winc1500/src/m2m_ssl.c b/src/drivers/winc1500/src/m2m_ssl.c
index 79b0dfb48..3c7ed3213 100644
--- a/src/drivers/winc1500/src/m2m_ssl.c
+++ b/src/drivers/winc1500/src/m2m_ssl.c
@@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi SSL APIs implementation.
*
- * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -53,8 +53,8 @@ MACROS
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-static tpfAppSSLCb gpfAppSSLCb = NULL;
-static uint32 gu32HIFAddr = 0;
+static tpfAppSSLCb gpfAppSSLCb = NULL;
+static uint32 gu32HIFAddr = 0;
static tenuTlsFlashStatus genuStatus = TLS_FLASH_ERR_UNKNOWN;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
@@ -62,348 +62,443 @@ FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
- @fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
- @brief SSL callback function
- @param [in] u8OpCode
- HIF Opcode type.
- @param [in] u16DataSize
- HIF data length.
- @param [in] u32Addr
- HIF address.
+@fn void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
+@brief Internal SSL callback function.
+@param [in] u8OpCode
+ HIF Opcode type.
+@param [in] u16DataSize
+ HIF data length.
+@param [in] u32Addr
+ HIF address.
*/
static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
- sint8 s8tmp = M2M_SUCCESS;
- switch(u8OpCode)
- {
- case M2M_SSL_REQ_ECC:
- {
- tstrEccReqInfo strEccREQ;
- s8tmp = hif_receive(u32Addr, (uint8*)&strEccREQ, sizeof(tstrEccReqInfo), 0);
- if(s8tmp == M2M_SUCCESS)
- {
- if (gpfAppSSLCb)
- {
- gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
- gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
- }
- }
- }
- break;
- case M2M_SSL_RESP_SET_CS_LIST:
- {
- tstrSslSetActiveCsList strCsList;
- s8tmp = hif_receive(u32Addr, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
- if(s8tmp == M2M_SUCCESS)
- {
- if (gpfAppSSLCb)
- gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
- }
- }
- break;
- case M2M_SSL_RESP_WRITE_OWN_CERTS:
- {
- tstrTlsSrvChunkHdr strTlsSrvChunkRsp;
- uint8 bCallApp = 1;
+ sint8 s8tmp = M2M_SUCCESS;
+ switch(u8OpCode)
+ {
+ case M2M_SSL_REQ_ECC:
+ {
+ tstrEccReqInfo strEccREQ;
+ s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0);
+ if(s8tmp == M2M_SUCCESS)
+ {
+ if(gpfAppSSLCb)
+ {
+ gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
+ gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
+ }
+ }
+ }
+ break;
+ case M2M_SSL_RESP_SET_CS_LIST:
+ {
+ tstrSslSetActiveCsList strCsList;
+ s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
+ if(s8tmp == M2M_SUCCESS)
+ {
+ if(gpfAppSSLCb)
+ gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
+ }
+ }
+ break;
+ case M2M_SSL_RESP_WRITE_OWN_CERTS:
+ {
+ tstrTlsSrvChunkHdr strTlsSrvChunkRsp;
+ uint8 bCallApp = 1;
- s8tmp = hif_receive(u32Addr, (uint8*)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0);
- if(s8tmp == M2M_SUCCESS)
- {
- uint16 offset = strTlsSrvChunkRsp.u16Offset32;
- uint16 chunk_size = strTlsSrvChunkRsp.u16Size32;
- uint16 total_size = strTlsSrvChunkRsp.u16TotalSize32;
- tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig);
-
- /* If first chunk, reset status. */
- if (offset == 0)
- genuStatus = TLS_FLASH_OK_NO_CHANGE;
- /* Only send status to app when processing last chunk. */
- if (offset + chunk_size != total_size)
- bCallApp = 0;
+ s8tmp = hif_receive(u32Addr, (uint8 *)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0);
+ if(s8tmp == M2M_SUCCESS)
+ {
+ uint16 offset = strTlsSrvChunkRsp.u16Offset32;
+ uint16 chunk_size = strTlsSrvChunkRsp.u16Size32;
+ uint16 total_size = strTlsSrvChunkRsp.u16TotalSize32;
+ tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig);
- switch (status)
- {
- case TLS_FLASH_OK:
- // Good flash write. Update status if no errors yet.
- if (genuStatus == TLS_FLASH_OK_NO_CHANGE)
- genuStatus = status;
- break;
- case TLS_FLASH_OK_NO_CHANGE:
- // No change, don't update status.
- break;
- case TLS_FLASH_ERR_CORRUPT:
- // Corrupt. Always update status.
- genuStatus = status;
- break;
- case TLS_FLASH_ERR_NO_CHANGE:
- // Failed flash write. Update status if no more serious error.
- if ((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN))
- genuStatus = status;
- break;
- default:
- // Don't expect any other case. Ensure we don't mask a previous corrupt error.
- if (genuStatus != TLS_FLASH_ERR_CORRUPT)
- genuStatus = TLS_FLASH_ERR_UNKNOWN;
- break;
- }
- }
- if (bCallApp && gpfAppSSLCb)
- gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus);
- }
- break;
- }
- if(s8tmp != M2M_SUCCESS)
- {
- M2M_ERR("Error receiving SSL from the HIF\n");
- }
-}
+ /* If first chunk, reset status. */
+ if(offset == 0)
+ genuStatus = TLS_FLASH_OK_NO_CHANGE;
+ /* Only send status to app when processing last chunk. */
+ if(offset + chunk_size != total_size)
+ bCallApp = 0;
-
-/*!
- @fn \ m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
- @brief Sends ECC responses to the WINC
- @param [in] strECCResp
- ECC Response struct.
- @param [in] pu8RspDataBuffe
- Pointer of the response data to be sent.
- @param [in] u16RspDataSz
- Response data size.
- @return The function SHALL return 0 for success and a negative value otherwise.
-*/
-NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
-{
- sint8 s8Ret = M2M_SUCCESS;
-
- s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8*)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
-
- return s8Ret;
+ switch(status)
+ {
+ case TLS_FLASH_OK:
+ // Good flash write. Update status if no errors yet.
+ if(genuStatus == TLS_FLASH_OK_NO_CHANGE)
+ genuStatus = status;
+ break;
+ case TLS_FLASH_OK_NO_CHANGE:
+ // No change, don't update status.
+ break;
+ case TLS_FLASH_ERR_CORRUPT:
+ // Corrupt. Always update status.
+ genuStatus = status;
+ break;
+ case TLS_FLASH_ERR_NO_CHANGE:
+ // Failed flash write. Update status if no more serious error.
+ if((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN))
+ genuStatus = status;
+ break;
+ default:
+ // Don't expect any other case. Ensure we don't mask a previous corrupt error.
+ if(genuStatus != TLS_FLASH_ERR_CORRUPT)
+ genuStatus = TLS_FLASH_ERR_UNKNOWN;
+ break;
+ }
+ }
+ if(bCallApp && gpfAppSSLCb)
+ gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus);
+ }
+ break;
+ }
+ if(s8tmp != M2M_SUCCESS)
+ {
+ M2M_ERR("Error receiving SSL from the HIF\n");
+ }
}
/*!
- @fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
- @brief Sends certificates to the WINC
- @param [in] pu8Buffer
- Pointer to the certificates.
- @param [in] u32BufferSz
- Size of the certificates.
- @return The function SHALL return 0 for success and a negative value otherwise.
-*/
-NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
-{
- sint8 s8Ret = M2M_SUCCESS;
- #define TXLIMIT (256 * 6)
-
- if(u32BufferSz <= TXLIMIT)
- {
- // set chunk header for one chunk
- tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)pu8Buffer;
- pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
- pchkhdr->u16TotalSize32 = (u32BufferSz + 3) >> 2;
- pchkhdr->u16Offset32 = 0;
- pchkhdr->u16Size32 = (u32BufferSz + 3) >> 2;
- s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
- M2M_INFO("Transferred %lu bytes of cert data NON-CHUNKED\n", u32BufferSz);
- }
- else
- {
- // chunk it
- // We are sneaking in a header - tstrTlsSrvChunkHdr
- #define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr))
- #define CHUNKSZ (TXLIMIT - 256) // divisible by 4
- uint8 saveblob[CHUNKHDRSZ];
- uint32 ofs = 0;
- uint32 thischunksz = 0;
-
- // first is special - over writing our header
- m2m_memcpy(saveblob, &pu8Buffer[ofs], CHUNKHDRSZ);
- thischunksz = min(CHUNKSZ,u32BufferSz-ofs); // no need to round up to quad words this time
-
- tstrTlsSrvChunkHdr* pchkhdr = (tstrTlsSrvChunkHdr*)&pu8Buffer[ofs];
- pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
- pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
- pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
- pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
- s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs], thischunksz, 0);
- M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %lu total %lu\n", thischunksz, ofs, u32BufferSz);
- m2m_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ);
- ofs += thischunksz;
-
- while (ofs < u32BufferSz)
- {
- // Subsequent chunks write header before and send a little more
- m2m_memcpy(saveblob, &pu8Buffer[ofs-CHUNKHDRSZ], CHUNKHDRSZ);
- thischunksz = min(CHUNKSZ,u32BufferSz-ofs);
- thischunksz = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length
- pchkhdr = (tstrTlsSrvChunkHdr*)&pu8Buffer[ofs - CHUNKHDRSZ];
- pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
- pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
- pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
- pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
- s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs - CHUNKHDRSZ], thischunksz + CHUNKHDRSZ, 0);
- M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %lu total %lu\n", thischunksz, ofs, u32BufferSz);
- m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ);
- ofs += thischunksz;
- }
- }
-
- return s8Ret;
-}
-
-/*!
- @fn \ m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
- @brief Retrieve the certificate to be verified from the WINC
- @param [in] pu16CurveType
- Pointer to the certificate curve type.
- @param [in] pu8Hash
- Pointer to the certificate hash.
- @param [in] pu8Sig
- Pointer to the certificate signature.
- @param [in] pu8Key
- Pointer to the certificate Key.
- @return The function SHALL return 0 for success and a negative value otherwise.
-*/
-NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
-{
- uint8 bSetRxDone = 1;
- uint16 u16HashSz, u16SigSz, u16KeySz;
- sint8 s8Ret = M2M_SUCCESS;
-
- if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
-
- if(hif_receive(gu32HIFAddr, (uint8*)pu16CurveType, 2, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += 2;
-
- if(hif_receive(gu32HIFAddr, (uint8*)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += 2;
-
- if(hif_receive(gu32HIFAddr, (uint8*)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += 2;
-
- if(hif_receive(gu32HIFAddr, (uint8*)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += 2;
-
- (*pu16CurveType)= _htons((*pu16CurveType));
- pu8Key->u16Size = _htons(u16KeySz);
- u16HashSz = _htons(u16HashSz);
- u16SigSz = _htons(u16SigSz);
-
- if(hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += (pu8Key->u16Size * 2);
-
- if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += u16HashSz;
-
- if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
- gu32HIFAddr += u16SigSz;
-
- bSetRxDone = 0;
-
-__ERR:
- if(bSetRxDone)
- {
- s8Ret = M2M_ERR_FAIL;
- hif_receive(0, NULL, 0, 1);
- }
- return s8Ret;
-}
-
-/*!
- @fn \ m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
- @brief Retrieve the certificate hash
- @param [in] pu8Hash
- Pointer to the certificate hash.
- @param [in] u16HashSz
- Hash size.
- @return The function SHALL return 0 for success and a negative value otherwise.
-*/
-NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz)
-{
- uint8 bSetRxDone = 1;
- sint8 s8Ret = M2M_SUCCESS;
-
- if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
-
- if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
-
- bSetRxDone = 0;
-
-__ERR:
- if(bSetRxDone)
- {
- s8Ret = M2M_ERR_FAIL;
- hif_receive(0, NULL, 0, 1);
- }
- return s8Ret;
-}
-
-/*!
- @fn \ m2m_ssl_stop_processing_certs(void)
- @brief Stops receiving from the HIF
-*/
-NMI_API void m2m_ssl_stop_processing_certs(void)
-{
- hif_receive(0, NULL, 0, 1);
-}
-
-/*!
- @fn \ m2m_ssl_ecc_process_done(void)
- @brief Stops receiving from the HIF
-*/
-NMI_API void m2m_ssl_ecc_process_done(void)
-{
- gu32HIFAddr = 0;
-}
-
-/*!
-@fn \
- m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
- Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
- a bitmap containing the required ciphers to be on.
- There is no need to call this function if the application will not change the default ciphersuites.
-
-@param [in] u32SslCsBMP
- Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
- @ref SSLCipherSuiteID.
- The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
- The caller can override the default with any desired combination, except for combinations involving both RSA
- and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
- If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
- be changed.
-
-@return
- - [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
- - [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
-*/
-sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
-{
- sint8 s8Ret = M2M_SUCCESS;
- tstrSslSetActiveCsList strCsList;
-
- strCsList.u32CsBMP = u32SslCsBMP;
- s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
-
- return s8Ret;
-}
-
-/*!
- @fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
- @brief Initializes the SSL layer.
- @param [in] pfAppSslCb
- Application SSL callback function.
- @return The function SHALL return 0 for success and a negative value otherwise.
+@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
+@brief Initializes the SSL layer.
+@param [in] pfAppSslCb
+ Application SSL callback function.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
- sint8 s8Ret = M2M_SUCCESS;
-
- gpfAppSSLCb = pfAppSSLCb;
- gu32HIFAddr = 0;
- genuStatus = TLS_FLASH_ERR_UNKNOWN;
-
- s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL,m2m_ssl_cb);
- if (s8Ret != M2M_SUCCESS)
- {
- M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
- }
- return s8Ret;
+ sint8 s8Ret = M2M_SUCCESS;
+ gpfAppSSLCb = pfAppSSLCb;
+ gu32HIFAddr = 0;
+ genuStatus = TLS_FLASH_ERR_UNKNOWN;
+ s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
+ if(s8Ret != M2M_SUCCESS)
+ {
+ M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
+ }
+ return s8Ret;
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
+@brief Sends ECC responses to the WINC.
+@param[in] strECCResp
+ ECC Response struct.
+@param[in] pu8RspDataBuff
+ Pointer of the response data to be sent.
+@param[in] u16RspDataSz
+ Response data size.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+*/
+NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
+{
+ sint8 s8Ret = M2M_SUCCESS;
+
+ s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8 *)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
+
+ return s8Ret;
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
+@brief Sends certificates to the WINC
+@param[in] pu8Buffer
+ Pointer to the certificates.
+@param[in] u32BufferSz
+ Size of the certificates.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+*/
+NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
+{
+ sint8 s8Ret = M2M_SUCCESS;
+#define TXLIMIT (256 * 6)
+
+ if(u32BufferSz <= TXLIMIT)
+ {
+ // set chunk header for one chunk
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+ tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)pu8Buffer;
+#pragma GCC diagnostic pop
+ pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
+ pchkhdr->u16TotalSize32 = (u32BufferSz + 3) >> 2;
+ pchkhdr->u16Offset32 = 0;
+ pchkhdr->u16Size32 = (u32BufferSz + 3) >> 2;
+ s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
+ M2M_INFO("Transferred %lu bytes of cert data NON-CHUNKED\n", u32BufferSz);
+ }
+ else
+ {
+ // chunk it
+ // We are sneaking in a header - tstrTlsSrvChunkHdr
+#define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr))
+#define CHUNKSZ (TXLIMIT - 256) // divisible by 4
+ uint8 saveblob[CHUNKHDRSZ];
+ uint32 ofs = 0;
+ uint32 thischunksz = 0;
+
+ // first is special - over writing our header
+ m2m_memcpy(saveblob, &pu8Buffer[ofs], CHUNKHDRSZ);
+ thischunksz = min(CHUNKSZ, u32BufferSz-ofs); // no need to round up to quad words this time
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+ tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs];
+#pragma GCC diagnostic pop
+ pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
+ pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
+ pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
+ pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
+ s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs], thischunksz, 0);
+ M2M_INFO("Transferred %u bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
+ m2m_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ);
+ ofs += thischunksz;
+
+ while(ofs < u32BufferSz)
+ {
+ // Subsequent chunks write header before and send a little more
+ m2m_memcpy(saveblob, &pu8Buffer[ofs-CHUNKHDRSZ], CHUNKHDRSZ);
+ thischunksz = min(CHUNKSZ, u32BufferSz-ofs);
+ thischunksz = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+ pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs - CHUNKHDRSZ];
+#pragma GCC diagnostic pop
+ pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
+ pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
+ pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
+ pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
+ s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs - CHUNKHDRSZ], thischunksz + CHUNKHDRSZ, 0);
+ M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
+ m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ);
+ ofs += thischunksz;
+ }
+ }
+
+ return s8Ret;
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
+@brief Retrieve the next set of information from the WINC for ECDSA verification.
+@param[out] penuCurve
+ The named curve.
+@param[out] pu8Value
+ Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
+@param[inout] pu16ValueSz
+ in: Size of value buffer provided by caller.
+ out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
+@param[out] pu8Sig
+ Signature retrieved for verification.
+@param[inout] pu16SigSz
+ in: Size of signature buffer provided by caller.
+ out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
+@param[out] pstrKey
+ Public key retrieved for verification.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+
+@pre This function should only be called after the application has been notified that
+ verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
+
+@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
+ the WINC is lost.
+*/
+NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey)
+{
+ sint8 s8Ret = M2M_ERR_FAIL;
+ uint16 u16HashSz, u16SigSz, u16KeySz;
+
+ if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
+
+ if((NULL == penuCurve) || (NULL == pu8Value) || (NULL == pu16ValueSz) || (NULL == pu8Sig) || (NULL == pu16SigSz) || (NULL == pstrKey))
+ {
+ s8Ret = M2M_ERR_INVALID_ARG;
+ goto __ERR;
+ }
+
+ if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
+ *penuCurve = _htons(u16KeySz);
+ gu32HIFAddr += 2;
+
+ if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
+ u16KeySz = _htons(u16KeySz);
+ if(u16KeySz > sizeof(pstrKey->X)) goto __ERR;
+ pstrKey->u16Size = u16KeySz;
+ gu32HIFAddr += 2;
+
+ if(hif_receive(gu32HIFAddr, (uint8 *)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
+ u16HashSz = _htons(u16HashSz);
+ if(u16HashSz > *pu16ValueSz) goto __ERR;
+ *pu16ValueSz = u16HashSz;
+ gu32HIFAddr += 2;
+
+ if(hif_receive(gu32HIFAddr, (uint8 *)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
+ u16SigSz = _htons(u16SigSz);
+ if(u16SigSz > *pu16SigSz) goto __ERR;
+ *pu16SigSz = u16SigSz;
+ gu32HIFAddr += 2;
+
+ if(hif_receive(gu32HIFAddr, pstrKey->X, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
+ gu32HIFAddr += u16KeySz;
+ if(hif_receive(gu32HIFAddr, pstrKey->Y, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
+ gu32HIFAddr += u16KeySz;
+
+ if(hif_receive(gu32HIFAddr, pu8Value, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
+ gu32HIFAddr += u16HashSz;
+
+ if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
+ gu32HIFAddr += u16SigSz;
+
+ return M2M_SUCCESS;
+
+__ERR:
+ hif_receive(0, NULL, 0, 1);
+ return s8Ret;
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
+@brief Retrieve the next set of information from the WINC for ECDSA verification.
+@param[out] pu16Curve
+ The named curve, to be cast to type @ref tenuEcNamedCurve.
+@param[out] pu8Value
+ Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
+ The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
+@param[out] pu8Sig
+ Signature retrieved for verification.
+ The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
+@param[out] pstrKey
+ Public key retrieved for verification.
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+
+@pre This function should only be called after the application has been notified that
+ verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
+
+@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
+ the WINC is lost.
+
+@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
+ that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
+*/
+NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey)
+{
+ uint16 u16ValueSz = 32, u16SigSz = 64;
+
+ return m2m_ssl_retrieve_next_for_verifying((tenuEcNamedCurve *)pu16Curve, pu8Value, &u16ValueSz, pu8Sig, &u16SigSz, pstrKey);
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
+@brief Retrieve the value from the WINC for ECDSA signing.
+@param[out] pu8Value
+ Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
+@param[in] u16ValueSz
+ Size of value to be retrieved. (The application should obtain this information,
+ along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+
+@pre This function should only be called after the application has been notified that
+ signing information is ready via @ref ECC_REQ_SIGN_GEN.
+
+@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
+*/
+NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz)
+{
+ sint8 s8Ret = M2M_ERR_FAIL;
+
+ if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
+
+ if(NULL == pu8Value)
+ {
+ s8Ret = M2M_ERR_INVALID_ARG;
+ goto __ERR;
+ }
+
+ if(hif_receive(gu32HIFAddr, pu8Value, u16ValueSz, 0) != M2M_SUCCESS) goto __ERR;
+
+ return M2M_SUCCESS;
+
+__ERR:
+ hif_receive(0, NULL, 0, 1);
+ return s8Ret;
+}
+
+/*!
+@fn NMI_API void m2m_ssl_stop_retrieving(void);
+@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
+ information.
+
+@return None.
+
+@warning The application must call this function if it has been notified (via
+ @ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
+ retrieving from the WINC, but chooses not to retrieve it all.
+ The application must not call this function if it has retrieved all the available
+ information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
+ remaining information has been lost.
+
+@see m2m_ssl_retrieve_next_for_verifying\n
+ m2m_ssl_retrieve_cert\n
+ m2m_ssl_retrieve_hash
+*/
+NMI_API void m2m_ssl_stop_retrieving(void)
+{
+ hif_receive(0, NULL, 0, 1);
+}
+
+/*!
+@fn NMI_API void m2m_ssl_stop_processing_certs(void);
+@brief Allow SSL driver to tidy up in case application does not read all available certificates.
+@return None.
+
+@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
+ that @ref m2m_ssl_stop_retrieving is used instead.
+*/
+NMI_API void m2m_ssl_stop_processing_certs(void)
+{
+ m2m_ssl_stop_retrieving();
+}
+
+/*!
+@fn NMI_API void m2m_ssl_ecc_process_done(void);
+@brief Allow SSL driver to tidy up after application has finished processing ECC message.
+
+@return None.
+
+@warning The application should call this function after receiving an SSL callback with message
+ type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
+ calling @ref m2m_ssl_handshake_rsp.
+*/
+NMI_API void m2m_ssl_ecc_process_done(void)
+{
+ gu32HIFAddr = 0;
+}
+
+/*!
+@fn NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
+@brief Sets the active ciphersuites.
+@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
+ a bitmap containing the required ciphers to be on.
+ There is no need to call this function if the application will not change the default ciphersuites.
+
+@param [in] u32SslCsBMP
+ Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
+ @ref SSLCipherSuiteID.
+ The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
+ The caller can override the default with any desired combination.
+ If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
+ change.
+
+@return
+ - @ref SOCK_ERR_NO_ERROR
+ - @ref SOCK_ERR_INVALID_ARG
+*/
+NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
+{
+ sint8 s8Ret = M2M_SUCCESS;
+ tstrSslSetActiveCsList strCsList;
+
+ strCsList.u32CsBMP = u32SslCsBMP;
+ s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
+
+ return s8Ret;
}
diff --git a/src/drivers/winc1500/src/m2m_wifi.c b/src/drivers/winc1500/src/m2m_wifi.c
index 643d8b067..58b31098a 100644
--- a/src/drivers/winc1500/src/m2m_wifi.c
+++ b/src/drivers/winc1500/src/m2m_wifi.c
@@ -4,7 +4,7 @@
*
* \brief This module contains M2M Wi-Fi APIs implementation.
*
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -44,12 +44,35 @@
*
* \{
*/
+
+/* Require authentication of server. */
+#define WIFI_1X_TLS_HS_FLAGS_PEER_AUTH NBIT1
+/* Enable expiry checking of server certificate chain. */
+#define WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK NBIT2
+/* Require local system time to be known (i.e. fail expiry checking if time is not known locally). */
+#define WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME NBIT3
+/* Enable TLS session caching. */
+#define WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING NBIT4
+/* Reserved, this bit must be clear. */
+#define WIFI_1X_TLS_HS_FLAGS_RSV5 NBIT5
+/* Require server authentication to be against a specified root certificate. */
+#define WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT NBIT6
+/* Reserved, this bit must be clear. */
+#define WIFI_1X_TLS_HS_FLAGS_RSV7 NBIT7
+
+#define WIFI_1X_TLS_HS_FLAGS_DEFAULT ( \
+ WIFI_1X_TLS_HS_FLAGS_PEER_AUTH \
+ | WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK \
+ | WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING \
+)
-static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT;
static volatile uint8 gu8ChNum;
+static volatile uint8 gu8WifiState = WIFI_STATE_DEINIT;
+static tpfAppWifiCb gpfAppWifiCb = NULL;
static volatile uint8 gu8scanInProgress = 0;
-static tpfAppWifiCb gpfAppWifiCb = NULL;
+static uint32 gu321xTlsHsFlags = WIFI_1X_TLS_HS_FLAGS_DEFAULT;
+static uint8 gau81xRootSha1[20] = {0};
#ifdef ETH_MODE
static tpfAppEthCb gpfAppEthCb = NULL;
@@ -58,19 +81,16 @@ static uint16 gu16ethRcvBufSize ;
#endif
/**
-* @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
-* @brief WiFi call back function
-* @param [in] u8OpCode
-* HIF Opcode type.
-* @param [in] u16DataSize
-* HIF data length.
-* @param [in] u32Addr
-* HIF address.
-* @param [in] grp
-* HIF group type.
-* @author
-* @date
-* @version 1.0
+@fn void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
+@brief Internal WiFi callback function.
+@param[in] u8OpCode
+ HIF Opcode type.
+@param[in] u16DataSize
+ HIF data length.
+@param[in] u32Addr
+ HIF address.
+@param[in] grp
+ HIF group type.
*/
static void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
@@ -614,39 +634,9 @@ static sint8 m2m_wifi_connect_prepare_msg(
}
return ret;
INVALID_ARG:
- return M2M_ERR_INVALID_ARG;
+ return M2M_ERR_INVALID_ARG;
}
-/* Convert hexchar to value 0-15 */
-static uint8 hexchar_2_val(uint8 ch)
-{
- ch -= 0x30;
- if (ch <= 9)
- return ch;
- ch |= 0x20;
- ch -= 0x31;
- if (ch <= 5)
- return ch + 10;
- return 0xFF;
- }
-/* Convert hexstring to bytes */
-static sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
- {
- while (u8SizeOut--)
- {
- uint8 u8Out = hexchar_2_val(*pu8In++);
- if (u8Out > 0xF)
- return M2M_ERR_INVALID_ARG;
- *pu8Out = u8Out * 0x10;
- u8Out = hexchar_2_val(*pu8In++);
- if (u8Out > 0xF)
- return M2M_ERR_INVALID_ARG;
- *pu8Out += u8Out;
- pu8Out++;
- }
- return M2M_SUCCESS;
- }
-
/*************************************************************************************************/
/* WIFI CONNECT APIS */
/*************************************************************************************************/
@@ -692,18 +682,24 @@ sint8 m2m_wifi_connect_wep(
if (ret == M2M_SUCCESS)
{
- tstrM2mWifiWep pstrWep;
- pstrWep.u8KeyIndex = pstrAuthWep->u8KeyIndx - 1;
- pstrWep.u8KeyLen = pstrAuthWep->u8KeySz/2;
- hexstr_2_bytes(pstrWep.au8WepKey, (pstrAuthWep->pu8WepKey), pstrWep.u8KeyLen);
+ tstrM2mWifiWep *pstrWep = (tstrM2mWifiWep*)fb_alloc(sizeof(tstrM2mWifiWep), 0);
+ if (pstrWep != NULL)
+ {
+ pstrWep->u8KeyIndex = pstrAuthWep->u8KeyIndx - 1;
+ pstrWep->u8KeyLen = pstrAuthWep->u8KeySz/2;
+ hexstr_2_bytes(pstrWep->au8WepKey, (pstrAuthWep->pu8WepKey), pstrWep->u8KeyLen);
- ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
- (uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
- (uint8*)&pstrWep, sizeof(tstrM2mWifiWep), sizeof(tstrM2mWifiConnHdr));
- }
- }
- return ret;
- }
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
+ (uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
+ (uint8 *)pstrWep, sizeof(tstrM2mWifiWep), sizeof(tstrM2mWifiConnHdr));
+ fb_free();
+ }
+ else
+ ret = M2M_ERR_MEM_ALLOC;
+ }
+ }
+ return ret;
+}
sint8 m2m_wifi_connect_psk(
tenuCredStoreOption enuCredStoreOption,
@@ -723,44 +719,173 @@ sint8 m2m_wifi_connect_psk(
pstrNetworkId,
&strConnHdr);
- if (ret == M2M_SUCCESS)
- {
- tstrM2mWifiPsk pstrPsk;
- m2m_memset((uint8*)&pstrPsk, 0, sizeof(tstrM2mWifiPsk));
- if (pstrAuthPsk->pu8Psk != NULL)
+ if(ret == M2M_SUCCESS)
+ {
+ tstrM2mWifiPsk *pstrPsk = (tstrM2mWifiPsk *)fb_alloc(sizeof(tstrM2mWifiPsk), 0);
+ if(pstrPsk != NULL)
{
- if (pstrAuthPsk->pu8Passphrase != NULL)
- ret = M2M_ERR_INVALID_ARG;
- else
+ m2m_memset((uint8 *)pstrPsk, 0, sizeof(tstrM2mWifiPsk));
+ if(pstrAuthPsk->pu8Psk != NULL)
{
- pstrPsk.u8PassphraseLen = M2M_MAX_PSK_LEN-1;
- /* Use hexstr_2_bytes to verify pu8Psk input. */
- if (M2M_SUCCESS != hexstr_2_bytes(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen/2))
+ if(pstrAuthPsk->pu8Passphrase != NULL)
ret = M2M_ERR_INVALID_ARG;
- m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk.u8PassphraseLen);
+ else
+ {
+ pstrPsk->u8PassphraseLen = M2M_MAX_PSK_LEN-1;
+ /* Use hexstr_2_bytes to verify pu8Psk input. */
+ if(M2M_SUCCESS != hexstr_2_bytes(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen/2))
+ ret = M2M_ERR_INVALID_ARG;
+ m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Psk, pstrPsk->u8PassphraseLen);
+ }
}
- }
- else if (pstrAuthPsk->pu8Passphrase != NULL)
- {
- if (pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1)
- ret = M2M_ERR_INVALID_ARG;
- else
+ else if(pstrAuthPsk->pu8Passphrase != NULL)
{
- pstrPsk.u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
- m2m_memcpy(pstrPsk.au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk.u8PassphraseLen);
+ if(pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1)
+ ret = M2M_ERR_INVALID_ARG;
+ else
+ {
+ pstrPsk->u8PassphraseLen = pstrAuthPsk->u8PassphraseLen;
+ m2m_memcpy(pstrPsk->au8Passphrase, pstrAuthPsk->pu8Passphrase, pstrPsk->u8PassphraseLen);
+ }
}
+ else
+ ret = M2M_ERR_INVALID_ARG;
+ if(ret == M2M_SUCCESS)
+ {
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
+ (uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
+ (uint8 *)pstrPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr));
+ }
+ fb_free();
}
else
- ret = M2M_ERR_INVALID_ARG;
- if (ret == M2M_SUCCESS)
- {
- ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
- (uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
- (uint8*)&pstrPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr));
- }
+ ret = M2M_ERR_MEM_ALLOC;
}
- }
- return ret;
+ }
+ return ret;
+}
+
+sint8 m2m_wifi_1x_set_option(tenu1xOption enuOptionName, const void *pOptionValue, size_t OptionLen)
+{
+ if((pOptionValue == NULL) && (OptionLen > 0))
+ return M2M_ERR_INVALID_ARG;
+ switch(enuOptionName)
+ {
+ case WIFI_1X_BYPASS_SERVER_AUTH:
+ if(OptionLen != sizeof(int))
+ return M2M_ERR_INVALID_ARG;
+ switch(*(int*)pOptionValue)
+ {
+ case 1:
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
+ break;
+ case 0:
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_AUTH;
+ break;
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ break;
+ case WIFI_1X_TIME_VERIF_MODE:
+ if(OptionLen != sizeof(tenuSslCertExpSettings))
+ return M2M_ERR_INVALID_ARG;
+ switch(*(tenuSslCertExpSettings*)pOptionValue)
+ {
+ case SSL_CERT_EXP_CHECK_DISABLE:
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
+ break;
+ case SSL_CERT_EXP_CHECK_ENABLE:
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
+ break;
+ case SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME:
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK;
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME;
+ break;
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ break;
+ case WIFI_1X_SESSION_CACHING:
+ if(OptionLen != sizeof(int))
+ return M2M_ERR_INVALID_ARG;
+ switch(*(int*)pOptionValue)
+ {
+ case 1:
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
+ break;
+ case 0:
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING;
+ break;
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ break;
+ case WIFI_1X_SPECIFIC_ROOTCERT:
+ switch(OptionLen)
+ {
+ case 20:
+ gu321xTlsHsFlags |= WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
+ m2m_memcpy(gau81xRootSha1, (uint8*)pOptionValue, sizeof(gau81xRootSha1));
+ break;
+ case 0:
+ gu321xTlsHsFlags &= ~WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT;
+ m2m_memset(gau81xRootSha1, 0, sizeof(gau81xRootSha1));
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ break;
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ return M2M_SUCCESS;
+}
+
+sint8 m2m_wifi_1x_get_option(tenu1xOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
+{
+ if(pOptionValue == NULL)
+ return M2M_ERR_INVALID_ARG;
+ switch(enuOptionName)
+ {
+ case WIFI_1X_BYPASS_SERVER_AUTH:
+ if(*pOptionLen < sizeof(int))
+ return M2M_ERR_INVALID_ARG;
+ *pOptionLen = sizeof(int);
+ *(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_AUTH) ? 0 : 1;
+ break;
+ case WIFI_1X_TIME_VERIF_MODE:
+ if(*pOptionLen < sizeof(tenuSslCertExpSettings))
+ return M2M_ERR_INVALID_ARG;
+ *pOptionLen = sizeof(tenuSslCertExpSettings);
+ if(!(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_PEER_CERTTIMECHECK))
+ *(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_DISABLE;
+ else if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_REQUIRE_TIME)
+ *(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_ENABLE;
+ else
+ *(tenuSslCertExpSettings*)pOptionValue = SSL_CERT_EXP_CHECK_EN_IF_SYS_TIME;
+ break;
+ case WIFI_1X_SESSION_CACHING:
+ if(*pOptionLen < sizeof(int))
+ return M2M_ERR_INVALID_ARG;
+ *pOptionLen = sizeof(int);
+ *(int*)pOptionValue = (gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SESSION_CACHING) ? 1 : 0;
+ break;
+ case WIFI_1X_SPECIFIC_ROOTCERT:
+ if(gu321xTlsHsFlags & WIFI_1X_TLS_HS_FLAGS_SPECIFY_ROOTCERT)
+ {
+ if(*pOptionLen < sizeof(gau81xRootSha1))
+ return M2M_ERR_INVALID_ARG;
+ *pOptionLen = sizeof(gau81xRootSha1);
+ m2m_memcpy((uint8*)pOptionValue, gau81xRootSha1, sizeof(gau81xRootSha1));
+ }
+ else
+ *pOptionLen = 0;
+ break;
+ default:
+ return M2M_ERR_INVALID_ARG;
+ }
+ return M2M_SUCCESS;
}
sint8 m2m_wifi_connect_1x_mschap2(
@@ -807,32 +932,38 @@ sint8 m2m_wifi_connect_1x_mschap2(
if (pstrAuth1xMschap2->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
- pstr1xHdr->u8DomainLength = 0;
- if (pstrAuth1xMschap2->pu8Domain != NULL)
- {
- pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xMschap2->u16DomainLen);
- m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, pstr1xHdr->u8DomainLength);
- pu8AuthPtr += pstr1xHdr->u8DomainLength;
- }
+ pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
+ pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
+ m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
- pstr1xHdr->u16UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
- m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u16UserNameLength);
- pu8AuthPtr += pstr1xHdr->u16UserNameLength;
+ pstr1xHdr->u8DomainLength = 0;
+ if(pstrAuth1xMschap2->pu8Domain != NULL)
+ {
+ pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xMschap2->u16DomainLen);
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, pstr1xHdr->u8DomainLength);
+ pu8AuthPtr += pstr1xHdr->u8DomainLength;
+ }
- pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
- pstr1xHdr->u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen;
- m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Password, pstr1xHdr->u16PrivateKeyLength);
+ pstr1xHdr->u8UserNameLength = (pstrAuth1xMschap2->u16UserNameLen);
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, pstr1xHdr->u8UserNameLength);
+ pu8AuthPtr += pstr1xHdr->u8UserNameLength;
- ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
- (uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
- (uint8*)pstr1xHdr, u16AuthSize,
- sizeof(tstrM2mWifiConnHdr));
- fb_free();
- }
- }
- }
- }
- return ret;
+ pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
+ pstr1xHdr->u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen;
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Password, pstr1xHdr->u16PrivateKeyLength);
+
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
+ (uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
+ (uint8 *)pstr1xHdr, u16AuthSize,
+ sizeof(tstrM2mWifiConnHdr));
+ fb_free();
+ }
+ else
+ ret = M2M_ERR_MEM_ALLOC;
+ }
+ }
+ }
+ return ret;
}
sint8 m2m_wifi_connect_1x_tls(
@@ -886,49 +1017,55 @@ tstrAuth1xTls *pstrAuth1xTls
if (pstrAuth1xTls->bPrependDomain == true)
pstr1xHdr->u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG;
- pstr1xHdr->u8DomainLength = 0;
- if (pstrAuth1xTls->pu8Domain != NULL)
- {
- pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xTls->u16DomainLen);
- m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, pstr1xHdr->u8DomainLength);
- pu8AuthPtr += pstr1xHdr->u8DomainLength;
- }
+ pstr1xHdr->u8HdrLength = sizeof(tstrM2mWifi1xHdr);
+ pstr1xHdr->u32TlsHsFlags = gu321xTlsHsFlags;
+ m2m_memcpy(pstr1xHdr->au8TlsSpecificRootNameSha1, gau81xRootSha1, sizeof(gau81xRootSha1));
- pstr1xHdr->u16UserNameLength = (pstrAuth1xTls->u16UserNameLen);
- m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u16UserNameLength);
- pu8AuthPtr += pstr1xHdr->u16UserNameLength;
+ pstr1xHdr->u8DomainLength = 0;
+ if(pstrAuth1xTls->pu8Domain != NULL)
+ {
+ pstr1xHdr->u8DomainLength = (uint8)(pstrAuth1xTls->u16DomainLen);
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, pstr1xHdr->u8DomainLength);
+ pu8AuthPtr += pstr1xHdr->u8DomainLength;
+ }
- pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
- pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen;
- m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Mod, pstr1xHdr->u16PrivateKeyLength);
- pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength;
- m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Exp, pstr1xHdr->u16PrivateKeyLength);
- pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength;
+ pstr1xHdr->u8UserNameLength = (pstrAuth1xTls->u16UserNameLen);
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, pstr1xHdr->u8UserNameLength);
+ pu8AuthPtr += pstr1xHdr->u8UserNameLength;
- pstr1xHdr->u16CertificateOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
- pstr1xHdr->u16CertificateLength = pstrAuth1xTls->u16CertificateLen;
+ pstr1xHdr->u16PrivateKeyOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
+ pstr1xHdr->u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen;
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Mod, pstr1xHdr->u16PrivateKeyLength);
+ pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength;
+ m2m_memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Exp, pstr1xHdr->u16PrivateKeyLength);
+ pu8AuthPtr += pstr1xHdr->u16PrivateKeyLength;
- strInfoHdr.u8Type = M2M_802_1X_TLS_CLIENT_CERTIFICATE;
- strInfoHdr.u16InfoPos = pstr1xHdr->u16CertificateOffset;
- strInfoHdr.u16InfoLen = pstr1xHdr->u16CertificateLength;
- ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_IND_CONN_PARAM | M2M_REQ_DATA_PKT,
- (uint8*)&strInfoHdr, sizeof(tstrM2mWifiAuthInfoHdr),
- pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen,
- sizeof(tstrM2mWifiAuthInfoHdr));
+ pstr1xHdr->u16CertificateOffset = pu8AuthPtr - pstr1xHdr->au81xAuthDetails;
+ pstr1xHdr->u16CertificateLength = pstrAuth1xTls->u16CertificateLen;
- if (ret == M2M_SUCCESS)
- {
- ret = hif_send( M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
- (uint8*)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
- (uint8*)pstr1xHdr, u16Payload1Size,
- sizeof(tstrM2mWifiConnHdr));
- }
- fb_free();
- }
- }
- }
- }
- return ret;
+ strInfoHdr.u8Type = M2M_802_1X_TLS_CLIENT_CERTIFICATE;
+ strInfoHdr.u16InfoPos = pstr1xHdr->u16CertificateOffset;
+ strInfoHdr.u16InfoLen = pstr1xHdr->u16CertificateLength;
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_IND_CONN_PARAM | M2M_REQ_DATA_PKT,
+ (uint8 *)&strInfoHdr, sizeof(tstrM2mWifiAuthInfoHdr),
+ pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen,
+ sizeof(tstrM2mWifiAuthInfoHdr));
+
+ if(ret == M2M_SUCCESS)
+ {
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT,
+ (uint8 *)&strConnHdr, sizeof(tstrM2mWifiConnHdr),
+ (uint8 *)pstr1xHdr, u16Payload1Size,
+ sizeof(tstrM2mWifiConnHdr));
+ }
+ fb_free();
+ }
+ else
+ ret = M2M_ERR_MEM_ALLOC;
+ }
+ }
+ }
+ return ret;
}
sint8 m2m_wifi_connect(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *pvAuthInfo, uint16 u16Ch)
@@ -1091,6 +1228,29 @@ sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption)
}
return s8Ret;
}
+
+sint8 m2m_wifi_set_stop_scan_on_first(uint8 u8StopScanOption)
+{
+ sint8 s8Ret = M2M_ERR_FAIL;
+
+ tstrM2MStopScanOption StopScanOption = { 0 };
+
+ if(1 >= u8StopScanOption)
+ {
+ StopScanOption.u8StopOnFirstResult = u8StopScanOption;
+
+ s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_STOP_SCAN_OPTION, (uint8 *)&StopScanOption, sizeof(tstrM2MStopScanOption), NULL, 0, 0);
+
+ M2M_INFO("Scan will %s stop on first result.\n", StopScanOption.u8StopOnFirstResult ? "" : "NOT");
+ }
+ else
+ {
+ s8Ret = M2M_ERR_INVALID_ARG;
+ }
+
+ return s8Ret;
+}
+
sint8 m2m_wifi_set_scan_region(uint16 ScanRegion)
{
sint8 s8Ret = M2M_ERR_FAIL;
@@ -1217,15 +1377,14 @@ sint8 m2m_wifi_wps_disable(void)
return ret;
}
/*!
-@fn NMI_API sint8 m2m_wifi_req_client_ctrl(uint8 cmd);
-@brief Send a command to the PS Client (An WINC1500 board running the ps_firmware),
- if the PS client send any commands it will be received in wifi_cb M2M_WIFI_RESP_CLIENT_INFO
-@param [in] cmd
- Control command sent from PS Server to PS Client (command values defined by the application)
-@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
-@sa m2m_wifi_req_server_init, M2M_WIFI_RESP_CLIENT_INFO
-@pre m2m_wifi_req_server_init should be called first
-@warning
+@fn NMI_API sint8 m2m_wifi_req_client_ctrl(uint8 cmd)
+@brief Send a command to the PS Client (An WINC board running the ps_firmware),
+ if the PS client send any commands it will be received in wifi_cb @ref M2M_WIFI_RESP_CLIENT_INFO.
+@param[in] cmd
+ Control command sent from PS Server to PS Client (command values defined by the application).
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+@sa m2m_wifi_req_server_init, M2M_WIFI_RESP_CLIENT_INFO
+@pre m2m_wifi_req_server_init should be called first
*/
sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
{
@@ -1241,14 +1400,14 @@ sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
return ret;
}
/*!
-@fn NMI_API sint8 m2m_wifi_req_server_init(uint8 ch);
-@brief Initialize the PS Server, The WINC1500 support Non secure communication with another WINC1500,
- (SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup
-@param [in] ch
- Server listening channel
-@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise
-@sa m2m_wifi_req_client_ctrl
-@warning The server mode can't be used with any other modes (STA/P2P/AP)
+@fn NMI_API sint8 m2m_wifi_req_server_init(uint8 ch)
+@brief Initialize the PS Server, The WINC support non secure communication with another WINC,
+ (SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup.
+@param[in] ch
+ Server listening channel
+@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
+@sa m2m_wifi_req_client_ctrl
+@warning The server mode can't be used with any other modes (STA/AP).
*/
sint8 m2m_wifi_req_server_init(uint8 ch)
{
@@ -1479,10 +1638,10 @@ sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn)
return ret;
}
/*!
-@fn NMI_API sint8 m2m_wifi_request_sleep(void)
-@brief Request from WINC1500 device to Sleep for specific time in the M2M_PS_MANUAL Power save mode (only).
-@param [in] u32SlpReqTime
- Request Sleep in ms
+@fn NMI_API sint8 m2m_wifi_request_sleep(void)
+@brief Request from WINC device to Sleep for specific time in the M2M_PS_MANUAL Power save mode (only).
+@param [in] u32SlpReqTime
+ Request Sleep in ms
@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
@sa tenuPowerSaveModes , m2m_wifi_set_sleep_mode
@warning the Function should be called in M2M_PS_MANUAL power save only
@@ -1501,14 +1660,14 @@ sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime)
return ret;
}
/*!
-@fn NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength);
-@brief Set the WINC1500 device name which is used as P2P device name.
-@param [in] pu8DeviceName
- Buffer holding the device name.
-@param [in] u8DeviceNameLength
- Length of the device name.
-@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
-@warning The Function called once after initialization.
+@fn NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength);
+@brief Sets the WINC device name. The name string is used as a device name in DHCP hostname (option 12).
+@param [in] pu8DeviceName
+ Buffer holding the device name.
+@param [in] u8DeviceNameLength
+ Length of the device name.
+@return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
+@warning The Function called once after initialization.
*/
sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength)
{
@@ -1754,19 +1913,22 @@ sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100)
*/
sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
{
- sint8 ret = M2M_ERR_FAIL;
- tstrPrng strRng = {0};
- if((u16PrngSize < (M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)))&&(pu8PrngBuff != NULL))
- {
- strRng.u16PrngSize = u16PrngSize;
- strRng.pu8RngBuff = pu8PrngBuff;
- ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT,(uint8 *)&strRng, sizeof(tstrPrng),NULL,0, 0);
- }
- else
- {
- M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n",u16PrngSize);
- }
- return ret;
+ sint8 ret = M2M_ERR_FAIL;
+ tstrPrng strRng = {0};
+ if(
+ (u16PrngSize <= (M2M_HIF_MAX_PACKET_SIZE - (M2M_HIF_HDR_OFFSET + sizeof(tstrPrng))))
+ && (pu8PrngBuff != NULL)
+ )
+ {
+ strRng.u16PrngSize = u16PrngSize;
+ strRng.pu8RngBuff = pu8PrngBuff;
+ ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT, (uint8 *)&strRng, sizeof(tstrPrng), NULL, 0, 0);
+ }
+ else
+ {
+ M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n", u16PrngSize);
+ }
+ return ret;
}
/*!
@@ -1905,3 +2067,19 @@ sint8 m2m_wifi_disable_roaming(void)
strWiFiRoaming.u8EnableRoaming = 0;
return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ROAMING, (uint8 *) &strWiFiRoaming, sizeof(tstrM2mWiFiRoaming), NULL, 0,0);
}
+
+sint8 m2m_wifi_enable_XO_during_sleep(uint8 bXOSleepEnable)
+{
+ tstrM2mWiFiXOSleepEnable strM2mWiFiXOSleepEnable;
+
+ if(0 == bXOSleepEnable || 1 == bXOSleepEnable)
+ {
+ strM2mWiFiXOSleepEnable.u8EnableXODuringSleep = bXOSleepEnable;
+ return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_XO_SLEEP_ENABLE,
+ (uint8 *) &strM2mWiFiXOSleepEnable, sizeof(strM2mWiFiXOSleepEnable), NULL, 0, 0);
+ }
+ else
+ {
+ return M2M_ERR_INVALID_ARG;
+ }
+}
diff --git a/src/drivers/winc1500/src/nm_bus_wrapper.c b/src/drivers/winc1500/src/nm_bus_wrapper.c
index 4e78f4f7e..1cd5b0f29 100644
--- a/src/drivers/winc1500/src/nm_bus_wrapper.c
+++ b/src/drivers/winc1500/src/nm_bus_wrapper.c
@@ -55,7 +55,7 @@ sint8 nm_bus_deinit(void) {
return M2M_SUCCESS;
}
-static sint8 nm_bus_rw(uint8 *txbuf, uint8 *rxbuf, uint16 size) {
+sint8 nm_spi_rw(uint8 *txbuf, uint8 *rxbuf, uint16 size) {
sint8 result = M2M_SUCCESS;
omv_spi_transfer_t spi_xfer = {
.txbuf = txbuf,
@@ -85,7 +85,7 @@ sint8 nm_bus_ioctl(uint8 cmd, void *arg) {
switch (cmd) {
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *spi_rw = (tstrNmSpiRw *) arg;
- ret = nm_bus_rw(spi_rw->pu8InBuf, spi_rw->pu8OutBuf, spi_rw->u16Sz);
+ ret = nm_spi_rw(spi_rw->pu8InBuf, spi_rw->pu8OutBuf, spi_rw->u16Sz);
}
break;
default:
diff --git a/src/drivers/winc1500/src/nm_common.c b/src/drivers/winc1500/src/nm_common.c
index c626aca14..ce4ad1dc6 100644
--- a/src/drivers/winc1500/src/nm_common.c
+++ b/src/drivers/winc1500/src/nm_common.c
@@ -4,7 +4,7 @@
*
* \brief This module contains common APIs declarations.
*
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -127,3 +127,37 @@ sint8 m2m_memcmp(uint8 *pu8Buff1,uint8 *pu8Buff2 ,uint32 u32Size)
}
return s8Result;
}
+
+/* Convert hexchar to value 0-15 */
+static uint8 hexchar_2_val(uint8 ch)
+{
+ /* ch -= '0' */
+ ch -= 0x30;
+ if(ch <= 9)
+ return ch;
+ /* OR with 0x20 to convert upper case to lower case. */
+ ch |= 0x20;
+ /* ch -= ('a'-'0') */
+ ch -= 0x31;
+ if(ch <= 5)
+ return ch + 10;
+ return 0xFF;
+}
+
+/* Convert hexstring to bytes */
+sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
+{
+ while(u8SizeOut--)
+ {
+ uint8 u8Out = hexchar_2_val(*pu8In++);
+ if(u8Out > 0xF)
+ return M2M_ERR_INVALID_ARG;
+ *pu8Out = u8Out * 0x10;
+ u8Out = hexchar_2_val(*pu8In++);
+ if(u8Out > 0xF)
+ return M2M_ERR_INVALID_ARG;
+ *pu8Out += u8Out;
+ pu8Out++;
+ }
+ return M2M_SUCCESS;
+}
diff --git a/src/drivers/winc1500/src/nmspi.c b/src/drivers/winc1500/src/nmspi.c
index 0a3167f7d..a3a4df27a 100644
--- a/src/drivers/winc1500/src/nmspi.c
+++ b/src/drivers/winc1500/src/nmspi.c
@@ -4,7 +4,7 @@
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
@@ -35,8 +35,6 @@
#ifdef CONF_WINC_USE_SPI
-#define USE_OLD_SPI_SW
-
#include "bus_wrapper/include/nm_bus_wrapper.h"
#include "driver/include/nmspi.h"
@@ -73,10 +71,10 @@
#define CMD_SINGLE_READ 0xca
#define CMD_RESET 0xcf
-#define N_OK 1
-#define N_FAIL 0
-#define N_RESET -1
-#define N_RETRY -2
+#define N_OK 0
+#define N_FAIL -1
+#define N_RESET -2
+#define N_RETRY -3
#define SPI_RESP_RETRY_COUNT (10)
#define SPI_RETRY_COUNT (10)
@@ -89,33 +87,19 @@
static uint8 gu8Crc_off = 0;
-static sint8 nmi_spi_read(uint8* b, uint16 sz)
+static inline sint8 nmi_spi_read(uint8 *b, uint16 sz)
{
- tstrNmSpiRw spi;
- spi.pu8InBuf = NULL;
- spi.pu8OutBuf = b;
- spi.u16Sz = sz;
- return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
+ return nm_spi_rw(NULL, b, sz);
+}
+static inline sint8 nmi_spi_write(uint8 *b, uint16 sz)
+{
+ return nm_spi_rw(b, NULL, sz);
+}
+static sint8 nmi_spi_writeread(uint8 *bw, uint8 *br, uint16 sz)
+{
+ return nm_spi_rw(bw, br, sz);
}
-static sint8 nmi_spi_write(uint8* b, uint16 sz)
-{
- tstrNmSpiRw spi;
- spi.pu8InBuf = b;
- spi.pu8OutBuf = NULL;
- spi.u16Sz = sz;
- return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
-}
-#ifndef USE_OLD_SPI_SW
-static sint8 nmi_spi_rw(uint8 *bin,uint8* bout,uint16 sz)
-{
- tstrNmSpiRw spi;
- spi.pu8InBuf = bin;
- spi.pu8OutBuf = bout;
- spi.u16Sz = sz;
- return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
-}
-#endif
/********************************************
Crc7
@@ -158,12 +142,12 @@ static const uint8 crc7_syndrome_table[256] = {
};
-static uint8 crc7_byte(uint8 crc, uint8 data)
+static inline uint8 crc7_byte(uint8 crc, uint8 data)
{
return crc7_syndrome_table[(crc << 1) ^ data];
}
-static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
+static inline uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
{
while (len--)
crc = crc7_byte(crc, *buffer++);
@@ -176,25 +160,6 @@ static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
********************************************/
-#define CMD_DMA_WRITE 0xc1
-#define CMD_DMA_READ 0xc2
-#define CMD_INTERNAL_WRITE 0xc3
-#define CMD_INTERNAL_READ 0xc4
-#define CMD_TERMINATE 0xc5
-#define CMD_REPEAT 0xc6
-#define CMD_DMA_EXT_WRITE 0xc7
-#define CMD_DMA_EXT_READ 0xc8
-#define CMD_SINGLE_WRITE 0xc9
-#define CMD_SINGLE_READ 0xca
-#define CMD_RESET 0xcf
-
-#define DATA_PKT_SZ_256 256
-#define DATA_PKT_SZ_512 512
-#define DATA_PKT_SZ_1K 1024
-#define DATA_PKT_SZ_4K (4 * 1024)
-#define DATA_PKT_SZ_8K (8 * 1024)
-#define DATA_PKT_SZ DATA_PKT_SZ_8K
-
static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 clockless)
{
uint8 bc[9];
@@ -216,24 +181,29 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
bc[3] = 0x00;
len = 5;
break;
+#if defined(CMD_TERMINATE)
case CMD_TERMINATE: /* termination */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
+#endif
+#if defined(CMD_REPEAT)
case CMD_REPEAT: /* repeat */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
+#endif
case CMD_RESET: /* reset */
bc[1] = 0xff;
bc[2] = 0xff;
bc[3] = 0xff;
len = 5;
break;
+#if defined(CMD_DMA_WRITE) || defined(CMD_DMA_READ)
case CMD_DMA_WRITE: /* dma write */
case CMD_DMA_READ: /* dma read */
bc[1] = (uint8)(adr >> 16);
@@ -243,6 +213,7 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
bc[5] = (uint8)(sz);
len = 7;
break;
+#endif
case CMD_DMA_EXT_WRITE: /* dma extended write */
case CMD_DMA_EXT_READ: /* dma extended read */
bc[1] = (uint8)(adr >> 16);
@@ -278,7 +249,7 @@ static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 cloc
break;
}
- if (result) {
+ if(result == N_OK) {
if (!gu8Crc_off)
bc[len-1] = (crc7(0x7f, (const uint8 *)&bc[0], len-1)) << 1;
else
@@ -330,14 +301,22 @@ static sint8 spi_cmd_rsp(uint8 cmd)
/**
Command/Control response
**/
- if ((cmd == CMD_RESET) ||
- (cmd == CMD_TERMINATE) ||
- (cmd == CMD_REPEAT)) {
+#if defined(CMD_TERMINATE)
+ if(cmd == CMD_TERMINATE) {
+ if(M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
+ result = N_FAIL;
+ goto _fail_;
+ }
+ }
+#endif
+#if defined(CMD_REPEAT)
+ if(cmd == CMD_REPEAT) {
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
+#endif
/* wait for response */
s8RetryCnt = SPI_RESP_RETRY_COUNT;
@@ -368,372 +347,27 @@ _fail_:
return result;
}
-#ifndef USE_OLD_SPI_SW
-static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
+
+sint8 nm_spi_reset(void)
{
- uint8_t wb[32], rb[32];
- uint8_t wix, rix;
- uint32_t len2;
- uint8_t rsp;
- int len = 0;
- int result = N_OK;
+ //M2M_INFO("Reset Spi\n");
+ spi_cmd(CMD_RESET, 0, 0, 0, 0);
- wb[0] = cmd;
- switch (cmd) {
- case CMD_SINGLE_READ: /* single word (4 bytes) read */
- wb[1] = (uint8_t)(adr >> 16);
- wb[2] = (uint8_t)(adr >> 8);
- wb[3] = (uint8_t)adr;
- len = 5;
- break;
- case CMD_INTERNAL_READ: /* internal register read */
- wb[1] = (uint8_t)(adr >> 8);
- if(clockless == 1) wb[1] |= (1 << 7);
- wb[2] = (uint8_t)adr;
- wb[3] = 0x00;
- len = 5;
- break;
- case CMD_TERMINATE: /* termination */
- wb[1] = 0x00;
- wb[2] = 0x00;
- wb[3] = 0x00;
- len = 5;
- break;
- case CMD_REPEAT: /* repeat */
- wb[1] = 0x00;
- wb[2] = 0x00;
- wb[3] = 0x00;
- len = 5;
- break;
- case CMD_RESET: /* reset */
- wb[1] = 0xff;
- wb[2] = 0xff;
- wb[3] = 0xff;
- len = 5;
- break;
- case CMD_DMA_WRITE: /* dma write */
- case CMD_DMA_READ: /* dma read */
- wb[1] = (uint8_t)(adr >> 16);
- wb[2] = (uint8_t)(adr >> 8);
- wb[3] = (uint8_t)adr;
- wb[4] = (uint8_t)(sz >> 8);
- wb[5] = (uint8_t)(sz);
- len = 7;
- break;
- case CMD_DMA_EXT_WRITE: /* dma extended write */
- case CMD_DMA_EXT_READ: /* dma extended read */
- wb[1] = (uint8_t)(adr >> 16);
- wb[2] = (uint8_t)(adr >> 8);
- wb[3] = (uint8_t)adr;
- wb[4] = (uint8_t)(sz >> 16);
- wb[5] = (uint8_t)(sz >> 8);
- wb[6] = (uint8_t)(sz);
- len = 8;
- break;
- case CMD_INTERNAL_WRITE: /* internal register write */
- wb[1] = (uint8_t)(adr >> 8);
- if(clockless == 1) wb[1] |= (1 << 7);
- wb[2] = (uint8_t)(adr);
- wb[3] = b[3];
- wb[4] = b[2];
- wb[5] = b[1];
- wb[6] = b[0];
- len = 8;
- break;
- case CMD_SINGLE_WRITE: /* single word write */
- wb[1] = (uint8_t)(adr >> 16);
- wb[2] = (uint8_t)(adr >> 8);
- wb[3] = (uint8_t)(adr);
- wb[4] = b[3];
- wb[5] = b[2];
- wb[6] = b[1];
- wb[7] = b[0];
- len = 9;
- break;
- default:
- result = N_FAIL;
- break;
- }
-
- if (result != N_OK) {
- return result;
- }
-
- if (!gu8Crc_off) {
- wb[len-1] = (crc7(0x7f, (const uint8_t *)&wb[0], len-1)) << 1;
- } else {
- len -=1;
- }
-
-#define NUM_SKIP_BYTES (1)
-#define NUM_RSP_BYTES (2)
-#define NUM_DATA_HDR_BYTES (1)
-#define NUM_DATA_BYTES (4)
-#define NUM_CRC_BYTES (2)
-#define NUM_DUMMY_BYTES (3)
-
- if ((cmd == CMD_RESET) ||
- (cmd == CMD_TERMINATE) ||
- (cmd == CMD_REPEAT)) {
- len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
- } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
- if (!gu8Crc_off) {
- len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
- + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
- } else {
- len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
- + NUM_DUMMY_BYTES);
+ if(spi_cmd_rsp(CMD_RESET) != N_OK) {
+ // Reset command failed, need to send repeated 1's until reset occurs
+ uint8 w_buf[8] = {0xFF};
+ uint8 r_buf[8];
+ M2M_ERR("[nmi spi]: Failed rst cmd response\n");
+ nmi_spi_writeread(w_buf, r_buf, 8);
+ if(r_buf[7] != 0xFF)
+ {
+ M2M_ERR("[nmi spi]: Failed repeated reset\n");
+ return N_FAIL;
}
- } else {
- len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
}
-#undef NUM_DUMMY_BYTES
-
- if(len2 > (sizeof(wb)/sizeof(wb[0]))) {
- M2M_ERR("[nmi spi]: spi buffer size too small (%d) (%d)\n",
- len2, (sizeof(wb)/sizeof(wb[0])));
- result = N_FAIL;
- return result;
- }
- /* zero spi write buffers. */
- for(wix = len; wix< len2; wix++) {
- wb[wix] = 0;
- }
- rix = len;
-
- if (nmi_spi_rw(wb, rb, len2) != M2M_SUCCESS) {
- M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
- result = N_FAIL;
- return result;
- }
-
-#if 0
- {
- int jj;
- printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2);
- for(jj=0; jj