Sync inav to Gitea
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s

This commit is contained in:
2026-08-03 16:37:40 +08:00
commit dac37fd077
14095 changed files with 5603119 additions and 0 deletions
@@ -0,0 +1,219 @@
/**
******************************************************************************
* @file net_address.h
* @author MCD Application Team
* @brief Header for the network address management functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_ADDRESS_H
#define NET_ADDRESS_H
#include "string.h"
#include <stdlib.h>
#include "net_types.h"
#define NET_ZERO(a) (void) memset(&a,0,sizeof(a))
#define NET_EQUAL(a,b) (memcmp(&(a),&(b),sizeof(a))==0)
#define NET_DIFF(a,b) (memcmp(&(a),&(b),sizeof(a))!=0)
#define NET_COPY(a,b) (void) memcpy(&a,&b,sizeof(a))
#ifdef NET_USE_LWIP_DEFINITIONS
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "lwip/sockets.h"
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
typedef struct sockaddr_in net_sockaddr_in_t;
typedef struct sockaddr_in6 net_sockaddr_in6_t;
typedef struct sockaddr net_sockaddr_t;
typedef ip_addr_t net_ip_addr_t;
typedef in_addr_t net_in_addr_t;
#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
(sin)->sin_len = (uint8_t) sizeof(struct sockaddr_in); \
(sin)->sin_family = AF_INET; \
(sin)->sin_port = lwip_htons((port)); \
inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \
(void) memset((void*)(sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
#define NET_IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
IP4ADDR_PORT_TO_SOCKADDR(( struct sockaddr_in*)( void*)(sockaddr), ipaddr, port)
#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \
inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \
(port) = lwip_ntohs((sin)->sin_port); }while(0)
#define NET_SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \
SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port)
#define NET_IP_ADDR_CMP ip_addr_cmp
#define NET_IP_ADDR_ISANY_VAL ip_addr_isany_val
#define NET_IP_ADDR_COPY ip_addr_copy
#define NET_HTONL htonl
#define NET_NTOHL ntohl
#define NET_HTONS htons
#define NET_NTOHS ntohs
#define NET_NTOA_R ipaddr_ntoa_r
#define NET_NTOA ipaddr_ntoa
#define NET_ATON ip4addr_aton
#define NET_ATON_R ipaddr_addr
#define NET_IPADDR4_INIT(u32val) { u32val }
#define NET_IPADDR4_INIT_BYTES(a,b,c,d) NET_IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
#else /* NET_USE_LWIP_DEFINTIONS */
#define NET_IP_ADDR_CMP(addr1, addr2) ((addr1)->addr == (addr2)->addr)
#define NET_IP_ADDR_COPY(dest, src) ((dest).addr = (src).addr)
/** Safely copy one IP address to another (src may be NULL) */
#define NET_IP_ADDR_SET(dest, src) ((dest)->addr = \
((src) == NULL ? 0 : \
(src)->addr))
/** Set complete address to zero */
#define NET_IP_ADDR_SET_ZERO(ipaddr) ((ipaddr)->addr = 0U)
#define NET_IP_ADDR_ISANY_VAL(addr1) ((addr1).addr == 0U)
#define NET_SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) do { \
(ipaddr)->addr = (sockaddr)->sin_addr.s_addr;\
(port) = NET_NTOHS((sockaddr)->sin_port); }while(0)
#define NET_IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
(sin)->sin_len = (uint8_t) sizeof(net_sockaddr_in_t); \
(sin)->sin_family = NET_AF_INET; \
(sin)->sin_port = NET_HTONS((port)); \
(sin)->sin_addr.s_addr = (ipaddr)->addr;\
memset((void*)(sin)->sin_zero, 0, NET_SIN_ZERO_LEN); }while(0)
#define NET_IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
NET_IP4ADDR_PORT_TO_SOCKADDR(( net_sockaddr_in_t*)( void*)(sockaddr), ipaddr, port)
#define NET_HTONL(A) ((((uint32_t)(A) & 0xff000000U) >> 24) | \
(((uint32_t)(A) & 0x00ff0000U) >> 8) | \
(((uint32_t)(A) & 0x0000ff00U) << 8) | \
(((uint32_t)(A) & 0x000000ffU) << 24))
#define NET_NTOHL NET_HTONL
#define NET_HTONS(A) ((((uint16_t)(A) & 0xff00U) >> 8U) | \
(((uint16_t)(A) & 0x00ffU) << 8U))
#define NET_NTOHS NET_HTONS
#define NET_NTOA net_ntoa
#define NET_NTOA_R net_ntoa_r
#define NET_ATON net_aton
#define NET_ATON_R net_aton_r
#define NET_NULL_IP_ADDR 0U
#define NET_PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
(((x) & 0x0000ff00UL) << 8) | \
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define NET_ASLWIP_MAKEU32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
((uint32_t)((b) & 0xff) << 16) | \
((uint32_t)((c) & 0xff) << 8) | \
(uint32_t)((d) & 0xff))
#define NET_IPADDR4_INIT(u32val) { u32val }
#define NET_IPADDR4_INIT_BYTES(a,b,c,d) NET_IPADDR4_INIT(NET_PP_HTONL(NET_ASLWIP_MAKEU32(a,b,c,d)))
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*\
)&((source_inaddr)->s_addr))
/** IPv4 only: set the IP address given as an u32_t */
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
/** IPv4 only: get the IP address as an u32_t */
#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
/* generic socket address structure to support IPV6 and IPV4 */
/* size is 16 bytes and is aligned on LWIP definition to ease integration */
typedef struct
{
uint32_t addr;
} net_ip4_addr_t;
typedef struct net_in_addr
{
uint32_t s_addr;
} net_in_addr_t;
/* Only IPv4 is managed */
typedef net_ip4_addr_t net_ip_addr_t;
typedef struct net_sockaddr
{
uint8_t sa_len;
uint8_t sa_family;
char_t sa_data[14];
} net_sockaddr_t;
/* IPV4 address , with 8 stuffing byte */
#define NET_SIN_ZERO_LEN 8
typedef struct net_sockaddr_in
{
uint8_t sin_len;
uint8_t sin_family;
uint16_t sin_port;
net_in_addr_t sin_addr;
char_t sin_zero[NET_SIN_ZERO_LEN];
} net_sockaddr_in_t;
char_t *net_ntoa(const net_ip_addr_t *addr);
char_t *net_ntoa_r(const net_ip_addr_t *addr, char_t *buf, int32_t buflen);
int32_t net_aton_r(const char_t *cp);
int32_t net_aton(const char_t *cp, net_ip_addr_t *addr);
#endif /* NET_USE_LWIP_DEFINTIONS */
#define S_ADDR(a) (a).s_addr
typedef net_sockaddr_in_t sockaddr_in_t;
#if NET_USE_IPV6
typedef net_sockaddr_in6_t sockaddr_in6_t;
#endif /* NET_USE_IPV6 */
typedef net_sockaddr_t sockaddr_t;
/** MAC address. */
typedef struct
{
uint8_t mac[6];
} macaddr_t;
void net_set_port(net_sockaddr_t *addr, uint16_t port);
uint16_t net_get_port(net_sockaddr_t *addr);
net_ip_addr_t net_get_ip_addr(net_sockaddr_t *addr);
typedef struct net_if_handle_s net_if_handle_t;
#endif /* NET_ADDRESS_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,31 @@
/**
******************************************************************************
* @file net_buffers.h
* @author MCD Application Team
* @brief Defines buffer allocation functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_BUFFERS_H
#define NET_BUFFERS_H
#include "lwip/pbuf.h"
#define NET_BUF_ALLOC(n) (net_buf_t*)pbuf_alloc(PBUF_RAW, n, PBUF_POOL)
#define NET_BUF_REF_ALLOC() (net_buf_t*)pbuf_alloc(PBUF_RAW, 0, PBUF_REF);
#define NET_BUF_FREE(p) pbuf_free((struct pbuf*)p);
#define NET_BUF_REF(p) pbuf_ref((struct pbuf*)p);
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#endif /* NET_BUFFERS_H */
@@ -0,0 +1,83 @@
/**
******************************************************************************
* @file net_cellular.h
* @author MCD Application Team
* @brief Header for the network Cellular class.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CELLULAR_H
#define NET_CELLULAR_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef NET_CELLULAR_CREDENTIAL_V2
/* SIM socket type */
#define NET_SIM_SLOT_MODEM_SOCKET 0 /* Modem Socket SIM Slot */
#define NET_SIM_SLOT_MODEM_EMBEDDED_SIM 1 /* Modem Embedded SIM Slot */
#define NET_CELLULAR_MAX_SUPPORTED_SLOT 2 /* Number max of supported SIM slot */
#define NET_CELLULAR_DEFAULT_SIM_SLOT NET_SIM_SLOT_MODEM_SOCKET /* Default SIM Slot */
typedef char_t net_sim_slot_type_t ;
/* SIM Slot parameters */
typedef struct net_cellular_sim_slot_s
{
net_sim_slot_type_t sim_slot_type; /* sim slot type */
char_t *apn; /* APN (string) */
char_t cid; /* CID (1-9) */
char_t *username; /* username: empty string => no username */
char_t *password; /* password (used only is username is defined) */
} net_cellular_sim_slot_t;
/* Credential configuration */
typedef struct net_cellular_credentials_s
{
uint8_t sim_socket_nb; /* number of sim slot used */
net_cellular_sim_slot_t sim_slot[NET_CELLULAR_MAX_SUPPORTED_SLOT]; /* sim slot parameters */
} net_cellular_credentials_t;
#else /*NET_CELLULAR_CREDENTIAL_V2 */
/* Credential configuration */
typedef struct net_cellular_credentials_s
{
const char_t *apn;
const char_t *username;
const char_t *password;
bool_t use_internal_sim;
} net_cellular_credentials_t;
#endif /* NET_CELLULAR_CREDENTIAL_V2 */
/* Network radio results */
typedef struct net_cellular_radio_results_s
{
int8_t signal_level_db;
} net_cellular_radio_results_t;
/* network extension for Cellular class interface */
int32_t net_cellular_set_credentials(net_if_handle_t *pnetif, const net_cellular_credentials_t *credentials);
int32_t net_cellular_get_radio_results(net_if_handle_t *pnetif, net_cellular_radio_results_t *results);
/* Declaration of cellular network interface constructor */
int32_t cellular_net_driver(net_if_handle_t *pnetif);
#ifdef __cplusplus
}
#endif
#endif /* NET_CELLULAR_H */
@@ -0,0 +1,71 @@
/**
******************************************************************************
* @file net_class_extension.h
* @author MCD Application Team
* @brief Header for the network class extensions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_CLASS_EXTENSION_H
#define NET_CLASS_EXTENSION_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct net_if_wifi_class_extension_s
{
int32_t (*scan)(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
int32_t (*get_scan_results)(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
int32_t (*set_credentials)(const net_wifi_credentials_t *cred);
int32_t (*get_system_info)(const net_wifi_system_info_t info, void *data);
int32_t (*set_param)(const net_wifi_param_t info, void *data);
const net_wifi_credentials_t *credentials;
net_wifi_mode_t mode;
/* Acces Point parameter */
uint8_t access_channel;
uint8_t max_connections;
bool AP_hidden;
const net_wifi_powersave_t *powersave;
void *ifp; /* Interface STA or AP handler */
} net_if_wifi_class_extension_t;
typedef struct net_if_ethernet_class_extension_s
{
int32_t (*version)(void);
} net_if_ethernet_class_extension_t;
typedef struct net_if_cellular_class_extension_s
{
int32_t (*get_radio_results)(net_cellular_radio_results_t *results);
const net_cellular_credentials_t *credentials;
} net_if_cellular_class_extension_t;
typedef struct net_if_custom_class_extension_s
{
int32_t (*version)(void);
} net_if_custom_class_extension_t;
#ifdef __cplusplus
}
#endif
#endif /* NET_CLASS_EXTENSION_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,206 @@
/**
******************************************************************************
* @file net_conf_template.h
* @author MCD Application Team
* @brief Configures the network socket APIs.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_CONF_TEMPLATE_H
#define NET_CONF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
/*cstat -MISRAC2012-Dir-4.4 */
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include <stdio.h>
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
/* Please uncomment if you want socket address defintion from LWIP include file rather than local one */
/* This is recommended if network interface uses LWIP to save some code size. This is required if */
/* project uses IPv6 */
/* #define NET_USE_LWIP_DEFINITIONS */
/* Experimental : Please uncomment if you want to use only control part of network library */
/* net_socket api are directly redifined to LWIP ,NET_MBEDTLS_HOST_SUPPORT is not supported with */
/* this mode, dedicated to save memory (4K code) */
/* #define NET_BYPASS_NET_SOCKET */
/* Please uncomment if secure socket have to be supported and is implemented thanks to MBEDTLS running on MCU */
/* #define NET_MBEDTLS_HOST_SUPPORT */
/* Please uncomment if device supports internally Secure TCP connection */
/* #define NET_MBEDTLS_DEVICE_SUPPORT */
#ifdef NET_USE_RTOS
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "cmsis_os.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
#endif /* NET_USE_RTOS */
/* when using LWIP , size of hostname */
#define NET_IP_HOSTNAME_MAX_LEN 32
#ifndef NET_USE_IPV6
#define NET_USE_IPV6 0
#endif /* NET_USE_IPV6 */
#if NET_USE_IPV6 && !defined(NET_USE_LWIP_DEFINTIONS)
#error "NET IPV6 required to define NET_USE_LWIP_DEFINTIONS"
#endif /* NET_USE_IPV6 */
/* MbedTLS configuration */
#ifdef NET_MBEDTLS_HOST_SUPPORT
#if !defined NET_MBEDTLS_DEBUG_LEVEL
#define NET_MBEDTLS_DEBUG_LEVEL 1
#endif /* NET_MBEDTLS_DEBUG_LEVEL */
#if !defined NET_MBEDTLS_CONNECT_TIMEOUT
#define NET_MBEDTLS_CONNECT_TIMEOUT 10000U
#endif /* NET_MBEDTLS_CONNECT_TIMEOUT */
#if !defined(MBEDTLS_CONFIG_FILE)
#define MBEDTLS_CONFIG_FILE "mbedtls/config.h"
#endif /* MBEDTLS_CONFIG_FILE */
#endif /* NET_MBEDTLS_HOST_SUPPORT */
#if !defined(NET_MAX_SOCKETS_NBR)
#define NET_MAX_SOCKETS_NBR 5
#endif /* NET_MAX_SOCKETS_NBR */
#define NET_IF_NAME_LEN 128
#define NET_DEVICE_NAME_LEN 64
#define NET_DEVICE_ID_LEN 64
#define NET_DEVICE_VER_LEN 64
#define NET_SOCK_DEFAULT_RECEIVE_TO 60000
#define NET_SOCK_DEFAULT_SEND_TO 60000
#define NET_UDP_MAX_SEND_BLOCK_TO 1024
#if !defined(NET_USE_DEFAULT_INTERFACE)
#define NET_USE_DEFAULT_INTERFACE 1
#endif /* NET_USE_DEFAULT_INTERFACE */
#ifdef NET_USE_RTOS
#if ( osCMSIS < 0x20000U)
#define RTOS_SUSPEND if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { (void) vTaskSuspendAll(); }
#define RTOS_RESUME if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { (void) xTaskResumeAll(); }
#else
#define RTOS_SUSPEND (void) osKernelLock()
#define RTOS_RESUME (void) osKernelUnlock()
#endif /* osCMSIS */
#else
#define RTOS_SUSPEND
#define RTOS_RESUME
#endif /* NET_USE_RTOS */
#if !defined(NET_DBG_INFO)
#define NET_DBG_INFO(...)
/*
#define NET_DBG_INFO(...) do { \
RTOS_SUSPEND; \
(void) printf(__VA_ARGS__); \
RTOS_RESUME; \
} while (0)
*/
#endif /* NET_DBG_INFO */
#if !defined(NET_DBG_ERROR)
#define NET_DBG_ERROR(...) do { \
RTOS_SUSPEND; \
(void) printf("\nERROR: %s:%d ",__FILE__,__LINE__) ;\
(void)printf(__VA_ARGS__);\
(void)printf("\n"); \
RTOS_RESUME; \
} while (false)
#endif /* NET_DBG_ERROR */
#if !defined(NET_DBG_PRINT)
#define NET_DBG_PRINT(...) do { \
RTOS_SUSPEND; \
(void)printf("%s:%d ",__FILE__,__LINE__) ;\
(void)printf(__VA_ARGS__);\
(void)printf("\n"); \
RTOS_RESUME; \
} while (false)
#endif /* NET_DBG_PRINT */
#if !defined(NET_ASSERT)
#define NET_ASSERT(test,...) do { if (!(test)) {\
RTOS_SUSPEND; \
(void) printf("Assert Failed %s %d :",__FILE__,__LINE__);\
(void) printf(__VA_ARGS__);\
RTOS_RESUME; \
while(true) {}; }\
} while (false)
#endif /* NET_ASSERT */
#if !defined(NET_PRINT)
#define NET_PRINT(...) do { \
RTOS_SUSPEND; \
(void) printf(__VA_ARGS__);\
(void) printf("\n"); \
RTOS_RESUME; \
} while (false)
#endif /* NET_PRINT */
#if !defined(NET_PRINT_WO_CR)
#define NET_PRINT_WO_CR(...) do { \
RTOS_SUSPEND; \
(void) printf(__VA_ARGS__);\
RTOS_RESUME; \
} while (false)
#endif /* NET_PRINT_WO_CR */
#if !defined(NET_WARNING)
#define NET_WARNING(...) do { \
RTOS_SUSPEND; \
(void) printf("Warning %s:%d ",__FILE__,__LINE__) ;\
(void) printf(__VA_ARGS__);\
(void) printf("\n"); \
RTOS_RESUME; \
} while (false)
#endif /* NET_WARNING */
#ifndef NET_PERF_MAXTHREAD
#define NET_PERF_MAXTHREAD 10U
#endif /* NET_PERF_MAXTHREAD */
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_TEMPLATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,312 @@
/**
******************************************************************************
* @file net_connect.h
* @author MCD Application Team
* @brief Provides the network interface APIs.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONNECT_H
#define NET_CONNECT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "net_types.h"
#include "net_conf.h"
#include "net_mem.h"
#include "net_perf.h"
#include "net_address.h"
#include "net_errors.h"
#include "net_wifi.h"
#include "net_cellular.h"
/* flags */
#define NET_ETHERNET_FLAG_DEFAULT_IF 1
/* Socket family */
#define NET_AF_INET 2
#define NET_AF_UNSPEC 0
#define NET_AF_INET6 10
#define NET_IPADDR_ANY ((u32_t)0x00000000UL)
/* Socket types */
#define NET_SOCK_STREAM 1
#define NET_SOCK_DGRAM 2
#define NET_SOCK_RAW 3
/* Socket protocol */
#define NET_IPPROTO_TCP 6
#define NET_IPPROTO_ICMP 1
#define NET_IPPROTO_UDP 17
#define NET_IPPROTO_TCP_TLS 36
#define NET_SHUTDOWN_R 0
#define NET_SHUTDOWN_W 1
#define NET_SHUTDOWN_RW 2
#define NET_SOL_SOCKET 0xfff
/** @defgroup Socket
* @{
*/
typedef enum
{
NET_SO_RCVTIMEO = 0x1006,/**< to set received timeout in ms, option type is an integer value */
NET_SO_SNDTIMEO = 0x1005,/**< to set send timeout in ms, option type is an integer value */
NET_SO_BINDTODEVICE = 3,/**< to map socket to a specific network interface, no implemented so far , normal bind should make the job */
NET_SO_BLOCKING = 4,/**< to set blocking or none blocking mode, option type is an boolean, true means blocking (default value), false non blocking */
NET_SO_SECURE = 5,/**< to set a socket a a secure socket, no option argument, setsock option must be done before any connection */
NET_SO_TLS_CA_CERT = 7,/**< to pass root ca to secure socket, option type is a pointer to a string , certificat is pem format string */
NET_SO_TLS_CA_CRL = 8,/**< to pass revocation certificat list, this is not supported */
NET_SO_TLS_DEV_KEY = 9,/**< to pass device key to secure socket, option type is a pointer to a string , key is pem format string */
NET_SO_TLS_DEV_CERT = 10,/**< to pass device certificat to secure socket, option type is a pointer to a string , certificat is pem format string */
NET_SO_TLS_SERVER_VERIFICATION = 11,/**< to define verification mode for secure socket,option type is a boolean, True to check server name */
NET_SO_TLS_SERVER_NAME = 12,/**< to define server name to check again,option type is a point to a null terminated string */
NET_SO_TLS_PASSWORD = 13,/**< to define passwd (if any) used to encrypt the device key, option type is pointer to a null terminated string */
NET_SO_TLS_CERT_PROF = 14,/**< to set the X509 security profile , option type is pointer to mbedtls_x509_crt_profile structure */
}
net_socketoption_t;
/** @defgroup Socket
* @}
*/
#define NET_MSG_DONTWAIT 0x08U /* Nonblocking i/o for this operation only */
typedef struct pbuf net_buf_t;
/**
* TOPPP transition are requested by application. "ING" state are transitioning state, meaning that application has required a transition and the transition is ongoing. "ED" states are stable state.
*/
typedef enum
{
NET_EVENT_STATE_CHANGE,
NET_EVENT,
NET_EVENT_WIFI,
} net_evt_t;
/** @defgroup State
* @{
* State transition are requested by application. "ING" state are transitioning state, meaning that application has required a transition and the transition is ongoing. "ED" states are stable state.
*/
typedef enum enum_state
{
NET_STATE_DEINITIALIZED = 0,
NET_STATE_INITIALIZED, /**< basic memory allocation for driver and network interface have been performed */
NET_STATE_STARTING, /**< Network interface interface is starting, application waits for event from network interface to signal transition is performed to NET_STATE_STARTED */
NET_STATE_READY, /**< Network interface interface is started, MAC address can be retrieved */
NET_STATE_CONNECTING,/**< Network interface interface is connecting */
NET_STATE_CONNECTED,/**< Network interface interface is connected, IP address can be retrieved , socket operation can be performed*/
NET_STATE_STOPPING, /**< Network interface interface is stopping */
NET_STATE_DISCONNECTING, /**< Network interface interface is disconnecting */
NET_STATE_CONNECTION_LOST, /**< Network interface connection is lost , this can be a transient state , it can return to connected state without application specific action*/
} net_state_t;
/** @defgroup State
* @}
*/
/** Network state events. */
typedef enum
{
NET_EVENT_CMD_INIT = 0,
NET_EVENT_CMD_START,
NET_EVENT_CMD_CONNECT,
NET_EVENT_CMD_DISCONNECT,
NET_EVENT_CMD_STOP,
NET_EVENT_CMD_DEINIT,
NET_EVENT_INTERFACE_INITIALIZED,
NET_EVENT_INTERFACE_READY,
NET_EVENT_LINK_UP,
NET_EVENT_LINK_DOWN,
NET_EVENT_IPADDR,
} net_state_event_t;
/** Network events. */
typedef enum
{
NET_EVENT_POWERSAVE_ENABLED = 0,
} net_event_t;
typedef struct net_if_drv_s net_if_drv_t;
typedef struct net_ip_if_s net_ip_if_t;
typedef void(* net_if_notify_func)(void *context, uint32_t event_class, uint32_t event_id, void *event_data);
typedef struct
{
net_if_notify_func callback;
void *context;
} net_event_handler_t;
struct net_if_handle_s
{
struct net_if_handle_s *next;
net_ip_addr_t ipaddr;
net_ip_addr_t gateway;
net_ip_addr_t netmask;
net_ip_addr_t static_ipaddr;
net_ip_addr_t static_gateway;
net_ip_addr_t static_netmask;
net_ip_addr_t static_dnserver;
bool_t dhcp_mode;
bool_t dhcp_inform_flag;
bool_t dhcp_enabled;
bool_t dhcp_release_on_link_lost;
char_t DeviceName[NET_DEVICE_NAME_LEN];
char_t DeviceID [NET_DEVICE_ID_LEN];
char_t DeviceVer [NET_DEVICE_VER_LEN];
macaddr_t macaddr;
net_state_t state;
net_if_drv_t *pdrv;
struct netif *netif;
const net_event_handler_t *event_handler;
} ;
typedef int32_t(* net_if_driver_init_func)(net_if_handle_t *pnetif);
/* network state control functions */
int32_t net_if_init(net_if_handle_t *pnetif, net_if_driver_init_func driver_init,
const net_event_handler_t *event_handler);
int32_t net_if_deinit(net_if_handle_t *pnetif);
int32_t net_if_start(net_if_handle_t *pnetif);
int32_t net_if_stop(net_if_handle_t *pnetif);
/* network io data receive process, called in main loop */
int32_t net_if_yield(net_if_handle_t *pnetif, uint32_t timeout);
int32_t net_if_connect(net_if_handle_t *pnetif);
int32_t net_if_disconnect(net_if_handle_t *pnetif);
int32_t net_if_getState(net_if_handle_t *pnetif, net_state_t *state);
int32_t net_if_wait_state(net_if_handle_t *pnetif, net_state_t state, uint32_t timeout);
/* network event management */
void net_if_notify(net_if_handle_t *pnetif, net_evt_t event_class, uint32_t event_if, void *event_data);
/* network parameter and status functions */
int32_t net_if_set_dhcp_mode(net_if_handle_t *pnetif, bool_t mode);
int32_t net_if_set_ipaddr(net_if_handle_t *pnetif, net_ip_addr_t ipaddr, net_ip_addr_t gateway, net_ip_addr_t netmask);
int32_t net_if_get_mac_address(net_if_handle_t *pnetif, macaddr_t *mac);
int32_t net_if_get_ip_address(net_if_handle_t *pnetif, net_ip_addr_t *ip);
int32_t net_if_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
int32_t net_if_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t reponse[]);
/* networtk interface power management */
int32_t net_if_powersave_enable(net_if_handle_t *pnetif);
int32_t net_if_powersave_disable(net_if_handle_t *pnetif);
#if 0
int32_t net_if_sleep(net_if_handle_t *pnetif);
int32_t net_if_wakeup(net_if_handle_t *pnetif);
#endif /* 0 */
/* network socket API */
#ifdef NET_BYPASS_NET_SOCKET
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "lwip/netdb.h"
#include "lwip/dhcp.h"
#include "lwip/tcpip.h"
#include "lwip/etharp.h"
/*cstat +MISRAC* +DEFINE-* -CERT-EXP19* */
#define net_socket lwip_socket
#define net_bind lwip_bind
#define net_accept lwip_accept
#define net_closesocket lwip_close
#define net_shutdown lwip_shutdown
#define net_setsockopt lwip_setsockopt
#define net_getsockopt lwip_getsockopt
#define net_connect lwip_connect
#define net_listen lwip_listen
#define net_send lwip_send
#define net_recv lwip_recv
#define net_sendto lwip_sendto
#define net_recvfrom lwip_recvfrom
#define net_getsockname lwip_getsockname
#define net_getpeername lwip_getpeeername
#else
int32_t net_socket(int32_t Domain, int32_t Type, int32_t Protocol);
int32_t net_bind(int32_t sock, net_sockaddr_t *addr, uint32_t addrlen);
int32_t net_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
int32_t net_closesocket(int32_t sock);
int32_t net_shutdown(int32_t sock, int32_t mode);
int32_t net_setsockopt(int32_t sock, int32_t level, net_socketoption_t optname, const void *optvalue, uint32_t optlen);
int32_t net_getsockopt(int32_t sock, int32_t level, net_socketoption_t optname, void *optvalue, uint32_t *optlen);
int32_t net_connect(int32_t sock, net_sockaddr_t *addr, uint32_t addrlen);
int32_t net_listen(int32_t sock, int32_t backlog);
int32_t net_send(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags);
int32_t net_recv(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags);
int32_t net_sendto(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags, net_sockaddr_t *to, uint32_t tolen);
int32_t net_recvfrom(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags, net_sockaddr_t *from, uint32_t *fromlen);
int32_t net_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
int32_t net_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
#endif /* NET_BYPASS_NET_SOCKET */
extern const int32_t net_tls_sizeof_suite_structure;
extern const void *net_tls_user_suite0;
extern const void *net_tls_user_suite1;
extern const void *net_tls_user_suite2;
extern const void *net_tls_user_suite3;
extern const void *net_tls_user_suite4;
#ifdef __cplusplus
}
#endif
#endif /* NET_CONNECT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,216 @@
/**
******************************************************************************
* @file net_core.h
* @author MCD Application Team
* @brief Provides the network interface driver APIs.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_CORE_H
#define NET_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "net_state.h"
#include "net_wifi.h"
#include "net_class_extension.h"
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
/* #include "lwip/err.h" */
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
int32_t icmp_ping(net_if_handle_t *netif, net_sockaddr_t *addr, int32_t count, int32_t timeout, int32_t response[]);
#ifdef NET_USE_RTOS
void net_init_locks(void);
void net_destroy_locks(void);
void net_lock(int32_t idx, uint32_t to);
void net_unlock(int32_t idx);
void net_lock_nochk(int32_t idx, uint32_t to);
void net_unlock_nochk(int32_t idx);
/* OS */
#define NET_OS_WAIT_FOREVER 0xffffffffU
#define NET_LOCK_SOCKET_ARRAY NET_MAX_SOCKETS_NBR
#define NET_LOCK_NETIF_LIST NET_MAX_SOCKETS_NBR+1
#define NET_LOCK_STATE_EVENT NET_MAX_SOCKETS_NBR+2
#define NET_LOCK_NUMBER (NET_LOCK_STATE_EVENT+1)
#define LOCK_SOCK(s) net_lock((int32_t)s,NET_OS_WAIT_FOREVER)
#define UNLOCK_SOCK(s) net_unlock(s)
#define LOCK_SOCK_ARRAY() net_lock(NET_LOCK_SOCKET_ARRAY,NET_OS_WAIT_FOREVER)
#define UNLOCK_SOCK_ARRAY() net_unlock(NET_LOCK_SOCKET_ARRAY )
#define LOCK_NETIF_LIST() net_lock(NET_LOCK_NETIF_LIST,NET_OS_WAIT_FOREVER )
#define UNLOCK_NETIF_LIST() net_unlock(NET_LOCK_NETIF_LIST )
#define WAIT_STATE_CHANGE(to) net_lock_nochk(NET_LOCK_STATE_EVENT,to )
#define SIGNAL_STATE_CHANGE() net_unlock_nochk(NET_LOCK_STATE_EVENT )
#else
#define LOCK_SOCK(s)
#define UNLOCK_SOCK(s)
#define LOCK_SOCK_ARRAY()
#define UNLOCK_SOCK_ARRAY()
#define LOCK_NETIF_LIST()
#define UNLOCK_NETIF_LIST()
#define WAIT_STATE_CHANGE(to) pnetif->pdrv->if_yield(pnetif, 10)
#define SIGNAL_STATE_CHANGE()
#endif /* NET_USE_RTOS */
typedef enum
{
NET_INTERFACE_CLASS_WIFI,
NET_INTERFACE_CLASS_CELLULAR,
NET_INTERFACE_CLASS_ETHERNET,
NET_INTERFACE_CLASS_CUSTOM
}
net_interface_class_t;
typedef enum
{
NET_ACCESS_SOCKET,
NET_ACCESS_BIND,
NET_ACCESS_LISTEN,
NET_ACCESS_CONNECT,
NET_ACCESS_SEND,
NET_ACCESS_SENDTO,
NET_ACCESS_RECV,
NET_ACCESS_RECVFROM,
NET_ACCESS_CLOSE,
NET_ACCESS_SETSOCKOPT,
}
net_access_t;
struct net_if_drv_s
{
net_interface_class_t if_class;
/* Interface APIs */
int32_t (* if_init)(net_if_handle_t *pnetif);
int32_t (* if_deinit)(net_if_handle_t *pnetif);
int32_t (* if_start)(net_if_handle_t *pnetif);
int32_t (* if_stop)(net_if_handle_t *pnetif);
int32_t (* if_yield)(net_if_handle_t *pnetif, uint32_t timeout);
int32_t (* if_connect)(net_if_handle_t *pnetif);
int32_t (* if_disconnect)(net_if_handle_t *pnetif);
int32_t (* if_powersave_enable)(net_if_handle_t *pnetif);
int32_t (* if_powersave_disable)(net_if_handle_t *pnetif);
void *netif;
void *context;
#ifndef NET_BYPASS_NET_SOCKET
/* Socket BSD Like APIs */
int32_t (* psocket)(int32_t domain, int32_t type, int32_t protocol);
int32_t (* pbind)(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
int32_t (* plisten)(int32_t sock, int32_t backlog);
int32_t (* paccept)(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
int32_t (* pconnect)(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
int32_t (* psend)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
int32_t (* precv)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
int32_t (* psendto)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to, uint32_t tolen);
int32_t (* precvfrom)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from, uint32_t *flen);
int32_t (* psetsockopt)(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
int32_t (* pgetsockopt)(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
int32_t (* pgetsockname)(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
int32_t (* pgetpeername)(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
int32_t (* pclose)(int32_t sock, bool Clone);
int32_t (* pshutdown)(int32_t sock, int32_t mode);
#endif /* NET_BYPASS_NET_SOCKET */
/* Service */
int32_t (* pgethostbyname)(net_if_handle_t *, net_sockaddr_t *addr, char_t *name);
int32_t (* pping)(net_if_handle_t *, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t reponse[]);
/* class extension */
struct
{
net_if_wifi_class_extension_t *wifi;
net_if_ethernet_class_extension_t *ethernet;
net_if_cellular_class_extension_t *cellular;
net_if_custom_class_extension_t *custom;
} extension;
};
net_if_handle_t *net_if_find(net_sockaddr_t *addr);
net_if_handle_t *netif_check(net_if_handle_t *pnetif);
bool net_access_control(net_if_handle_t *pnetif, net_access_t access, int32_t *l);
typedef void (*sock_notify_func)(int32_t, int32_t, const uint8_t *, uint32_t);
typedef struct net_tls_data net_tls_data_t;
typedef int32_t net_ulsock_t;
typedef enum { SOCKET_NOT_ALIVE = 0, SOCKET_ALLOCATED, SOCKET_CONNECTED } socket_state_t;
typedef struct net_socket_s
{
net_if_handle_t *pnetif;
net_ulsock_t ulsocket;
socket_state_t status;
int32_t domain;
int32_t type;
int32_t protocol;
bool cloneserver;
bool connected;
#ifdef NET_MBEDTLS_HOST_SUPPORT
bool is_secure;
net_tls_data_t *tlsData;
bool tls_started;
#endif /* NET_MBEDTLS_HOST_SUPPORT */
int32_t read_timeout;
int32_t write_timeout;
bool blocking;
int32_t idx;
} net_socket_t;
#ifdef NET_MBEDTLS_HOST_SUPPORT
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "net_mbedtls.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
#endif /* NET_MBEDTLS_HOST_SUPPORT */
#ifdef __cplusplus
}
#endif
#endif /* NET_CORE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,83 @@
/**
******************************************************************************
* @file net_errors.h
* @author MCD Application Team
* @brief Defines the network interface error codes
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_ERRORS_H
#define NET_ERRORS_H
#ifdef __cplusplus
extern "C" {
#endif
#define NET_OK 0 /*!< no error */
#define NET_TIMEOUT -1 /*!< Timeout rearched during a blocking operation. */
#define NET_ERROR_WOULD_BLOCK -2 /*!< no data is available but call is non-blocking */
#define NET_ERROR_UNSUPPORTED -3 /*!< unsupported functionality */
#define NET_ERROR_PARAMETER -4 /*!< invalid parameter/configuration */
#define NET_ERROR_NO_CONNECTION -5 /*!< not connected to a network */
#define NET_ERROR_INVALID_SOCKET -6 /*!< socket invalid */
#define NET_ERROR_NO_ADDRESS -7 /*!< IP address is not known */
#define NET_ERROR_NO_MEMORY -8 /*!< memory resource not available */
#define NET_ERROR_NO_SSID -9 /*!< ssid not found */
#define NET_ERROR_DNS_FAILURE -10 /*!< DNS failed to complete successfully */
#define NET_ERROR_DHCP_FAILURE -11 /*!< DHCP failed to complete successfully */
#define NET_ERROR_AUTH_FAILURE -12 /*!< connection to access point failed */
#define NET_ERROR_DEVICE_ERROR -13 /*!< failure interfacing with the network processor */
#define NET_ERROR_IN_PROGRESS -14 /*!< operation (eg connect) in progress */
#define NET_ERROR_ALREADY -15 /*!< operation (eg connect) already in progress */
#define NET_ERROR_IS_CONNECTED -16 /*!< socket is already connected */
#define NET_ERROR_INTERFACE_FAILURE -17 /*!< an error in interface level */
#define NET_ERROR_DATA -18 /*!< an error in interface level */
#define NET_ERROR_SOCKET_FAILURE -19 /*!< an error in interface level */
#define NET_ERROR_OUT_OF_SOCKET -20 /*!< no more available socket , open failed */
#define NET_ERROR_CLOSE_SOCKET -21 /*!< error while closing socket */
#define NET_ERROR_DISCONNECTED -22 /*!< Connection dropped during the operation. */
#define NET_ERROR_CREATE_SECURE_SOCKET -23 /*!< failed to create the secure socket */
#define NET_ERROR_IS_NOT_SECURE -24 /*!< try to set secure option on a non secure socket */
#define NET_ERROR_FRAMEWORK -25 /*!< should never happen */
#define NET_ERROR_STATE_TRANSITION -26 /*!< should never happen */
#define NET_ERROR_INVALID_STATE_TRANSITION -27 /*!< should never happen */
#define NET_ERROR_INVALID_STATE -28 /*!< should never happen */
#define NET_ERROR_GENERIC -29 /*!< generic error */
#define NET_ERROR_MODULE_INITIALIZATION -30 /*!< module is not able to initialized */
#define NET_ERROR_WIFI_CANT_JOIN -31 /*!< wifi module is not able to join */
#define NET_ERROR_MBEDTLS_ENTROPY -100/*!<mbedtls enthropy setup failed */
#define NET_ERROR_MBEDTLS_CRT_PARSE -101/*!<mbedtls parsing certificat failed */
#define NET_ERROR_MBEDTLS_KEY_PARSE -102/*!<mbedtls parsing key failed */
#define NET_ERROR_MBEDTLS_SET_HOSTNAME -103/*!<mbedtls cannot setup hostname*/
#define NET_ERROR_MBEDTLS_SEED -104/*!<mbedtls seed setup failed */
#define NET_ERROR_MBEDTLS_REMOTE_AUTH -105/*!<mbedtls remote host could not be authentified */
#define NET_ERROR_MBEDTLS_CONFIG -106/*!<mbedtls error in config */
#define NET_ERROR_MBEDTLS_SSL_SETUP -107/*!<mbedtls error setting setup */
#define NET_ERROR_MBEDTLS_CONNECT -108/*!<mbedtls error while connecting */
#define NET_ERROR_MBEDTLS -109/*!<mbedtls error while reading writing data */
#ifdef __cplusplus
}
#endif
#endif /* NET_ERRORS_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,32 @@
/**
******************************************************************************
* @file net_internals.h
* @author MCD Application Team
* @brief Header for the network interface with mbedTLS (if used)
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_INTERNALS_H
#define NET_INTERNALS_H
#include "net_core.h"
#ifdef NET_MBEDTLS_HOST_SUPPORT
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "net_mbedtls.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
#endif /* NET_MBEDTLS_HOST_SUPPORT */
#endif /* NET_INTERNALS_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,41 @@
/**
******************************************************************************
* @file net_ip_ethernet.h
* @author MCD Application Team
* @brief Header for the network interface on ethernet
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_IP_ETHERNET_H
#define NET_IP_ETHERNET_H
#include "net_connect.h"
#include "net_internals.h"
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "lwip/netif.h"
/*cstat +MISRAC* -DEFINE-* -CERT-EXP19* */
/* Within 'USER CODE' section, code will be kept by default at each generation */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* Exported functions ------------------------------------------------------- */
void net_ethernetif_deinit(void);
void net_ethernetif_get_mac_addr(uint8_t *mac_addr);
uint8_t net_ethernetif_get_link_status(void);
err_t net_ethernetif_init(struct netif *netif);
int32_t net_ethernetif_output(void *context, net_buf_t *net_buf);
#endif /* NET_IP_ETHERNET_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,58 @@
/**
******************************************************************************
* @file net_ip_lwip.h
* @author MCD Application Team
* @brief Header for the network IP functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_IP_LWIP_H
#define NET_IP_LWIP_H
#include "net_connect.h"
#include "net_internals.h"
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "lwip/netdb.h"
#include "lwip/dhcp.h"
#include "lwip/tcpip.h"
#include "lwip/etharp.h"
/*cstat +MISRAC* +DEFINE-* -CERT-EXP19* */
#define NET_IP_IF_TIMEOUT 1000
#define NET_IP_INPUT_QUEUE_TIMEOUT 1000
#define NET_IP_INPUT_QUEUE_SIZE 128
#define NET_IP_THREAD_SIZE 1024
#define NET_IP_FLAG_DEFAULT_INTERFACE (1U<<0)
#define NET_IP_FLAG_TCPIP_STARTED_EXTERNALLY (1U<<1)
void net_ip_init(void);
int32_t net_ip_add_if(net_if_handle_t *pnetif, err_t (*if_init)(struct netif *netif), uint32_t flag);
int32_t net_ip_remove_if(net_if_handle_t *pnetif, err_t (*if_deinit)(struct netif *netif));
int32_t net_ip_connect(net_if_handle_t *pnetif);
int32_t net_ip_disconnect(net_if_handle_t *pnetif);
void net_ip_status_cb(struct netif *netif);
void net_ip_link_status(struct netif *netif, uint8_t status);
int32_t returncode_lwip2net(int32_t ret);
#endif /* NET_IP_LWIP_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,69 @@
/**
******************************************************************************
* @file net_mbedtls.h
* @author MCD Application Team
* @brief Header for the network TLS functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef MBEDTLS_NET_H
#define MBEDTLS_NET_H
/* Includes ------------------------------------------------------------------*/
#include "mbedtls/platform.h"
#include "mbedtls/ssl.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "mbedtls/timing.h"
/* Private defines -----------------------------------------------------------*/
struct net_tls_data
{
const char_t *tls_ca_certs; /**< Socket option. */
const char_t *tls_ca_crl; /**< Socket option. */
const char_t *tls_dev_cert; /**< Socket option. */
const char_t *tls_dev_key; /**< Socket option. */
const uint8_t *tls_dev_pwd; /**< Socket option. */
size_t tls_dev_pwd_len; /**< Socket option / meta. */
bool tls_srv_verification; /**< Socket option. */
const char_t *tls_srv_name; /**< Socket option. */
/* mbedTLS objects */
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
uint32_t flags;
mbedtls_x509_crt cacert;
mbedtls_x509_crt clicert;
mbedtls_pk_context pkey;
const mbedtls_x509_crt_profile *tls_cert_prof; /**< Socket option. */
} ;
void net_tls_init(void);
void net_tls_destroy(void);
int32_t net_mbedtls_start(net_socket_t *sockhnd);
int32_t net_mbedtls_stop(net_socket_t *sockhnd);
int32_t net_mbedtls_sock_recv(net_socket_t *sockhnd, uint8_t *buf, size_t len);
int32_t net_mbedtls_sock_send(net_socket_t *sockhnd, const uint8_t *buf, size_t len);
bool net_mbedtls_check_tlsdata(net_socket_t *sockhnd);
void net_mbedtls_set_read_timeout(net_socket_t *sock);
#endif /* MBEDTLS_NET_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,110 @@
/**
******************************************************************************
* @file net_mem.h
* @author MCD Application Team
* @brief Memory allocator functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_MEM_H
#define NET_MEM_H
#include "net_conf.h"
#include "net_types.h"
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
/*cstat -MISRAC2012-Dir-4.4 */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef NET_ALLOC_DEBUG
#if !defined NET_ALLOC_MAX_NODE
#define NET_ALLOC_MAX_NODE 50U
#endif /* NET_ALLOC_MAX_NODE */
#if !defined NET_DISPLAY_TAB
#define NET_DISPLAY_TAB 4U
#endif /* NET_DISPLAY_TAB */
#if !defined NET_DISPLAY_WIDTH
#define NET_DISPLAY_WIDTH 120U
#endif /* NET_DISPLAY_WIDTH */
#if !defined NET_DISPLAY_RESULT_WIDTH
#define NET_DISPLAY_RESULT_WIDTH 8U
#endif /* NET_DISPLAY_RESULT_WIDTH */
#if !defined NET_DISPLAY_DIRNAME_LEN
#define NET_DISPLAY_DIRNAME_LEN 30U
#endif /* NET_DISPLAY_DIRNAME_LEN */
#if !defined NET_ALLOC_VERBOSE
#define NET_ALLOC_VERBOSE 0
#endif /* NET_ALLOC_VERBOSE */
#ifndef NET_LEAKAGE_ARRAY
#define NET_LEAKAGE_ARRAY 300U
#endif /* NET_LEAKAGE_ARRAY */
#ifndef NET_ALLOC_BREAK
#define NET_ALLOC_BREAK 0xFFFFFFFFU
#endif /* NET_ALLOC_BREAK */
#define NET_CALLOC(a,b) net_calloc_debug(a,b,__FILE__,__LINE__)
#define NET_REALLOC(a,b) net_realloc_debug(a,b,__FILE__,__LINE__)
#define NET_MALLOC(a) net_malloc_debug(a,__FILE__,__LINE__)
#define NET_FREE(a) net_free_debug(a)
void *net_calloc_debug(size_t m, size_t n, const char *s, uint32_t line);
void *net_malloc_debug(size_t m, const char *s, uint32_t line);
void *net_realloc_debug(void *p, size_t size, const char_t *filename, uint32_t line);
void net_free_debug(void *p);
void net_alloc_report(void);
#else /* !NET_ALLOC_DEBUG */
#ifdef NET_USE_RTOS
#define NET_CALLOC net_calloc
#define NET_REALLOC net_realloc
#define NET_MALLOC pvPortMalloc
#define NET_FREE vPortFree
void *net_calloc(size_t n, size_t m);
void *net_realloc(void *p, size_t m);
#else
#define NET_CALLOC calloc
#define NET_REALLOC realloc
#define NET_MALLOC malloc
#define NET_FREE free
#endif /* NET_USE_RTOS */
#endif /* NET_ALLOC_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* NET_MEM_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,112 @@
/**
******************************************************************************
* @file net_perf.h
* @author MCD Application Team
* @brief Memory allocator functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef NET_PERF_H
#define NET_PERF_H
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
/*cstat -MISRAC2012-Dir-4.4 */
#ifdef __cplusplus
extern "C" {
#endif
#include "net_conf.h"
#include "net_types.h"
#ifdef NET_USE_RTOS
#if (osCMSIS < 0x20000U)
#define NET_TICK osKernelSysTick
#else
#define NET_TICK osKernelGetTickCount
#endif /* osCMSIS */
#else
#define NET_TICK HAL_GetTick
#endif /* NET_USE_RTOS */
/*cstat -MISRAC2012-Rule-21.1 */
#ifndef __IO
#define __IO volatile
#endif /* __IO */
/*cstat +MISRAC2012-Rule-21.1 */
#define NET_DWT_CONTROL (*((__IO uint32_t*)0xE0001000U))
#define NET_DWT_CYCCNTENA_BIT (1UL<<0U)
/*!< DWT Cycle Counter register */
#define NET_DWT_CYCCNT (*((__IO uint32_t*)0xE0001004U))
/*!< DEMCR: Debug Exception and Monitor Control Register */
#define NET_DEMCR (*((__IO uint32_t*)0xE000EDFCU))
/*!< Trace enable bit in DEMCR register */
#define NET_TRCENA_BIT (1UL<<24U)
static inline uint32_t net_get_cycle(void)
{
/*cstat -MISRAC2012-Rule-11.4 */
return NET_DWT_CYCCNT;
/*cstat +MISRAC2012-Rule-11.4 */
}
static inline void net_stop_cycle(void)
{
/*cstat -MISRAC2012-Rule-11.4 */
NET_DWT_CONTROL &= ~NET_DWT_CYCCNTENA_BIT ;
/*cstat +MISRAC2012-Rule-11.4 */
}
static inline void net_start_cycle(void)
{
/*cstat -MISRAC2012-Rule-11.4 */
NET_DWT_CONTROL |= NET_DWT_CYCCNTENA_BIT ;
/*cstat +MISRAC2012-Rule-11.4 */
}
void net_perf_start(void);
void net_perf_report(void);
#ifdef NET_USE_RTOS
#if defined(NET_PERF_TASK) && !defined(NET_FREERTOS_PERF)
#warning "To use NET_PERF_TASK please add followings lines to FreeRTOSConfig.h"
#warning " void net_perf_task_in(void);"
#warning " void net_perf_task_out(void);"
#warning " #define NET_FREERTOS_PERF"
#warning " #define traceTASK_SWITCHED_IN net_perf_task_in"
#warning " #define traceTASK_SWITCHED_OUT net_perf_task_out"
#endif /* NET_PERF_TASK */
#endif /* NET_USE_RTOS */
#ifdef __cplusplus
}
#endif
#endif /* NET_PERF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,27 @@
/**
******************************************************************************
* @file net_state.h
* @author MCD Application Team
* @brief Header for the network state management functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_STATE_H
#define NET_STATE_H
int32_t net_state_manage_event(net_if_handle_t *pnetif, net_state_event_t state_to);
void net_state_transition_done(net_if_handle_t *pnetif, net_state_t state_to);
#endif /* NET_STATE_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,36 @@
/**
******************************************************************************
* @file net_types.h
* @author MCD Application Team
* @brief Header for the network types definitions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_TYPES_H
#define NET_TYPES_H
#include "stdint.h"
#include "stdbool.h"
/*cstat -MISRAC2012-Dir-4.6_b */
typedef char char_t;
typedef unsigned char uchar_t;
/*cstat +MISRAC2012-Dir-4.6_b */
typedef bool bool_t;
#endif /* NET_TYPES_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,195 @@
/**
******************************************************************************
* @file net_wifi.h
* @author MCD Application Team
* @brief Header for the network Wi-Fi class.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_WIFI_H
#define NET_WIFI_H
#ifdef __cplusplus
extern "C" {
#endif
#define NET_WIFI_MAC_ADDRESS_SIZE 6
#define NET_WIFI_MAX_SSID_SIZE 32
#define NET_WEP_ENABLED 0x0001U /**< Flag to enable WEP Security */
#define NET_TKIP_ENABLED 0x0002U /**< Flag to enable TKIP Encryption */
#define NET_AES_ENABLED 0x0004U /**< Flag to enable AES Encryption */
#define NET_SHARED_ENABLED 0x00008000U /**< Flag to enable Shared key Security */
#define NET_WPA_SECURITY 0x00200000U /**< Flag to enable WPA Security */
#define NET_WPA2_SECURITY 0x00400000U /**< Flag to enable WPA2 Security */
#define NET_WPA3_SECURITY 0x01000000U /**< Flag to enable WPA3 PSK Security */
#define NET_ENTERPRISE_ENABLED 0x02000000U /**< Flag to enable Enterprise Security */
#define NET_WPS_ENABLED 0x10000000U /**< Flag to enable WPS Security */
#define NET_IBSS_ENABLED 0x20000000U /**< Flag to enable IBSS mode */
#define NET_FBT_ENABLED 0x40000000U /**< Flag to enable FBT */
#define NET_WIFI_SM_OPEN 0U
/**< Open security */
#define NET_WIFI_SM_WEP_PSK NET_WEP_ENABLED
/**< WEP PSK Security with open authentication */
#define NET_WIFI_SM_WEP_SHARED (NET_WEP_ENABLED | NET_SHARED_ENABLED)
/**< WEP PSK Security with shared authentication */
#define NET_WIFI_SM_WPA_TKIP_PSK (NET_WPA_SECURITY | NET_TKIP_ENABLED)
/**< WPA PSK Security with TKIP */
#define NET_WIFI_SM_WPA_AES_PSK (NET_WPA_SECURITY | NET_AES_ENABLED)
/**< WPA PSK Security with AES */
#define NET_WIFI_SM_WPA_MIXED_PSK (NET_WPA_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
/**< WPA PSK Security with AES & TKIP */
#define NET_WIFI_SM_WPA2_AES_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED)
/**< WPA2 PSK Security with AES */
#define NET_WIFI_SM_WPA2_WPA_PSK (NET_WPA2_SECURITY | NET_WPA_SECURITY)
/**< WPA2 PSK Security with AES */
#define NET_WIFI_SM_WPA2_TKIP_PSK (NET_WPA2_SECURITY | NET_TKIP_ENABLED)
/**< WPA2 PSK Security with TKIP */
#define NET_WIFI_SM_WPA2_MIXED_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
/**< WPA2 PSK Security with AES & TKIP */
#define NET_WIFI_SM_WPA2_FBT_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED | NET_FBT_ENABLED)
/**< WPA2 FBT PSK Security with AES & TKIP */
#define NET_WIFI_SM_WPA3_SAE (NET_WPA3_SECURITY | NET_AES_ENABLED)
/**< WPA3 Security with AES */
#define NET_WIFI_SM_WPA3_WPA2_PSK (NET_WPA3_SECURITY | NET_WPA2_SECURITY | NET_AES_ENABLED)
/**< WPA3 WPA2 PSK Security with AES */
#define NET_WIFI_SM_WPA_TKIP_ENT (NET_ENTERPRISE_ENABLED | NET_WPA_SECURITY | NET_TKIP_ENABLED)
/**< WPA Enterprise Security with TKIP */
#define NET_WIFI_SM_WPA_AES_ENT (NET_ENTERPRISE_ENABLED | NET_WPA_SECURITY | NET_AES_ENABLED)
/**< WPA Enterprise Security with AES */
#define NET_WIFI_SM_WPA_MIXED_ENT (NET_ENTERPRISE_ENABLED\
| NET_WPA_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
/**< WPA Enterprise Security with AES & TKIP */
#define NET_WIFI_SM_WPA2_TKIP_ENT (NET_ENTERPRISE_ENABLED | NET_WPA2_SECURITY | NET_TKIP_ENABLED)
/**< WPA2 Enterprise Security with TKIP */
#define NET_WIFI_SM_WPA2_AES_ENT (NET_ENTERPRISE_ENABLED | NET_WPA2_SECURITY | NET_AES_ENABLED)
/**< WPA2 Enterprise Security with AES */
#define NET_WIFI_SM_WPA2_MIXED_ENT (NET_ENTERPRISE_ENABLED\
| NET_WPA2_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
/**< WPA2 Enterprise Security with AES & TKIP */
#define NET_WIFI_SM_WPA2_FBT_ENT (NET_ENTERPRISE_ENABLED\
| NET_WPA2_SECURITY | NET_AES_ENABLED | NET_FBT_ENABLED)
/**< WPA2 Enterprise Security with AES & FBT */
#define NET_WIFI_SM_IBSS_OPEN (NET_IBSS_ENABLED)
/**< Open security on IBSS ad-hoc network */
#define NET_WIFI_SM_WPS_OPEN (NET_WPS_ENABLED)
/**< WPS with open security */
#define NET_WIFI_SM_WPS_SECURE (NET_WPS_ENABLED | NET_AES_ENABLED)
/**< WPS with AES security */
#define NET_WIFI_SM_UNKNOWN 0xFFFFFFFFU
/**< UNKNOWN security */
#define NET_WIFI_SM_AUTO 0xFFFFFFF0U
/**< Auto Mode */
/* Wi-Fi events */
typedef enum
{
NET_WIFI_SCAN_RESULTS_READY
} net_wifi_event_t;
/* Mode */
typedef enum
{
NET_WIFI_MODE_STA,
NET_WIFI_MODE_AP
} net_wifi_mode_t;
/* MAC address */
typedef uint8_t net_wifi_mac_t[NET_WIFI_MAC_ADDRESS_SIZE];
/* SSID , max 32 alpha string chain*/
typedef struct
{
uint8_t length; /**< SSID length */
uint8_t value[NET_WIFI_MAX_SSID_SIZE]; /**< SSID name (AP name) */
} net_wifi_ssid_t;
/* Scan */
typedef enum
{
NET_WIFI_SCAN_PASSIVE,
NET_WIFI_SCAN_ACTIVE,
NET_WIFI_SCAN_AUTO
} net_wifi_scan_mode_t;
typedef struct net_wifi_scan_bss_s
{
net_wifi_ssid_t ssid;
net_wifi_mac_t bssid;
uint32_t security;
uint8_t channel;
uint8_t country[4]; /* one more char for null terminated string */
int8_t rssi;
} net_wifi_scan_bss_t;
#if 0
typedef struct net_wifi_scan_results_s
{
uint16_t number;
net_wifi_scan_bss_t *bss;
} net_wifi_scan_results_t;
#else
typedef net_wifi_scan_bss_t net_wifi_scan_results_t;
#endif /* old definiton */
/* Param */
typedef enum
{
NET_WIFI_MODE,
} net_wifi_param_t;
/* System info */
typedef enum
{
NET_WIFI_SCAN_RESULTS_NUMBER,
} net_wifi_system_info_t;
/* Credential configuration */
typedef struct net_wifi_credentials_s
{
const char_t *ssid;
const char_t *psk;
int32_t security_mode;
} net_wifi_credentials_t;
/* Powersave */
typedef enum
{
WIFI_POWERSAVE_ACTIVE,
WIFI_POWERSAVE_LIGHT_SLEEP,
WIFI_POWERSAVE_DEEP_SLEEP
}
net_wifi_powersave_t;
const char_t *net_wifi_security_to_string(uint32_t sec);
uint32_t net_wifi_string_to_security(char *sec);
int32_t net_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
int32_t net_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
int32_t net_wifi_set_credentials(net_if_handle_t *pnetif, const net_wifi_credentials_t *credentials);
int32_t net_wifi_set_access_mode(net_if_handle_t *pnetif, net_wifi_mode_t mode);
int32_t net_wifi_set_access_channel(net_if_handle_t *pnetif, uint8_t channel);
int32_t net_wifi_set_powersave(net_if_handle_t *pnetif, const net_wifi_powersave_t *powersave);
int32_t net_wifi_set_param(net_if_handle_t *pnetif, const net_wifi_param_t param, void *data);
#ifdef __cplusplus
}
#endif
#endif /* NET_WIFI_H */
@@ -0,0 +1 @@
STM32 Network Library Framework
@@ -0,0 +1,370 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Release Notes for STM32 Network Library</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<link rel="stylesheet" href="_htmresc/mini-st.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
<link rel="icon" type="image/x-icon" href="_htmresc/favicon.png" />
</head>
<body>
<p>::: {.row} ::: {.col-sm-12 .col-lg-4}</p>
<div class="card fluid">
<div class="sectione dark">
<center>
<h1 id="release-notes-for-stm32-network-library"><small>Release Notes for</small> <mark>STM32 Network Library</mark></h1>
<p>Copyright © 2019 STMicroelectronics<br />
Microcontrollers Division - Application Team</p>
<a href="https://www.st.com" class="logo"><img src="_htmresc/st_logo.png" alt="ST logo" /></a>
</center>
</div>
</div>
<h1 id="license">License</h1>
<p>Licensed under ST license SLA0044 (the “License”). You may not use this package except in compliance with the License.</p>
<p>You may obtain a copy of the License at: <a href="http://www.st.com/software_license_agreement_liberty_v2">SLA0044 Software license agreement</a>.</p>
<h1 id="purpose">Purpose</h1>
<p>The <mark>STM32 Network Library</mark> is a middleware providing network services on STM32 devices. It provides a socket API (BSD like style) with support of secure or non secure connection and an API to control the lifecycle of the network adapters.</p>
<p>Three classes of network adapters are supported WIFI, Ethernet and Cellular. Different WIFI modules are supported from third party vendors.</p>
<h1 id="documentation">Documentation</h1>
<p><a href="./NetworkLib.chm">Doxygen documentation</a> :::</p>
<div class="col-sm-12 col-lg-8">
<h1 id="update-history">Update History</h1>
<div class="collapse">
<input type="checkbox" id="collapse-section8" checked aria-hidden="false"> <label for="collapse-section8" aria-hidden="true">V2.1.0 / 2020-Mai-04</label>
<div>
<h2 id="main-changes">Main changes</h2>
<h3 id="network-library-core">Network library core</h3>
<ul>
<li>Improve performance monitoring primitives adding Thread display support</li>
<li>Improve Memory debug primitive</li>
<li>Add Node Tree display for dynamic memory allocation</li>
</ul>
<h3 id="mxchip-wifi-network-interface">MXCHIP WIFI Network interface</h3>
<ul>
<li>Add support of UART interrupt module</li>
</ul>
<h3 id="bug-fixes">Bug fixes</h3>
<ul>
<li>Fix uninitialized variable for all WIFI network interface to force default to AP mode when connecting</li>
<li>Fix memory leakage for MXCHIP network interface</li>
</ul>
<h2 id="development-toolchains-and-compilers">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.27.1</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
<li>STM32H743I-EVAL (with Ethernet interface)</li>
</ul>
<h2 id="known-limitations">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:</li>
<li>Server sockets are not supported</li>
</ul>
</div>
</div>
<div class="col-sm-12 col-lg-8">
<h1 id="update-history-1">Update History</h1>
<div class="collapse">
<input type="checkbox" id="collapse-section7" checked aria-hidden="false"> <label for="collapse-section7" aria-hidden="true">V2.0.0 / 2020-April-08</label>
<div>
<h2 id="main-changes-1">Main changes</h2>
<h3 id="network-library-core-1">Network library core</h3>
<ul>
<li>Prepare support of IPv6 addresses, making code independent from network address definition</li>
<li>Clean up template of configuration file to allow application to overwrite default definition</li>
<li>Add performance monitoring primitives</li>
<li>Add memory allocation primitive to track leakage</li>
<li>Add yield feature for specific network interface</li>
</ul>
<h3 id="wifi-generic-support">WIFI generic support</h3>
<ul>
<li>Add WIFI Access point support, with needed new API (set_channel, set mode )</li>
<li>Update state machine management to support AP and STA connection</li>
<li>Add support of concurrent interface, for instance an AP running in parallel with a STA</li>
<li>Extend list of supported security mode</li>
</ul>
<h3 id="cellular-network-interface">Cellular Network interface</h3>
<ul>
<li>Add compatibility until XCube Cellular package 1.5.0</li>
</ul>
<h3 id="cypress-wifi-network-interface">Cypress WIFI Network interface</h3>
<ul>
<li>Add support of Access Point mode</li>
</ul>
<h3 id="mxchip-wifi-network-interface-1">MXCHIP WIFI Network interface</h3>
<ul>
<li>Newly supported WIFI module</li>
<li>Add support of UART and SPI based module</li>
<li>Add templates files</li>
</ul>
<h3 id="inventek-wifi-network-interface">Inventek WIFI network interface</h3>
<ul>
<li>Add support of net_getpeername and net_getsocketinfo API</li>
</ul>
<h3 id="bug-fixes-1">Bug fixes</h3>
<ul>
<li>Fix memory leakage for Cypress WHD based devices</li>
<li>Fix memory leakage for secure socket (based on MbedTLS )</li>
<li>Fix timeout definition for Cellular devices on connection</li>
<li>Fix state machine on deinitialization transition</li>
</ul>
<h2 id="development-toolchains-and-compilers-1">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.27.1</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-1">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
<li>STM32H743I-EVAL (with Ethernet interface)</li>
</ul>
<h2 id="known-limitations-1">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:</li>
<li>Server sockets are not supported</li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section6" aria-hidden="true"> <label for="collapse-section6" aria-hidden="true">V1.1.0 / 2019-November-27</label>
<div>
<h2 id="main-changes-2">Main changes</h2>
<ul>
<li>Add support for WIFI-WHD devices, create a new network interface</li>
<li>Add support of ethernet on H7 device (STM32H743I-EVAL board)</li>
<li>Restructure code regarding LWIP based network interface</li>
<li>lwip related initialisation is moved to net_conf.c</li>
<li>Compliant with ST-Quality standard
<ul>
<li>Pass MISRA check list</li>
<li>Pass CodeSonar test<br />
</li>
<li>Enforce ST coding style rules</li>
</ul></li>
</ul>
<h3 id="bug-fixes-2">Bug fixes</h3>
<h2 id="development-toolchains-and-compilers-2">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-2">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
<li>STM32H743I-EVAL (with Ethernet interface)</li>
</ul>
<h2 id="known-limitations-2">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:
<ul>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section5" aria-hidden="true"> <label for="collapse-section5" aria-hidden="true">V1.0.5 / 2019-October-8</label>
<div>
<h2 id="main-changes-3">Main changes</h2>
<ul>
<li>Add support for CMSIS-OS2</li>
</ul>
<h3 id="bug-fixes-3">Bug fixes</h3>
<ul>
<li>Fix cellular network interface, required to used firmware version &gt;= BG96MAR02A08M1G.</li>
<li>Fix message order on notification</li>
</ul>
<h2 id="development-toolchains-and-compilers-3">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-3">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
</ul>
<h2 id="known-limitations-3">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:
<ul>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section4" aria-hidden="true"> <label for="collapse-section4" aria-hidden="true">V1.0.4 / 2019-August-1</label>
<div>
<h2 id="main-changes-4">Main changes</h2>
<ul>
<li>Renamed STM32 Connectivity library as STM32 Network library</li>
<li>Re-implement State management of network interface ,renamed states from INITIALIZED to READY , suppress some unused states</li>
<li>Add and test support of embedded Inventek WIFI TLS socket</li>
<li>Run MISRA checks</li>
</ul>
<h3 id="bug-fixes-4">Bug fixes</h3>
<ul>
<li>Ethernet template: properly clear the “Receive buffer unavailable status” in case of RX descriptor underflow.</li>
<li>Fix missing semaphore on net_wait API</li>
</ul>
<h2 id="development-toolchains-and-compilers-4">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-4">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
</ul>
<h2 id="known-limitations-4">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:
<ul>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section3" aria-hidden="true"> <label for="collapse-section3" aria-hidden="true">V1.0.3 / 2019-july-05</label>
<div>
<h2 id="main-changes-5">Main changes</h2>
<h3 id="bug-fixes-5">Bug fixes</h3>
<ul>
<li>Run Astyle checks</li>
<li>Add doxygen doc generation</li>
<li>Fix issue on F769 Ethernet interface , avoid blocking thread on alloc failure from LWIP pool</li>
</ul>
<h2 id="development-toolchains-and-compilers-5">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-5">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
</ul>
<h2 id="known-limitations-5">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:
<ul>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section2" aria-hidden="true"> <label for="collapse-section2" aria-hidden="true">V1.0.2 / 2019-june-07</label>
<div>
<h2 id="main-changes-6">Main changes</h2>
<h3 id="bug-fixes-6">Bug fixes</h3>
<ul>
<li>Ethernet template: properly clear the “Receive buffer unavailable status” in case of RX descriptor underflow.</li>
</ul>
<h2 id="development-toolchains-and-compilers-6">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-6">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
</ul>
<h2 id="known-limitations-6">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02:
<ul>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
<div class="collapse">
<input type="checkbox" id="collapse-section1" aria-hidden="true"> <label for="collapse-section1" aria-hidden="true">V1.0.0 / 2019-april-26</label>
<div>
<h2 id="initial-version">Initial version</h2>
<ul>
<li>Features supported:
<ul>
<li>BSD socket like API</li>
<li>Network interface control API (init, start, stop, …)</li>
<li>TCP and UPD protocols</li>
<li>Client and server connections</li>
<li>DNS and ping services</li>
<li>Secure socket on top of mbedTLS</li>
<li>RTOS and bare metal applications are supported</li>
<li>IPv4 address only is supported (IPv6 will be available in a future version)</li>
<li>Wi-Fi, Ethernet and cellular connectivities</li>
</ul></li>
</ul>
<h2 id="development-toolchains-and-compilers-7">Development Toolchains and Compilers</h2>
<ul>
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
<li>System Workbench for STM32. Version 2.8.1.</li>
</ul>
<h2 id="supported-devices-and-boards-7">Supported Devices and Boards</h2>
<ul>
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
</ul>
<h2 id="known-limitations-7">Known Limitations</h2>
<ul>
<li>Cellular on P-L496G-CELL02
<ul>
<li>UDP sockets are not supported</li>
<li>Server sockets are not supported</li>
</ul></li>
</ul>
</div>
</div>
</div>
</div>
<footer class="sticky">
For complete documentation on <mark>STM32</mark> microcontrollers please visit <a href="http://www.st.com/stm32" class="uri">http://www.st.com/stm32</a>
</footer>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1,319 @@
/**
******************************************************************************
* @file net_address.c
* @author MCD Application Team
* @brief Implements network address conversion routines
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#define NET_IN_RANGE(c, lo, up) (((c) >= (lo)) && ((c) <= (up)))
#define NET_IS_PRINT(c) (NET_IN_RANGE(c, 0x20, 0x7f))
#define NET_ISDIGIT(c) (NET_IN_RANGE(c, '0', '9'))
#define NET_ISXDIGIT(c) (NET_ISDIGIT(c) || NET_IN_RANGE(c, 'a', 'f') || NET_IN_RANGE(c, 'A', 'F'))
#define NET_ISLOWER(c) (NET_IN_RANGE(c, 'a', 'z'))
#define NET_ISSPACE(c) (((c) == ' ')\
|| ((c) == '\f') || ((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == '\v'))
/**
* @brief Function description
* @param Params
* @retval socket status
*/
#if !defined(NET_USE_LWIP_DEFINITIONS)
char_t *net_ntoa_r(const net_ip_addr_t *addr, char_t *buf, int32_t buflen)
{
uint32_t NET_S_ADDR;
uint8_t val;
char_t inv[3];
uint8_t *ap;
uint8_t rem;
uint8_t i;
int32_t len = 0;
char_t *buf_ret;
NET_S_ADDR = addr->addr;
ap = (uint8_t *)&NET_S_ADDR;
for (uint8_t n = 0; n < (uint8_t) 4; n++)
{
i = 0;
val = ap[n];
do
{
rem = val % 10U;
val /= 10U;
inv[i] = (char_t)'0' + rem;
i++;
} while (val != 0U);
while (i != 0U)
{
i--;
if (len < buflen)
{
buf[len] = inv[i];
len++;
}
}
if ((n < 3U) && (len < buflen))
{
buf[len] = (char_t) '.';
len++;
}
}
if (len < buflen)
{
buf[len] = (char_t) '\0';
buf_ret = buf;
}
else
{
buf_ret = NULL;
}
return buf_ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
char_t *net_ntoa(const net_ip_addr_t *addr)
{
static char_t str[16];
return net_ntoa_r(addr, str, 16);
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
int32_t net_aton(const char_t *ptr, net_ip_addr_t *addr)
{
uint32_t val = 0;
uint32_t base;
char_t c0;
const char_t *cp = ptr;
uint32_t parts[4];
uint32_t *pp = parts;
int32_t ret = 1;
int32_t done;
c0 = *cp;
done = 0;
for (;;)
{
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, 1-9=decimal.
*/
if (done == 1)
{
break;
}
if (!NET_ISDIGIT(c0))
{
ret = 0;
done = 1;
}
else
{
val = 0;
base = 10;
if (c0 == '0')
{
++cp;
c0 = (char_t) * cp;
if ((c0 == (char_t) 'x') || (c0 == (char_t) 'X'))
{
base = 16;
++cp;
c0 = (char_t) * cp;
}
else
{
base = 8;
}
}
for (;;)
{
if (NET_ISDIGIT(c0))
{
val = (val * base) + (uint32_t)c0 - (uint32_t) '0';
++cp;
c0 = (char_t) * cp;
}
else if ((base == 16U) && NET_ISXDIGIT(c0))
{
val = (val << 4) | ((uint32_t)c0 + 10U - (uint32_t)(NET_ISLOWER(c0) ? 'a' : 'A'));
++cp;
c0 = (char_t) * cp;
}
else
{
break;
}
}
if (c0 == '.')
{
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16 bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= (parts + 3))
{
ret = 0;
done = 1;
}
else
{
*pp = val;
pp++;
++cp;
c0 = (char_t) * cp;
}
}
else
{
done = 1;
}
}
}
/*
* Check for trailing characters.
*/
if ((c0 != (char_t)'\0') && (NET_ISSPACE((c0)) == false))
{
ret = 0;
}
else
/*
* Concoct the address according to
* the number of parts specified.
*/
{
switch (pp - parts + 1)
{
case 0:
ret = 0; /* initial nondigit */
break;
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if (val > 0xffffffUL)
{
ret = 0;
}
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffffU)
{
ret = 0;
break;
}
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xffU)
{
ret = 0;
break;
}
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
default:
ret = 0;
break;
}
}
if (ret == 1)
{
if (addr != NULL)
{
addr->addr = NET_HTONL(val);
}
}
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
int32_t net_aton_r(const char_t *cp)
{
net_ip_addr_t val;
int32_t ret;
val.addr = 0;
if (net_aton(cp, &val) != 0)
{
ret = (int32_t) val.addr;
}
else
{
ret = 0;
}
return (ret);
}
#endif /* NET_USE_LWIP_DEFINITIONS */
uint16_t net_get_port(net_sockaddr_t *addr)
{
/*cstat -MISRAC2012-Rule-11.3 -MISRAC2012-Rule-11.8 */
return (NET_NTOHS(((net_sockaddr_in_t *)addr)->sin_port));
/*cstat +MISRAC2012-Rule-11.3 +MISRAC2012-Rule-11.8 +MISRAC2012-Rule-10.8 Cast */
}
void net_set_port(net_sockaddr_t *addr, uint16_t port)
{
/*cstat -MISRAC2012-Rule-11.3 Cast */
((net_sockaddr_in_t *)addr)->sin_port = NET_HTONS(port);
/*cstat +MISRAC2012-Rule-11.3 Cast */
}
net_ip_addr_t net_get_ip_addr(net_sockaddr_t *addr)
{
net_ip_addr_t ipaddr;
uint32_t addrv;
/*cstat -MISRAC2012-Rule-11.3 Cast */
addrv = ((net_sockaddr_in_t *)addr)->sin_addr.s_addr;
/*cstat +MISRAC2012-Rule-11.3 Cast */
NET_COPY(ipaddr, addrv);
return ipaddr;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,431 @@
/**
******************************************************************************
* @file net_class_extension.c
* @author MCD Application Team
* @brief Specific class interface function implementation
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#define MATCH(a,b) (a & (b) == (b))
/**
* @brief Convert wifi security enum value to string
* @param sec is an unsigned integer
* @retval a constant string , for instance "Open" or "WPA2-AES"
*/
const char_t *net_wifi_security_to_string(uint32_t sec)
{
const char_t *s;
if (sec == NET_WIFI_SM_OPEN)
{
s = "Open";
}
else if (sec == NET_WIFI_SM_WEP_SHARED)
{
s = "WEP-shared";
}
else if (sec == NET_WIFI_SM_WPA_TKIP_PSK)
{
s = "WPA-TKIP";
}
else if (sec == NET_WIFI_SM_WPA_MIXED_PSK)
{
s = "WPA-Mixed";
}
else if (sec == NET_WIFI_SM_WPA2_AES_PSK)
{
s = "WPA2-AES";
}
else if (sec == NET_WIFI_SM_WPA2_TKIP_PSK)
{
s = "WPA2-TKIP";
}
else if (sec == NET_WIFI_SM_WPA2_MIXED_PSK)
{
s = "WPA2_Mixed";
}
else if (sec == NET_WIFI_SM_WPA2_FBT_PSK)
{
s = "WPA2-FBT";
}
else if (sec == NET_WIFI_SM_WPA3_SAE)
{
s = "WPA3";
}
else if (sec == NET_WIFI_SM_WPA3_WPA2_PSK)
{
s = "WPA3-WPA2";
}
else if (sec == NET_WIFI_SM_WPA_TKIP_ENT)
{
s = "WPA-TKIP-Ent";
}
else if (sec == NET_WIFI_SM_WPA_AES_ENT)
{
s = "WPA-AES-Ent";
}
else if (sec == NET_WIFI_SM_WPA2_TKIP_ENT)
{
s = "WPA2-TKIP-Ent";
}
else if (sec == NET_WIFI_SM_WPA2_AES_ENT)
{
s = "WPA2-AES-Ent";
}
else if (sec == NET_WIFI_SM_WPA2_MIXED_ENT)
{
s = "WPA2-Mixed-Ent";
}
else if (sec == NET_WIFI_SM_WPA2_FBT_ENT)
{
s = "WPA-FBT-Ent";
}
else if (sec == NET_WIFI_SM_IBSS_OPEN)
{
s = "IBS";
}
else if (sec == NET_WIFI_SM_WPS_OPEN)
{
s = "WPS";
}
else if (sec == NET_WIFI_SM_WPS_SECURE)
{
s = "WPS-AES";
}
else
{
s = "unknown";
}
return s;
}
/**
* @brief Convert a string to a security enum value
* @param sec is a pointer to a string
*/
uint32_t net_wifi_string_to_security(char_t *sec)
{
uint32_t ret = NET_WIFI_SM_UNKNOWN;
if (strcmp(sec, "Open") == 0)
{
ret = NET_WIFI_SM_OPEN;
}
if (strcmp(sec, "WEP-shared") == 0)
{
ret = NET_WIFI_SM_WEP_SHARED;
}
if (strcmp(sec, "WPA-TKIP") == 0)
{
ret = NET_WIFI_SM_WPA_TKIP_PSK;
}
if (strcmp(sec, "WPA-Mixed") == 0)
{
ret = NET_WIFI_SM_WPA_MIXED_PSK;
}
if (strcmp(sec, "WPA2-AES") == 0)
{
ret = NET_WIFI_SM_WPA2_AES_PSK;
}
if (strcmp(sec, "WPA2-TKIP") == 0)
{
ret = NET_WIFI_SM_WPA2_TKIP_PSK;
}
if (strcmp(sec, "WPA2-Mixed") == 0)
{
ret = NET_WIFI_SM_WPA2_MIXED_PSK;
}
if (strcmp(sec, "WPA2-DBT") == 0)
{
ret = NET_WIFI_SM_WPA2_FBT_PSK;
}
if (strcmp(sec, "WPA3") == 0)
{
ret = NET_WIFI_SM_WPA3_SAE;
}
if (strcmp(sec, "WPA3-WPA2") == 0)
{
ret = NET_WIFI_SM_WPA3_WPA2_PSK;
}
if (strcmp(sec, "WPA-TKIP-Ent") == 0)
{
ret = NET_WIFI_SM_WPA_TKIP_ENT;
}
if (strcmp(sec, "WPA-AES-Ent") == 0)
{
ret = NET_WIFI_SM_WPA_AES_ENT;
}
if (strcmp(sec, "WPA2-TKIP-Ent") == 0)
{
ret = NET_WIFI_SM_WPA2_TKIP_ENT;
}
if (strcmp(sec, "WPA2-AES-Ent") == 0)
{
ret = NET_WIFI_SM_WPA2_AES_ENT;
}
if (strcmp(sec, "WPA2-Mixed-Ent") == 0)
{
ret = NET_WIFI_SM_WPA2_MIXED_ENT;
}
if (strcmp(sec, "WPA-FBT-Ent") == 0)
{
ret = NET_WIFI_SM_WPA2_FBT_ENT;
}
if (strcmp(sec, "IBS") == 0)
{
ret = NET_WIFI_SM_IBSS_OPEN;
}
if (strcmp(sec, "WPS") == 0)
{
ret = NET_WIFI_SM_WPS_OPEN;
}
if (strcmp(sec, "WPS-AES") == 0)
{
ret = NET_WIFI_SM_WPS_SECURE;
}
return ret;
}
/**
* @brief start a wifi scan operation
* @param pnetif_in is a pointer to an allocated network interface structure
* @param mode is an enum to specify type of scan mode to be performed
* @param ssid is a pointer to a string, when not null, scan searches only this ssid
* @retval return the number of found access point , max value is "number".
* This function is a synchronous function.
*/
int32_t net_wifi_scan(net_if_handle_t *pnetif_in, net_wifi_scan_mode_t mode, char_t *ssid)
{
int32_t ret = NET_OK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
ret = NET_ERROR_PARAMETER;
}
else if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
{
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_scan function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
if (pnetif->pdrv->extension.wifi->scan(pnetif, mode, ssid) != NET_OK)
{
NET_DBG_ERROR("Error when executing net_wifi_scan function\n");
ret = NET_ERROR_GENERIC;
}
}
return ret;
}
/**
* @brief Get the result of scan operation , once event has been recevied
* @param pnetif_is a pointer to an allocated network interface structure
* @param results is a pointer to an allocated array of net_wifi_scan_results_t
* @param number is unsigned integer , size of the array 'results'
* @retval return the number of found access point , max value is "number".
*/
int32_t net_wifi_get_scan_results(net_if_handle_t *pnetif_in, net_wifi_scan_results_t *results, uint8_t number)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
ret = NET_ERROR_PARAMETER;
}
else if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
{
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_scan function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
ret = pnetif->pdrv->extension.wifi->get_scan_results(pnetif, results, number);
}
return ret;
}
/**
* @brief set the credential of a wifi interface, can be AP or STA credentials
* @param pnetif_is a pointer to an allocated network interface structure
* @param credentials a pointer to a const allocated structure which contain credentials values (ssid , passwd)
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_wifi_set_credentials(net_if_handle_t *pnetif, const net_wifi_credentials_t *credentials)
{
pnetif->pdrv->extension.wifi->credentials = credentials;
return NET_OK;
}
/**
* @brief set the acess mode for a wifi interface: AP or STA mode
* @param pnetif_is a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_wifi_set_access_mode(net_if_handle_t *pnetif, net_wifi_mode_t mode)
{
pnetif->pdrv->extension.wifi->mode = mode;
return NET_OK;
}
/**
* @brief set the wifi channel to used for an AP
* @param pnetif_is a pointer to an allocated network interface structure
* @param channel is an unsigned 8 bit integer
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_wifi_set_access_channel(net_if_handle_t *pnetif, uint8_t channel)
{
pnetif->pdrv->extension.wifi->access_channel = channel;
return NET_OK;
}
/**
* @brief set wifi power save mode
* @param pnetif_is a pointer to an allocated network interface structure
* @param powersave is a pointer to an allocated structute to define the powersave mode
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_wifi_set_powersave(net_if_handle_t *pnetif_in, const net_wifi_powersave_t *powersave)
{
int32_t ret = NET_OK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
ret = NET_ERROR_PARAMETER;
}
else
{
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
{
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_set_powersave function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
pnetif->pdrv->extension.wifi->powersave = powersave;
}
}
return ret;
}
/**
* @brief set wifi extension parameter
* @param pnetif_is a pointer to an allocated network interface structure
* @param param is an enum value to specify which parameter to set
* @param data is a pointer to an allocated opaque structure to specify the parameter value
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_wifi_set_param(net_if_handle_t *pnetif, const net_wifi_param_t param, void *data)
{
int32_t ret;
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
{
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_set_param function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
ret = pnetif->pdrv->extension.wifi->set_param(param, data);
}
return ret;
}
/**
* @brief set the credential of a cellular interface
* @param pnetif_is a pointer to an allocated network interface structure
* @param credentials a pointer to a const allocated structure which contains credentials values (ssid , passwd)
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_cellular_set_credentials(net_if_handle_t *pnetif_in, const net_cellular_credentials_t *credentials)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
ret = NET_ERROR_PARAMETER;
}
else
{
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_CELLULAR)
{
NET_DBG_ERROR("Incorrect class interface when calling net_cellular_get_radio_results function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
pnetif->pdrv->extension.cellular->credentials = credentials;
ret = NET_OK;
}
}
return ret;
}
/**
* @brief get cellular radio information
* @param pnetif_is a pointer to an allocated network interface structure
* @param reults is a pointer to an allocated net_cellular_radio_results_t structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_cellular_get_radio_results(net_if_handle_t *pnetif_in, net_cellular_radio_results_t *results)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
ret = NET_ERROR_PARAMETER;
}
else
{
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_CELLULAR)
{
NET_DBG_ERROR("Incorrect class interface when calling net_cellular_get_radio_results function\n");
ret = NET_ERROR_PARAMETER;
}
else
{
ret = pnetif->pdrv->extension.cellular->get_radio_results(results);
}
}
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,569 @@
/**
******************************************************************************
* @file net_core.c
* @author MCD Application Team
* @brief Network interface core implementation
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
static void netif_add_to_list(net_if_handle_t *pnetif);
static void netif_remove_from_list(net_if_handle_t *pnetif);
static net_if_handle_t *net_if_list = NULL;
#ifndef __IO
/*cstat -MISRAC2012-Rule-21.1 */
#define __IO volatile
/*cstat +MISRAC2012-Rule-21.1 */
#endif /* IO */
static void netif_add_to_list(net_if_handle_t *pnetif)
{
LOCK_NETIF_LIST();
if (net_if_list == NULL)
{
net_if_list = pnetif;
}
else
{
/*add it to end of the list*/
net_if_handle_t *plastnetif;
plastnetif = net_if_list;
while (plastnetif->next != NULL)
{
plastnetif = plastnetif->next;
}
plastnetif->next = pnetif;
}
UNLOCK_NETIF_LIST();
}
static void netif_remove_from_list(net_if_handle_t *pnetif)
{
net_if_handle_t *pnetif_prev;
LOCK_NETIF_LIST();
if (net_if_list == pnetif)
{
net_if_list = net_if_list->next;
}
else
{
for (pnetif_prev = net_if_list; pnetif_prev->next != NULL; pnetif_prev = pnetif_prev->next)
{
if (pnetif_prev->next == pnetif)
{
pnetif_prev->next = pnetif->next;
break;
}
}
}
UNLOCK_NETIF_LIST();
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
net_if_handle_t *net_if_find(net_sockaddr_t *addr)
{
net_if_handle_t *ptr;
net_ip_addr_t ipaddr;
net_ip_addr_t ipaddr_zero;
NET_ZERO(ipaddr_zero);
NET_ZERO(ipaddr);
if (addr != NULL)
{
ipaddr = net_get_ip_addr(addr);
}
LOCK_NETIF_LIST();
ptr = net_if_list;
if (NET_DIFF(ipaddr, ipaddr_zero) != 0)
{
do
{
if (NET_EQUAL(ptr->ipaddr, ipaddr))
{
break;
}
ptr = ptr->next;
} while (ptr != NULL);
}
UNLOCK_NETIF_LIST();
return ptr;
}
net_if_handle_t *netif_check(net_if_handle_t *pnetif_in)
{
net_if_handle_t *pnetif = pnetif_in;
if (pnetif == NULL)
{
/* get default interface*/
pnetif = net_if_find(NULL);
if (pnetif == NULL)
{
NET_DBG_ERROR("No network interface defined");
}
}
return pnetif;
}
/**
* @brief Wait for state transtion
* @param pnetif a pointer to the selected network interface
* @param state the expected state
* @param timeout max time to wait in ms for the transition
* @retval 0 in case of success, an error code otherwise
*/
extern uint32_t HAL_GetTick(void);
int32_t net_if_wait_state(net_if_handle_t *pnetif, net_state_t state, uint32_t timeout)
{
int32_t ret = NET_OK;
__IO net_state_t *p;
p = &pnetif->state;
uint32_t start_time = HAL_GetTick();
while (*p != state)
{
if (HAL_GetTick() >= (start_time + timeout))
{
ret = NET_TIMEOUT;
break;
}
WAIT_STATE_CHANGE(timeout);
}
return ret;
}
void net_if_notify(net_if_handle_t *pnetif, net_evt_t event_class, uint32_t event_id, void *event_data)
{
/* call the user Handler first ,FIXME , first or not , race between wait state transition and user handler */
if ((NULL != pnetif->event_handler) && (NULL != pnetif->event_handler->callback))
{
pnetif->event_handler->callback(pnetif->event_handler->context, event_class, event_id, event_data);
}
}
#ifdef NET_USE_RTOS
static int32_t net_initialized = 0;
#endif /* NET_USE_RTOS */
/** @defgroup State State Management Network Framework
* Application uses this set of function to control the network interface state.
* Normal state flow is init => start => connect.
* Socket interface can be used when connected state is reached.Network interface is connected and got an IP address.
* To finish, flow is disconnect,stop,deinit. All connection are closed and allocated resources are freed.
* State transition are asynchronous but could be implemented in a synchronous way depending on the selected
* network interface. Once a transition is requested,the net_wait_state primitive should be used to wait
* for transition to occur.
* @{
*/
/**
* @brief Perform network interface initialization
* @param pnetif a pointer to an allocated network interface structure
* @param driver_init a pointer to a function which define the driver to use
* @param event_handler a calback function to manage event from network framework
* @retval 0 in case of success, an error code otherwise
* This function is a synchronous function.
*/
int32_t net_if_init(net_if_handle_t *pnetif_in, net_if_driver_init_func driver_init,
const net_event_handler_t *event_handler)
{
int32_t ret;
net_if_handle_t *pnetif = pnetif_in;
#ifdef NET_USE_RTOS
if (net_initialized == 0)
{
net_init_locks();
net_initialized = 1;
}
#endif /* NET_USE_RTOS */
if (pnetif != NULL)
{
pnetif->event_handler = event_handler;
pnetif->state = NET_STATE_INITIALIZED;
netif_add_to_list(pnetif);
ret = (*driver_init)(pnetif);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot be initialized.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
}
else
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
return ret;
}
/**
* @brief Perform network interface de-initialization
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_deinit(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_state_manage_event(pnetif, NET_EVENT_CMD_DEINIT);
pnetif->state = NET_STATE_DEINITIALIZED;
if (ret == NET_OK)
{
netif_remove_from_list(pnetif);
}
#ifdef NET_USE_RTOS
if (net_initialized == 1)
{
net_destroy_locks();
net_initialized = 0;
}
#endif /* NET_USE_RTOS */
return ret;
}
/**
* @brief Start network interface
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_start(net_if_handle_t *pnetif)
{
return net_state_manage_event(pnetif, NET_EVENT_CMD_START);
}
/**
* @brief Stop network interface
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_stop(net_if_handle_t *pnetif)
{
return net_state_manage_event(pnetif, NET_EVENT_CMD_STOP);
}
/**
* @brief Yield data from network interface
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_yield(net_if_handle_t *pnetif_in, uint32_t timeout)
{
int32_t ret = NET_OK;
net_if_handle_t *pnetif;
net_state_t state;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
(void) net_if_getState(pnetif, &state);
if (state == NET_STATE_CONNECTED)
{
if (NULL != pnetif->pdrv->if_yield)
{
ret = pnetif->pdrv->if_yield(pnetif, timeout);
}
if (ret != NET_OK)
{
NET_DBG_ERROR("Interface yield failed!!!");
ret = NET_ERROR_STATE_TRANSITION;
}
}
else
{
NET_DBG_ERROR("Incorrect requested State transition");
ret = NET_ERROR_INVALID_STATE_TRANSITION;
}
}
else
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
return ret;
}
/**
* @brief Connect network interface
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_connect(net_if_handle_t *pnetif)
{
return net_state_manage_event(pnetif, NET_EVENT_CMD_CONNECT);
}
/**
* @brief Disconnect network interface
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_disconnect(net_if_handle_t *pnetif)
{
return net_state_manage_event(pnetif, NET_EVENT_CMD_DISCONNECT);
}
/**
* @brief get network interface state
* @param pnetif a pointer to an allocated network interface structure
* @param state a pointer to a net_state_t enum
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_getState(net_if_handle_t *pnetif_in, net_state_t *state)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
*state = pnetif->state;
ret = NET_OK;
}
else
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
return ret;
}
/** @defgroup State
* @}
*/
/**
* @brief Enable power save mode
* @param pnetif a pointer to an allocated network interface structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_powersave_enable(net_if_handle_t *pnetif_in)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
if (pnetif->state == NET_STATE_CONNECTED)
{
ret = pnetif->pdrv->if_powersave_enable(pnetif);
}
else
{
NET_DBG_ERROR("Power-save cannot be enabled when the device is not connected");
ret = NET_ERROR_INVALID_STATE_TRANSITION;
}
}
else
{
ret = NET_ERROR_PARAMETER;
NET_DBG_ERROR("Invalid interface.");
}
return ret;
}
/** @defgroup GetAndSet Get and Set Network Interface information
* @{
*/
/**
* @brief get MAC address
* @param pnetif a pointer to an allocated network interface structure
* @param mac a pointer to an allocated macaddr_t structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_get_mac_address(net_if_handle_t *pnetif_in, macaddr_t *mac)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
if (NET_STATE_DEINITIALIZED != pnetif->state)
{
(void) memcpy(mac, &pnetif->macaddr, sizeof(macaddr_t));
ret = NET_OK;
}
else
{
ret = NET_ERROR_INTERFACE_FAILURE;
NET_DBG_ERROR("Interface not yet initialized or in error state");
}
}
else
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
return ret;
}
/**
* @brief get IP address
* @param pnetif a pointer to an allocated network interface structure
* @param ip a pointer to an allocated net_ip_addr_t structure
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_get_ip_address(net_if_handle_t *pnetif_in, net_ip_addr_t *ip)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
if (pnetif->state == NET_STATE_CONNECTED)
{
*ip = pnetif->ipaddr;
ret = NET_OK;
}
else
{
NET_DBG_ERROR("Can get ipaddr for un connected network interface");
ret = NET_ERROR_INTERFACE_FAILURE;
}
}
else
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
return ret;
}
/**
* @brief get host by name
* @param pnetif a pointer to an allocated network interface structure
* @param name is a pointer to the hostname string
* @param addr is a pointer to the structure net_sockaddr_t
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_gethostbyname(net_if_handle_t *pnetif_in, net_sockaddr_t *addr, char_t *name)
{
int32_t ret = NET_ERROR_FRAMEWORK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
ret = pnetif->pdrv->pgethostbyname(pnetif, addr, name);
}
return ret;
}
/**
* @brief ping a remote machine
* @param pnetif a pointer to an allocated network interface structure
* @param addr is a pointer to the socketaddr of the remote host
* @param count is an integer, number of iteration to ping the remote machine
* @param delay is an integer, maximum delay in millisecond to wait for remote answer
* @param response is an array of <count> integer, containing the time to get response for each iteration.
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_ping(net_if_handle_t *pnetif_in, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t response[])
{
int32_t ret = NET_ERROR_FRAMEWORK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
ret = pnetif->pdrv->pping(pnetif, addr, count, delay, response);
}
return ret;
}
/**
* @brief enable or disable dhcp mode
* @param pnetif a pointer to an allocated network interface structure
* @param mode is a boolean , true to activate DHCP
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_set_dhcp_mode(net_if_handle_t *pnetif_in, bool mode)
{
int32_t ret = NET_ERROR_FRAMEWORK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
pnetif->dhcp_mode = mode;
ret = NET_OK;
}
return ret;
}
/**
* @brief setting ipaddr , gateway and netmask forcurrent network interface
* @param pnetif a pointer to an allocated network interface structure
* @param ipaddr is a pointer to and net_ip_addr_t structure used as ip address
* @param gateway is a pointer to the net_ip_addr_t structure used as gateway address
* @param netmask is a pointer to the net_ip_addr_t structure used as the netmask
* @retval 0 in case of success, an error code otherwise
*/
int32_t net_if_set_ipaddr(net_if_handle_t *pnetif_in, net_ip_addr_t ipaddr,
net_ip_addr_t gateway, net_ip_addr_t netmask)
{
int32_t ret = NET_ERROR_FRAMEWORK;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif != NULL)
{
pnetif->static_ipaddr = ipaddr;
pnetif->static_gateway = gateway;
pnetif->static_netmask = netmask;
ret = NET_OK;
}
return ret;
}
/** @defgroup GetAndSet
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,819 @@
/**
******************************************************************************
* @file net_os.c
* @author MCD Application Team
* @brief OS needed functions implementation
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#include "stdarg.h"
#ifdef NET_USE_RTOS
#if (osCMSIS >= 0x20000U)
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#else
#define OSSEMAPHOREWAIT osSemaphoreWait
#endif /* osCMSIS */
extern void *pxCurrentTCB;
static osSemaphoreId net_mutex[NET_LOCK_NUMBER];
void net_init_locks(void)
{
#if (osCMSIS < 0x20000U)
static osSemaphoreDef_t mutex_def[NET_LOCK_NUMBER] = {0};
#endif /* osCMSIS */
#ifdef NET_MBEDTLS_HOST_SUPPORT
net_tls_init();
#endif /* NET_MBEDTLS_HOST_SUPPORT */
for (int32_t i = 0; i < NET_LOCK_NUMBER; i++)
{
#if (osCMSIS < 0x20000U)
net_mutex[i] = osSemaphoreCreate(&mutex_def[i], 1);
#else
net_mutex[i] = osSemaphoreNew(1, 1, NULL);
#endif /* osCMSIS */
NET_ASSERT(net_mutex[i] > 0, "Failed on mutex creation");
}
}
void net_destroy_locks(void)
{
#ifdef NET_MBEDTLS_HOST_SUPPORT
net_tls_destroy();
#endif /* NET_MBEDTLS_HOST_SUPPORT */
for (int32_t i = 0; i < NET_LOCK_NUMBER; i++)
{
(void)osSemaphoreDelete(net_mutex[i]);
}
}
void net_lock(int32_t sock, uint32_t timeout_in)
{
int32_t ret;
uint32_t timeout = timeout_in;
if (timeout == NET_OS_WAIT_FOREVER)
{
/*MISRA issue so hand coded osWaitForever*/
timeout = 0xffffffffU;
}
ret = (int32_t) OSSEMAPHOREWAIT(net_mutex[sock], timeout);
NET_ASSERT(ret == 0, "Failed locking mutex");
}
void net_unlock(int32_t sock)
{
int32_t ret;
ret = (int32_t) osSemaphoreRelease(net_mutex[sock]);
NET_ASSERT(ret == 0, "Failed unlocking mutex");
}
void net_lock_nochk(int32_t sock, uint32_t timeout_in)
{
uint32_t timeout = timeout_in;
if (timeout == NET_OS_WAIT_FOREVER)
{
/* MISRA issue so hand coded t osWaitForever*/
timeout = 0xffffffffU;
}
(void) OSSEMAPHOREWAIT(net_mutex[sock], timeout);
}
void net_unlock_nochk(int32_t sock)
{
(void) osSemaphoreRelease(net_mutex[sock]);
}
#if !defined(NET_ALLOC_DEBUG)
/*cstat -MISRAC2012-Rule-21.2 */
void *net_calloc(size_t n, size_t m)
{
void *p;
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
p = pvPortMalloc(n * m);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (p != NULL)
{
(void) memset(p, 0, n * m);
}
return p;
}
void *net_realloc(void *ptr, size_t size)
{
void *ret;
if (ptr == NULL)
{
if (size != (size_t) 0)
{
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
ret = pvPortMalloc(size);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (ret == NULL)
{
/* to avoid erroneous MISRA detection */
ret = NULL;
}
}
else
{
ret = NULL;
}
}
else
{
if (size != (size_t) 0)
{
void *new_ptr;
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
new_ptr = pvPortMalloc(size);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (new_ptr != NULL)
{
(void) memcpy(new_ptr, ptr, size);
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
vPortFree(ptr);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
ret = new_ptr;
}
else
{
ret = NULL;
}
}
else
{
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
vPortFree(ptr);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
ret = NULL;
}
}
return ret;
}
#endif /* !NET_ALLOC_DEBUG */
/* below function are not supposed to be used , all malloc /free should be mapped to NET_MALLOC/NET_FREE macros */
/* if not the case , it means that some mapping are missing */
/* Using directly the malloc/free prevent to track orginal locatino of memory leakages */
/*cstat -MISRAC2012-Rule-21.2 */
void *realloc(void *p, size_t n)
{
return NET_REALLOC(p, n);
}
void *calloc(size_t n, size_t m)
{
return NET_CALLOC(n, m);
}
void *malloc(size_t n)
{
return NET_MALLOC(n);
}
void free(void *p)
{
NET_FREE(p);
}
/*cstat +MISRAC2012-Rule-21.2 */
#endif /* NET_USE_RTOS */
#ifdef NET_ALLOC_DEBUG
#ifdef NET_ALLOC_DEBUG_TREE
#define NET_DISPLAY_RESULT_COLUMN (NET_DISPLAY_WIDTH-((2U*NET_DISPLAY_RESULT_WIDTH)+1U))
typedef struct net_alloc_node_s
{
const char_t *name;
uint32_t namelen;
struct net_alloc_node_s *down;
struct net_alloc_node_s *up;
struct net_alloc_node_s *neighbour;
uint32_t current_alloc;
uint32_t max_total_alloc;
}
net_alloc_node_t;
static net_alloc_node_t node[NET_ALLOC_MAX_NODE + 1];
static net_alloc_node_t *root_node;
static uint32_t max_node;
#endif /* NET_ALLOC_DEBUG_TREE */
typedef struct net_debug_alloc
{
const char_t *filename;
uint16_t line;
uint16_t iter;
uint32_t size;
void *p;
#ifdef NET_ALLOC_DEBUG_TREE
net_alloc_node_t *node;
#endif /* NET_ALLOC_DEBUG_TREE */
} net_debug_alloc_t;
static uint32_t current_alloc = 0;
static uint32_t max_total_alloc = 0;
static uint32_t iteralloc = 0;
static uint32_t iterfree = 0;
static uint32_t max_alive_alloc = 0;
static net_debug_alloc_t allocated_info[NET_LEAKAGE_ARRAY];
void *net_calloc_debug(size_t n, size_t msize, const char_t *filename, uint32_t line)
{
/*cstat -MISRAC2012-Dir-4.12 */
void *p = net_malloc_debug(n * msize, filename, line);
/*cstat +MISRAC2012-Dir-4.12 */
if (p != NULL)
{
(void) memset(p, 0, n * msize);
}
return p;
}
void *net_realloc_debug(void *p, size_t size, const char_t *filename, uint32_t line)
{
void *ret;
if (p == NULL)
{
if (size != (size_t) 0)
{
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
ret = net_malloc_debug(size, filename, line);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (ret == NULL)
{
/* to avoid erroneous MISRA detection */
ret = NULL;
}
}
else
{
ret = NULL;
}
}
else
{
if (size != (size_t) 0)
{
void *new_ptr;
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
new_ptr = net_malloc_debug(size, filename, line);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (new_ptr != NULL)
{
(void) memcpy(new_ptr, p, size);
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
net_free_debug(p);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
ret = new_ptr;
}
else
{
ret = NULL;
}
}
else
{
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
net_free_debug(p);
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
ret = NULL;
}
}
return ret;
}
#ifdef NET_ALLOC_DEBUG_TREE
static uint32_t getdirlen(const char_t *filename_in)
{
uint32_t len = 0;
const char_t *filename = filename_in;
if (*filename != '\0')
{
if (*filename == '\\')
{
len = 1;
filename++;
}
if ((filename[0] == 'C') && (filename[1] == ':') && (filename[2] == '\\'))
{
len = 3;
filename++;
filename++;
filename++;
}
while ((*filename != '\0') && (*filename != '\\'))
{
len++;
filename++;
}
}
return len;
}
static net_alloc_node_t *get_new_node(const char_t *filename, uint32_t dir_name_len, uint32_t n)
{
net_alloc_node_t *p = &node[max_node];
uint32_t next_dir_name_len = getdirlen(&filename[dir_name_len]);
max_node++;
p->current_alloc = n;
p->max_total_alloc = n;
p->name = filename;
p->namelen = dir_name_len;
if (max_node == NET_ALLOC_MAX_NODE)
{
while (true)
{
(void) printf("ERROR: Please increase NET_ALLOC_MAX_NODE, current value %lu is too low\n", NET_ALLOC_MAX_NODE);
}
}
if (next_dir_name_len != 0U)
{
/*cstat -MISRAC2012-Rule-17.2_a */
p->down = get_new_node(&filename[dir_name_len], next_dir_name_len, n);
/*cstat +MISRAC2012-Rule-17.2_a */
p->down->up = p;
}
return p;
}
static net_alloc_node_t *net_walk_malloc_node(net_alloc_node_t *root, const char_t *filename, uint32_t n)
{
net_alloc_node_t *p = root;
uint32_t dir_name_len = getdirlen(filename);
/* search amoung the neighbour (same level tree) */
while (NULL != p)
{
if (strncmp(p->name, filename, dir_name_len) == 0)
{
/* find a matching neighbour */
p->current_alloc += n;
if (p->current_alloc > p->max_total_alloc)
{
p->max_total_alloc = p->current_alloc;
}
/*printf("ALLOC %s %d %d inc %d\n",filename,p->max_total_alloc,p->current_alloc,n);*/
/* Did not reach a leaf so continue down in the tree */
if (filename[dir_name_len] != '\0')
{
/*cstat -MISRAC2012-Rule-17.2_a */
p = net_walk_malloc_node(p->down, &filename[dir_name_len], n);
/*cstat +MISRAC2012-Rule-17.2_a */
}
break;
}
p = p->neighbour;
}
if (NULL == p)
{
/* create a new neighbour and all the associated tree */
p = get_new_node(filename, dir_name_len, n);
/* add to neighbour list */
if (NULL != root)
{
p->up = root->up;
p->neighbour = root->neighbour;
root->neighbour = p;
}
/* but we should return the leaf */
while (NULL != p->down)
{
p = p->down;
}
}
return p;
}
static void net_walk_free_node(net_alloc_node_t *node_in, uint32_t n)
{
net_alloc_node_t *node = node_in;
while (NULL != node)
{
node->current_alloc -= n;
/*printf("FREE %s %d %d inc %d\n",node->name,node->max_total_alloc,node->current_alloc,n);*/
node = node->up;
}
}
static net_alloc_node_t *net_malloc_tree_start(net_alloc_node_t *root)
{
net_alloc_node_t *p = root;
while (NULL == p->down->neighbour)
{
p = p->down;
}
return p;
}
static void net_malloc_tree_print(net_alloc_node_t *root, uint32_t level)
{
net_alloc_node_t *p = root;
if (level == 0U)
{
(void) printf("\n### Dynamic Allocation tree report, uses %lu nodes out of %lu (%lu bytes)\n", max_node,
NET_ALLOC_MAX_NODE, max_node * sizeof(net_alloc_node_t));
for (uint32_t i = 0U; i < NET_DISPLAY_RESULT_COLUMN; i++)
{
(void) printf("-");
}
(void) printf("%*s %*s", NET_DISPLAY_RESULT_WIDTH, "Maximum", NET_DISPLAY_RESULT_WIDTH, "Leakage");
(void) printf("\n");
}
while (NULL != p)
{
{
char_t s[100];
uint32_t w = level;
uint32_t n = NET_DISPLAY_RESULT_COLUMN - ((level + 1U) * NET_DISPLAY_TAB) - NET_DISPLAY_DIRNAME_LEN;
(void) strncpy(s, &p->name[1], p->namelen - 1U);
s[p->namelen - 1U] = '\0';
(void) printf("%*c", NET_DISPLAY_TAB, ' ');
while (w != 0U)
{
w--;
(void) printf(".");
#if (NET_DISPLAY_TAB>1)
(void)printf("%*c", NET_DISPLAY_TAB - 1U, ' ');
#endif /* NET_DISPLAY_TAB */
}
(void) printf("%-*s", NET_DISPLAY_DIRNAME_LEN, s);
if ((NULL != p->down) && (p->down->max_total_alloc == p->max_total_alloc)
&& (p->down->current_alloc == p->current_alloc))
{
(void) printf("\n");
}
else
{
(void) printf("%*c%*d %*d\n", n, ' ', NET_DISPLAY_RESULT_WIDTH, p->max_total_alloc, NET_DISPLAY_RESULT_WIDTH,
p->current_alloc);
}
}
/*cstat -MISRAC2012-Rule-17.2_a */
net_malloc_tree_print(p->down, level + 1U);
/*cstat +MISRAC2012-Rule-17.2_a */
p = p->neighbour;
}
}
#endif /* NET_ALLOC_DEBUG_TREE */
void *net_malloc_debug(size_t n, const char_t *filename, uint32_t line)
{
void *p;
uint32_t i;
#ifdef NET_USE_RTOS
vTaskSuspendAll();
#endif /* NET_USE_RTOS */
if (iteralloc == 0U)
{
(void) memset(allocated_info, 0, sizeof(allocated_info));
current_alloc = 0;
max_total_alloc = 0;
#ifdef NET_ALLOC_DEBUG_TREE
max_node = 0;
root_node = NULL;
(void) memset(node, 0, sizeof(node));
#endif /* NET_ALLOC_DEBUG_TREE */
}
iteralloc++;
current_alloc += n;
if (current_alloc > max_total_alloc)
{
max_total_alloc = current_alloc;
}
/*printf("-ALLOC- Max %d Current %d inc %d\n",max_total_alloc,current_alloc,n);*/
#ifdef NET_USE_RTOS
p = pvPortMalloc(n);
#else
/*cstat -MISRAC2012-Dir-4.12 -MISRAC2012-Dir-4.7_b -MISRAC2012-Rule-21.3 */
p = malloc(n);
/*cstat +MISRAC2012-Dir-4.12 +MISRAC2012-Dir-4.7_b +MISRAC2012-Rule-21.3 */
#endif /* NET_USE_RTOS */
if ((iteralloc - iterfree) > max_alive_alloc)
{
max_alive_alloc = iteralloc - iterfree;
}
for (i = 0; i < NET_LEAKAGE_ARRAY ; i++)
{
if (allocated_info[i].p == 0U)
{
allocated_info[i].p = p ;
allocated_info[i].size = n ;
allocated_info[i].line = (uint16_t) line ;
allocated_info[i].filename = filename;
allocated_info[i].iter = (uint16_t) iteralloc;
#ifdef NET_ALLOC_DEBUG_TREE
allocated_info[i].node = net_walk_malloc_node(root_node, filename, n);
if (NULL == root_node)
{
root_node = allocated_info[i].node;
/* we got the leaf , so move to top */
while (NULL != root_node->up)
{
root_node = root_node->up;
}
}
#endif /* NET_ALLOC_DEBUG_TREE */
break;
}
}
NET_ASSERT((iteralloc != NET_ALLOC_BREAK), "Reach Allocation break\n");
NET_ASSERT((i != NET_LEAKAGE_ARRAY), "Too much allocations,Please increase NET_LEAKAGE_ARRAY (%lu)in net_conf.h",
NET_LEAKAGE_ARRAY);
#if NET_ALLOC_VERBOSE
(void) printf("%lu bytes allocated: Allocating size %lu at %s:%lu\n", total_alloc, allocated_info[i].size,
allocated_info[i].filename, allocated_info[i].line);
#endif /* NET_ALLOC_VERBOSE */
#ifdef NET_USE_RTOS
(void) xTaskResumeAll();
#endif /* NET_USE_RTOS */
return p;
}
void net_free_debug(void *p)
{
uint32_t i;
#ifdef NET_USE_RTOS
vPortFree(p);
vTaskSuspendAll();
#else
/*cstat -MISRAC2012-Rule-21.3 */
free(p);
/*cstat +MISRAC2012-Rule-21.3 */
#endif /* NET_USE_RTOS */
#ifdef NET_FREE_STOP_ON_NULL_POINTER
if (NULL == p)
{
(void) printf("Free function : Freeing a NULL pointer, seriously ?\n");
while (1);
}
#endif /* NET_STOP_ON_FREEING_NULL_POINTER */
if (NULL != p)
{
iterfree++;
for (i = 0; i < NET_LEAKAGE_ARRAY; i++)
{
if (allocated_info[i].p == p)
{
allocated_info[i].p = NULL;
current_alloc -= allocated_info[i].size;
/*printf("-FREE- Max %d Current %d inc %d\n",max_total_alloc,current_alloc,allocated_info[i].size);*/
#ifdef NET_ALLOC_DEBUG_TREE
net_walk_free_node(allocated_info[i].node, allocated_info[i].size);
#endif /* NET_ALLOC_DEBUG_TREE */
allocated_info[i].size = 0;
break;
}
}
if (i == NET_LEAKAGE_ARRAY)
{
/*cstat -MISRAC2012-Rule-1.3_o -MISRAC2012-Rule-1.3_p -MISRAC2012-Dir-4.7_b -MISRAC2012-Dir-4.13_e -MISRAC2012-Dir-4.13_d */
(void) printf("Free function : did not find this segment %p\n", p);
/*cstat +MISRAC2012-Rule-1.3_o +MISRAC2012-Rule-1.3_p +MISRAC2012-Dir-4.7_b +MISRAC2012-Dir-4.13_e +MISRAC2012-Dir-4.13_d */
while (true) {};
}
}
#ifdef NET_USE_RTOS
(void) xTaskResumeAll();
#endif /* NET_USE_RTOS */
}
void net_alloc_report(void)
{
uint32_t i;
uint32_t count = 0;
uint32_t leak = 0;
#ifdef NET_USE_RTOS
vTaskSuspendAll();
#endif /* NET_USE_RTOS */
(void) printf("\n### Net Malloc report: max alloc: %lu bytes, current leakage: %lu bytes, number of allocation: %lu, number of free: %lu, alloc table usage %lu/%lu (%lu) bytes\n\n",
max_total_alloc, current_alloc, iteralloc, iterfree, max_alive_alloc, NET_LEAKAGE_ARRAY, sizeof(allocated_info));
for (i = 0; i < NET_LEAKAGE_ARRAY; i++)
{
if (allocated_info[i].p != 0)
{
count++;
leak += allocated_info[i].size;
(void) printf("\tAllocation number #%lu Not free %p size %lu at %s:%lu\n", allocated_info[i].iter, allocated_info[i].p,
allocated_info[i].size, allocated_info[i].filename, allocated_info[i].line);
}
}
(void) printf("\n%lu allocation not freed %lu bytes out of %lu allocated byte\n\n", count, leak, max_total_alloc);
#ifdef NET_ALLOC_DEBUG_TREE
net_malloc_tree_print(net_malloc_tree_start(root_node), 0);
#endif /* NET_ALLOC_DEBUG_TREE */
(void) printf("\n### Net Malloc end report\n");
#ifdef NET_USE_RTOS
(void) xTaskResumeAll();
#endif /* NET_USE_RTOS */
}
#endif /* NET_DEBUG_ALLOC */
static struct net_perf
{
uint32_t total;
#if defined(NET_USE_RTOS) && defined(NET_PERF_TASK)
uint32_t elapsed_cycle[NET_PERF_MAXTHREAD];
TaskHandle_t handle[NET_PERF_MAXTHREAD];
#endif
}
perf;
#if defined(NET_PERF_TASK)
/**
* @brief Executed for each context switch in
* @param None
* @retval None
*/
#if !defined(NET_USE_RTOS)
#error "NET_USE_RTOS must be defined to use NET_PERF_TASK"
#endif /* NET_USE_RTOS */
void net_perf_task_in(void)
{
uint32_t i;
TaskHandle_t xHandle = xTaskGetCurrentTaskHandle();
for (i = 0; i < NET_PERF_MAXTHREAD; i++)
{
if (NULL == perf.handle[i])
{
/* new thread */
perf.handle[i] = xHandle;
}
if (xHandle == perf.handle[i])
{
perf.elapsed_cycle[i] -= net_get_cycle();
break;
}
}
NET_ASSERT(NET_PERF_MAXTHREAD != i, "Net perf ,please increase NET_PERF_MAX_THREAD");
}
/**
* @brief Executed for each context switch out
* @param None
* @retval None
*/
void net_perf_task_out(void)
{
uint32_t i;
TaskHandle_t xHandle = xTaskGetCurrentTaskHandle();
for (i = 0; i < NET_PERF_MAXTHREAD; i++)
{
if (NULL == perf.handle[i])
{
/* new thread */
perf.handle[i] = xHandle;
while (true) { };
}
if (xHandle == perf.handle[i])
{
perf.elapsed_cycle[i] += net_get_cycle();
break;
}
}
NET_ASSERT(NET_PERF_MAXTHREAD != i, "Net perf ,please increase NET_PERF_MAX_THREAD");
}
static const char_t *GetTaskName(TaskHandle_t xHandle)
{
TaskStatus_t xTaskDetails;
vTaskGetInfo( /* The handle of the task being queried. */
xHandle,
/* The TaskStatus_t structure to complete with information
on xTask. */
&xTaskDetails,
/* Include the stack high water mark value in the
TaskStatus_t structure. */
pdTRUE,
/* Include the task state in the TaskStatus_t structure. */
eInvalid);
return (const char_t *)xTaskDetails.pcTaskName;
}
#endif /* NET_PERF_TASK */
void net_perf_start(void)
{
/*cstat -MISRAC2012-Rule-11.4 */
NET_DWT_CONTROL |= NET_DWT_CYCCNTENA_BIT ;
NET_DWT_CYCCNT = 0U;
/*cstat +MISRAC2012-Rule-11.4 */
(void) memset(&perf, 0, sizeof(perf));
#if defined(NET_PERF_TASK)
net_perf_task_in();
#endif /* NET_PERF_TASK */
}
void net_perf_report(void)
{
extern uint32_t SystemCoreClock;
#if defined(NET_PERF_TASK)
net_perf_task_out();
#endif /* NET_PERF_TASK */
perf.total += net_get_cycle();
(void) printf("\n### Net Performance report CPU Freq %3lu Mhz\n\n", SystemCoreClock / 1000000U);
(void) printf("\tTotal %12lu cycles %8lu ms\n", perf.total, perf.total / (SystemCoreClock / 1000U));
#if defined(NET_PERF_TASK)
uint32_t count = 0;
(void) printf("\n");
while (perf.handle[count] != 0)
{
(void) printf("\tthread #%lu %25s : %12lu cycles %7lu ms\n", count, GetTaskName(perf.handle[count]),
perf.elapsed_cycle[count], perf.elapsed_cycle[count] / (SystemCoreClock / 1000U));
count++;
}
#endif /* NET_PERF_TASK */
(void) printf("\n### Net Performance end report\n\n");
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,292 @@
/**
******************************************************************************
* @file net_state.c
* @author MCD Application Team
* @brief Management of state machine for network interfaces
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#include "stdarg.h"
#ifdef DEBUGSTATE
static const char_t *eventstr[] =
{
"NET_EVENT_CMD_INIT",
"NET_EVENT_CMD_START",
"NET_EVENT_CMD_CONNECT",
"NET_EVENT_CMD_DISCONNECT",
"NET_EVENT_CMD_STOP",
"NET_EVENT_CMD_DEINIT",
"NET_EVENT_INTERFACE_INITIALIZED",
"NET_EVENT_INTERFACE_READY",
"NET_EVENT_LINK_UP",
"NET_EVENT_LINK_DOWN",
"NET_EVENT_IPADDR",
};
static const char_t *statestr[] =
{
"NET_STATE_DEINITIALIZED",
"NET_STATE_INITIALIZED",
"NET_STATE_STARTING",
"NET_STATE_READY",
"NET_STATE_CONNECTING",
"NET_STATE_CONNECTED",
"NET_STATE_STOPPING",
"NET_STATE_DISCONNECTING",
"NET_STATE_CONNECTION_LOST",
};
#endif /* DEBUGSTATE */
static void set_state(net_if_handle_t *pnetif, net_state_t state)
{
pnetif->state = state;
net_if_notify(pnetif, NET_EVENT_STATE_CHANGE, (uint32_t) state, NULL);
SIGNAL_STATE_CHANGE();
}
static int32_t net_state_initialized(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_CMD_START:
set_state(pnetif, NET_STATE_STARTING);
ret = pnetif->pdrv->if_start(pnetif);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot be started.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
break;
case NET_EVENT_CMD_DEINIT:
ret = pnetif->pdrv->if_deinit(pnetif);
set_state(pnetif, NET_STATE_DEINITIALIZED);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot be deinitialized.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
break;
default:
break;
}
return ret;
}
static int32_t net_state_starting(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_INTERFACE_READY:
set_state(pnetif, NET_STATE_READY);
break;
default:
break;
}
return ret;
}
static int32_t net_state_ready(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_CMD_CONNECT:
set_state(pnetif, NET_STATE_CONNECTING);
ret = pnetif->pdrv->if_connect(pnetif);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot connect.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
break;
case NET_EVENT_CMD_STOP:
set_state(pnetif, NET_STATE_STOPPING);
ret = pnetif->pdrv->if_stop(pnetif);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot stop.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
break;
default:
break;
}
return ret;
}
static int32_t net_state_connecting(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_IPADDR:
set_state(pnetif, NET_STATE_CONNECTED);
break;
case NET_EVENT_CMD_DISCONNECT:
set_state(pnetif, NET_STATE_READY);
break;
default:
break;
}
return ret;
}
static int32_t net_state_connected(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_CMD_DISCONNECT:
set_state(pnetif, NET_STATE_DISCONNECTING);
ret = pnetif->pdrv->if_disconnect(pnetif);
if (NET_OK != ret)
{
NET_DBG_ERROR("Interface cannot disconnect.");
ret = NET_ERROR_INTERFACE_FAILURE;
}
break;
case NET_EVENT_LINK_DOWN:
set_state(pnetif, NET_STATE_CONNECTION_LOST);
break;
default:
break;
}
return ret;
}
static int32_t net_state_disconnecting(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_INTERFACE_READY:
set_state(pnetif, NET_STATE_READY);
break;
default:
break;
}
return ret;
}
static int32_t net_state_stopping(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_INTERFACE_INITIALIZED:
set_state(pnetif, NET_STATE_INITIALIZED);
break;
default:
break;
}
return ret;
}
static int32_t net_state_connection_lost(net_if_handle_t *pnetif, net_state_event_t event)
{
int32_t ret = NET_OK;
switch (event)
{
case NET_EVENT_LINK_UP:
set_state(pnetif, NET_STATE_CONNECTED);
break;
default:
break;
}
return ret;
}
int32_t net_state_manage_event(net_if_handle_t *pnetif_in, net_state_event_t event)
{
int32_t ret;
net_if_handle_t *pnetif;
pnetif = netif_check(pnetif_in);
if (pnetif == NULL)
{
NET_DBG_ERROR("Invalid interface.");
ret = NET_ERROR_PARAMETER;
}
else
{
#ifdef DEBUGSTATE
printf("In state %s , received event %s\n", statestr[pnetif->state], eventstr[event]);
#endif /* DEBUGSTATE */
switch (pnetif->state)
{
case NET_STATE_INITIALIZED:
ret = net_state_initialized(pnetif, event);
break;
case NET_STATE_STARTING:
ret = net_state_starting(pnetif, event);
break;
case NET_STATE_READY:
ret = net_state_ready(pnetif, event);
break;
case NET_STATE_CONNECTING:
ret = net_state_connecting(pnetif, event);
break;
case NET_STATE_CONNECTED:
ret = net_state_connected(pnetif, event);
break;
case NET_STATE_DISCONNECTING:
ret = net_state_disconnecting(pnetif, event);
break;
case NET_STATE_CONNECTION_LOST:
ret = net_state_connection_lost(pnetif, event);
break;
case NET_STATE_STOPPING:
ret = net_state_stopping(pnetif, event);
break;
default:
ret = NET_ERROR_INVALID_STATE;
break;
}
}
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1 @@
/C/users/gentit/Doxygen/bin/Release/doxygen.exe doxyconfig
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,143 @@
/**
******************************************************************************
* @file net_ethernet_driver.c
* @author MCD Application Team
* @brief Ethernet specific BSD-like socket wrapper
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#include "net_ip_ethernet.h"
#include "net_ip_lwip.h"
/* global constructor of the ethernet network interface */
int32_t ethernet_net_driver(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_init(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_deinit(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_start(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_stop(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_connect(net_if_handle_t *pnetif);
static int32_t net_ethernet_if_disconnect(net_if_handle_t *pnetif);
err_t ethernetif_init(struct netif *netif);
err_t ethernetif_deinit(struct netif *netif);
/**
* @brief Function description
* @param Params
* @retval socket status
*/
int32_t ethernet_net_driver(net_if_handle_t *pnetif)
{
int32_t ret;
net_ip_init();
ret = net_ethernet_if_init(pnetif);
return ret;
}
static int32_t net_ethernet_if_init(net_if_handle_t *pnetif)
{
int32_t ret;
/*cstat -MISRAC2012-Rule-11.5 malloc cast*/
net_if_drv_t *pdrv = NET_MALLOC(sizeof(net_if_drv_t));
/*cstat +MISRAC2012-Rule-11.5 */
if (pdrv != NULL)
{
pdrv->if_class = NET_INTERFACE_CLASS_ETHERNET;
pdrv->if_init = net_ethernet_if_init;
pdrv->if_deinit = net_ethernet_if_deinit;
pdrv->if_start = net_ethernet_if_start;
pdrv->if_stop = net_ethernet_if_stop;
pdrv->if_connect = net_ethernet_if_connect;
pdrv->if_disconnect = net_ethernet_if_disconnect;
pdrv->pping = icmp_ping;
pnetif->pdrv = pdrv;
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
ret = NET_OK;
}
else
{
NET_DBG_ERROR("can't allocate memory for es_wifi_driver class\n");
ret = NET_ERROR_NO_MEMORY;
}
return ret;
}
int32_t net_ethernet_if_start(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_ip_add_if(pnetif, ethernetif_init, NET_ETHERNET_FLAG_DEFAULT_IF);
if (ret == NET_OK)
{
(void) strncpy(pnetif->DeviceName, "Ethernet IF", sizeof(pnetif->DeviceName));
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
/* set call back , here to not loose first linkup when if_init is performed */
netif_set_down(pnetif->netif);
netif_set_link_down(pnetif->netif);
netif_set_status_callback(pnetif->netif, net_ip_status_cb);
netif_set_link_callback(pnetif->netif, net_ip_status_cb);
netif_set_link_up(pnetif->netif);
netif_set_up(pnetif->netif);
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
}
return ret;
}
static int32_t net_ethernet_if_connect(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_ip_connect(pnetif);
return ret;
}
static int32_t net_ethernet_if_disconnect(net_if_handle_t *pnetif)
{
int32_t ret;
(void) net_ip_disconnect(pnetif);
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
return ret;
}
static int32_t net_ethernet_if_stop(net_if_handle_t *pnetif)
{
int32_t ret;
(void) net_ip_remove_if(pnetif, ethernetif_deinit);
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
return ret;
}
static int32_t net_ethernet_if_deinit(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
NET_FREE(pnetif->pdrv);
pnetif->pdrv = NULL;
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,675 @@
/**
******************************************************************************
* @file net_ethernet_driver.c
* @author MCD Application Team
* @brief Ethernet specific BSD-like socket wrapper
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include <string.h>
#include "net_connect.h"
#include "net_internals.h"
#include "net_ip_lwip.h"
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "whd.h"
#include "whd_debug.h"
#include "whd_resource_api.h"
#include "whd_wifi_api.h"
#include "whd_network_types.h"
#include "whd_types_int.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
#define NET_CYPRESS_MAX_INTERFACE 4
typedef struct net_cypress_key
{
void *key;
void *value;
} net_cypress_key_t;
static net_cypress_key_t netif2ifp[NET_CYPRESS_MAX_INTERFACE];
static uint32_t cypress_alive_interface_count = 0;
static whd_driver_t whd_driver;
/* create and boot WHD driver */
cy_rslt_t whd_boot(whd_driver_t *whd_driver);
cy_rslt_t whd_powerdown(whd_driver_t *whd_driver);
/* global constructor of the ethernet network interface */
int32_t cypress_whd_net_driver(net_if_handle_t *pnetif);
static err_t low_level_output(struct netif *netif, struct pbuf *p);
static err_t low_level_init(struct netif *netif);
static int32_t net_cypress_whd_if_init(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_if_deinit(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_if_start(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_if_stop(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_if_connect(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_if_disconnect(net_if_handle_t *pnetif);
static int32_t net_cypress_whd_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
static int32_t net_cypress_whd_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
/**
* @brief Function description
* @param Params
* @retval socket status
*/
int32_t cypress_whd_net_driver(net_if_handle_t *pnetif)
{
int32_t ret;
/* init lwip library here if not already done by another network interface */
net_ip_init();
ret = net_cypress_whd_if_init(pnetif);
return ret;
}
static int32_t net_cypress_whd_if_init(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
net_if_drv_t *pdrv = NET_MALLOC(sizeof(net_if_drv_t));
if (pdrv != NULL)
{
pdrv->if_class = NET_INTERFACE_CLASS_WIFI;
pdrv->if_init = net_cypress_whd_if_init;
pdrv->if_deinit = net_cypress_whd_if_deinit;
pdrv->if_start = net_cypress_whd_if_start;
pdrv->if_stop = net_cypress_whd_if_stop;
pdrv->if_connect = net_cypress_whd_if_connect;
pdrv->if_disconnect = net_cypress_whd_if_disconnect;
pdrv->pping = icmp_ping;
pnetif->pdrv = pdrv;
pdrv->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
if (NULL == pdrv->extension.wifi)
{
NET_DBG_ERROR("can't allocate memory for wifi extension\n");
NET_FREE(pdrv);
ret = NET_ERROR_NO_MEMORY;
}
else
{
(void) memset(pdrv->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
pdrv->extension.wifi->scan = net_cypress_whd_scan;
pdrv->extension.wifi->get_scan_results = net_cypress_whd_scan_result;
if (cypress_alive_interface_count == 0)
{
/* Boot cypress module and start whd driver for very first interface */
if (WHD_SUCCESS != whd_boot(&whd_driver))
{
NET_DBG_ERROR("can't perform intialization of whd driver and module\n");
ret = NET_ERROR_MODULE_INITIALIZATION;
}
NET_DBG_PRINT("WHD init driver done\n");
(void) memset(netif2ifp, 0, sizeof(netif2ifp));
if (NET_OK == ret)
{
if (WHD_SUCCESS != whd_wifi_on(whd_driver, (whd_interface_t *) &pdrv->extension.wifi->ifp))
{
NET_DBG_PRINT("Failed when creating WIFI default interface\n");
NET_FREE(pdrv->extension.wifi);
NET_FREE(pdrv);
ret = NET_ERROR_MODULE_INITIALIZATION;
}
else
{
NET_DBG_PRINT("WHD init interface done\n");
cypress_alive_interface_count++;
ret = NET_OK;
}
}
}
else
{
whd_mac_t mac_addr = {0xA0, 0xC9, 0xA0, 0X3D, 0x43, 0x41};
if (WHD_SUCCESS != whd_add_secondary_interface(whd_driver, &mac_addr, (whd_interface_t *) &pdrv->extension.wifi->ifp))
{
NET_DBG_PRINT("Failed when creating WIFI default interface\n");
NET_FREE(pdrv->extension.wifi);
NET_FREE(pdrv);
ret = NET_ERROR_MODULE_INITIALIZATION;
}
else
{
NET_DBG_PRINT("WHD init interface done\n");
cypress_alive_interface_count++;
ret = NET_OK;
}
}
}
}
else
{
NET_DBG_ERROR("can't allocate memory for WHD driver class\n");
ret = NET_ERROR_NO_MEMORY;
}
return ret;
}
static void convert_credential(const net_wifi_credentials_t *credentials, whd_security_t *privacy, whd_ssid_t *myssid)
{
*privacy = (whd_security_t) credentials->security_mode;
strcpy((char *) myssid->value, (char *) credentials->ssid);
myssid->length = strlen((char *)myssid->value);
}
static int32_t net_cypress_whd_if_start_sta(net_if_handle_t *pnetif)
{
int32_t ret = 0;
whd_security_t privacy;
whd_ssid_t myssid;
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
convert_credential(credentials, &privacy, &myssid);
NET_DBG_PRINT("Joinning ... %s\n", myssid.value);
ret = whd_wifi_join((whd_interface_t)pnetif->pdrv->extension.wifi->ifp, (whd_ssid_t const *) &myssid, privacy,
(uint8_t const *) credentials->psk, strlen(credentials->psk));
if (ret != 0)
{
NET_DBG_ERROR("can't join %s\n", myssid.value);
ret = NET_ERROR_MODULE_INITIALIZATION;
}
else
{
NET_DBG_PRINT("Joined Access point %s\n", myssid.value);
ret = net_ip_add_if(pnetif, low_level_init, NET_ETHERNET_FLAG_DEFAULT_IF);
if (ret == NET_OK)
{
(void) strncpy(pnetif->DeviceName, "Wlan WHD murata 1LD", sizeof(pnetif->DeviceName));
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
netif_set_link_up(pnetif->netif);
}
else
{
NET_DBG_ERROR("can't add interface (netif)\n");
}
}
return ret;
}
static int32_t net_cypress_whd_if_start_ap(net_if_handle_t *pnetif)
{
int32_t ret = 0;
whd_security_t privacy;
whd_ssid_t myssid;
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
NET_DBG_PRINT("Init Access Point ... %s\n", myssid.value);
convert_credential(credentials, &privacy, &myssid);
ret = whd_wifi_init_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp, &myssid, privacy,
(uint8_t const *) credentials->psk, strlen(credentials->psk),
pnetif->pdrv->extension.wifi->access_channel);
if (ret != 0)
{
NET_DBG_ERROR("can't init access point %s\n", myssid.value);
ret = NET_ERROR_MODULE_INITIALIZATION;
}
else
{
ret = whd_wifi_start_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp);
if (ret != 0)
{
NET_DBG_ERROR("can't start access point %s\n", myssid.value);
ret = NET_ERROR_MODULE_INITIALIZATION;
}
else
{
NET_DBG_PRINT("Start Access point %s\n", myssid.value);
ret = net_ip_add_if(pnetif, low_level_init, NET_ETHERNET_FLAG_DEFAULT_IF);
if (ret == NET_OK)
{
(void) strncpy(pnetif->DeviceName, "Wlan WHD murata 1LD", sizeof(pnetif->DeviceName));
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
netif_set_link_up(pnetif->netif);
}
else
{
NET_DBG_ERROR("can't add interface (netif)\n");
}
}
}
return ret;
}
int32_t net_cypress_whd_if_start(net_if_handle_t *pnetif)
{
int32_t ret = 0;
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
{
ret = net_cypress_whd_if_start_sta(pnetif);
}
else
{
ret = net_cypress_whd_if_start_ap(pnetif);
}
return ret;
}
static int32_t net_cypress_whd_if_connect(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_ip_connect(pnetif);
if (ret != NET_OK)
{
NET_DBG_ERROR("Failed to connect\n");
ret = NET_ERROR_NO_CONNECTION;
}
return ret;
}
static int32_t net_cypress_whd_if_disconnect(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_ip_disconnect(pnetif);
if (ret == NET_OK)
{
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
}
return ret;
}
static int32_t net_cypress_whd_if_stop(net_if_handle_t *pnetif)
{
int32_t ret;
ret = net_ip_remove_if(pnetif, NULL);
if (ret == NET_OK)
{
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
}
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
{
whd_wifi_leave(pnetif->pdrv->extension.wifi->ifp);
}
else
{
whd_wifi_stop_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp);
}
return ret;
}
static int32_t net_cypress_whd_if_deinit(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
uint32_t i;
/*Switch off Wifi*/
whd_wifi_off(pnetif->pdrv->extension.wifi->ifp);
for (i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
{
if (netif2ifp[i].key == pnetif->pdrv->extension.wifi->ifp)
{
break;
}
}
if (i == NET_CYPRESS_MAX_INTERFACE)
{
WPRINT_WHD_DEBUG(("Couldn't find the interface \n"));
return ERR_VAL;
}
else
{
netif2ifp[i].key = NULL;
netif2ifp[i].value = NULL;
if (cypress_alive_interface_count == 1)
{
/*Deletes all the interface and De-init the whd, free whd_driver memory */
whd_deinit(pnetif->pdrv->extension.wifi->ifp);
whd_powerdown(&whd_driver);
}
cypress_alive_interface_count--;
NET_FREE(pnetif->pdrv->extension.wifi);
NET_FREE(pnetif->pdrv);
pnetif->pdrv = NULL;
}
return ret;
}
static err_t low_level_init(struct netif *netif)
{
err_t ret = ERR_VAL;
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
net_if_handle_t *pnetif = netif->state;
whd_interface_t ifp = pnetif->pdrv->extension.wifi->ifp;
/* to retrieve back netif from ifp */
for (int32_t i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
{
if (netif2ifp[i].key == NULL)
{
netif2ifp[i].key = ifp;
netif2ifp[i].value = netif;
ret = (err_t) ERR_OK;
break;
}
}
netif->name[0] = 'c';
netif->name[1] = 'y';
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...)
*/
netif->output = etharp_output;
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = low_level_output;
/* Set MAC hardware address length ( 6)*/
netif->hwaddr_len = (u8_t) ETHARP_HWADDR_LEN;
/* Setup the physical address of this IP instance. */
if (whd_wifi_get_mac_address(ifp, (whd_mac_t *) netif->hwaddr) != WHD_SUCCESS)
{
WPRINT_WHD_DEBUG(("Couldn't get MAC address\n"));
return ERR_VAL;
}
WPRINT_WHD_DEBUG((" MAC address %x.%x.%x.%x.%x.%x\n", netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2],
netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]));
/* Set Maximum Transfer Unit */
netif->mtu = (u16_t) WHD_PAYLOAD_MTU;
/* Set device capabilities. Don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = (u8_t)(NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET);
/* Do whatever else is needed to initialize interface. */
#if LWIP_IGMP
netif->flags |= NETIF_FLAG_IGMP;
netif_set_igmp_mac_filter(netif, lwip_igmp_mac_filter);
#endif /* LWIP_IGMP */
/* Register a handler for any address changes and when interface goes up or down*/
netif_set_status_callback(netif, net_ip_status_cb);
netif_set_link_callback(netif, net_ip_status_cb);
return ret;
}
/* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
net_if_handle_t *pnetif = netif->state;
whd_interface_t ifp = pnetif->pdrv->extension.wifi->ifp;
if (whd_wifi_is_ready_to_transceive(ifp) == WHD_SUCCESS)
{
/* Take a reference to this packet */
pbuf_ref(p);
#if 0
NET_DBG_PRINT("Transmit buffer 1 %x next=%p tot-len=%d len=%d\n", p, p->next, p->tot_len, p->len);
#endif /* for debug */
LWIP_ASSERT("No chained buffers", ((p->next == NULL) && ((p->tot_len == p->len))));
#ifdef NET_PERF
stat.whd_send_cycle -= net_get_cycle();
#endif /* NET_PERF */
whd_network_send_ethernet_data((whd_interface_t) ifp, p);
#ifdef NET_PERF
/*stat.whd_send_cycle += net_get_cycle();*/
#endif /* NET_PERF */
LINK_STATS_INC(link.xmit);
return (err_t) ERR_OK;
}
else
{
NET_DBG_PRINT("cannot transmit wifi not rdy\n");
/* Stop lint warning about packet not being freed - it is not being referenced */ /*@-mustfree@*/
return (err_t) ERR_INPROGRESS; /* Note that signalling ERR_CLSD or ERR_CONN causes loss of connectivity on a roam */
/*@+mustfree@*/
}
}
uint32_t cy_callback_tcpip = 0;
uint32_t cy_callback = 0;
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param p : the incoming ethernet packet
*/
void cy_network_process_ethernet_data(whd_interface_t interface, whd_buffer_t buff)
{
struct eth_hdr *ethernet_header;
struct netif *tmp_netif;
u8_t result;
uint16_t ethertype;
struct pbuf *buffer = (struct pbuf *) buff;
if (buffer == NULL)
{
return;
}
/* points to packet payload, which starts with an Ethernet header */
ethernet_header = (struct eth_hdr *) buffer->payload;
ethertype = lwip_htons(ethernet_header->type);
#ifdef FILTER
if (filter_ethernet_packet_callback != NULL && filter_ethertype == ethertype && filter_interface == interface)
{
filter_ethernet_packet_callback(buffer->payload, filter_userdata);
}
#endif /* FILTER */
/* Check if this is an 802.1Q VLAN tagged packet */
if (ethertype == WHD_ETHERTYPE_8021Q)
{
/* Need to remove the 4 octet VLAN Tag, by moving src and dest addresses 4 octets to the right,
* and then read the actual ethertype. The VLAN ID and priority fields are currently ignored. */
uint8_t temp_buffer[ 12 ];
memcpy(temp_buffer, buffer->payload, 12);
memcpy(((uint8_t *) buffer->payload) + 4, temp_buffer, 12);
buffer->payload = ((uint8_t *) buffer->payload) + 4;
buffer->len = (u16_t)(buffer->len - 4);
ethernet_header = (struct eth_hdr *) buffer->payload;
ethertype = lwip_htons(ethernet_header->type);
}
#ifdef DEEP_SLEEP
if (WHD_DEEP_SLEEP_IS_ENABLED() && (WHD_DEEP_SLEEP_SAVE_PACKETS_NUM != 0))
{
if (wiced_deep_sleep_save_packet(buffer, interface))
{
return;
}
}
#endif /* DEEP_SLEEP */
cy_callback++;
switch (ethertype)
{
case WHD_ETHERTYPE_IPv4:
case WHD_ETHERTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* Find the netif object matching the provided interface */
tmp_netif = NULL;
for (int32_t i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
{
if (netif2ifp[i].key == interface)
{
tmp_netif = netif2ifp[i].value;
break;
}
}
/*NET_DBG_PRINT("Recv %d for netif %x ifp %x\n",buffer->len,tmp_netif,interface);*/
if (tmp_netif == NULL)
{
NET_DBG_PRINT("This buffer is not for this interface !\n");
/* Received a packet for a network interface is not initialised Cannot do anything with packet
- just drop it. */
result = pbuf_free(buffer);
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
buffer = NULL;
return;
}
#if 0
NET_DBG_PRINT("process input packet ethertype %x size %d\n", ethertype, buffer->len);
#endif /* debug */
/* Send to packet to tcpip_thread to process */
cy_callback_tcpip++;
if (tcpip_input(buffer, tmp_netif) != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
/* Stop lint warning - packet has not been released in this case */ /*@-usereleased@*/
result = pbuf_free(buffer);
/*@+usereleased@*/
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
buffer = NULL;
}
break;
#if 0
/*FIXME , not supported todays */
case WHD_ETHERTYPE_EAPOL:
whd_eapol_receive_eapol_packet(buffer, interface);
break;
#endif /* 0 */
default:
result = pbuf_free(buffer);
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
buffer = NULL;
break;
}
}
static int32_t net_cypress_whd_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid)
{
(void) pnetif;
(void) mode;
(void) ssid;
return NET_OK;
}
static int32_t net_cypress_whd_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *scan_bss, uint8_t number)
{
int32_t ret = NET_ERROR_GENERIC;
whd_sync_scan_result_t *scan_result;
if ((NULL == scan_bss) || (0 == number))
{
return NET_ERROR_PARAMETER;
}
scan_result = (whd_sync_scan_result_t *)NET_MALLOC(sizeof(whd_sync_scan_result_t) * number);
if (NULL == scan_result)
{
return NET_ERROR_NO_MEMORY;
}
else
{
uint32_t apcount;
whd_sync_scan_result_t *scan_result_info = scan_result;
memset(scan_result, 0, sizeof(whd_sync_scan_result_t) * number);
apcount = whd_wifi_scan_synch((whd_interface_t) pnetif->pdrv->extension.wifi->ifp, scan_result, number);
for (uint32_t i = 0; i < apcount; i++)
{
memset(scan_bss, 0, sizeof(net_wifi_scan_bss_t));
memcpy(scan_bss->ssid.value, (void *) scan_result_info->SSID.value, scan_result_info->SSID.length);
scan_bss->ssid.value[scan_result_info->SSID.length] = 0;
scan_bss->ssid.length = scan_result_info->SSID.length;
scan_bss->security = scan_result_info->security;
memcpy(&scan_bss->bssid, scan_result_info->BSSID.octet, NET_WIFI_MAC_ADDRESS_SIZE);
scan_bss->rssi = (int8_t)scan_result_info->signal_strength;
scan_bss->channel = scan_result_info->channel;
memcpy(scan_bss->country, ".CN", 4); /* NOT SUPPORT for MX_WIFI */
scan_bss++;
scan_result_info++;
}
ret = apcount;
}
free((void *) scan_result);
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,715 @@
/**
******************************************************************************
* @file net_mx_wifi.c
* @author MCD Application Team
* @brief MXCHIP Wi-Fi specific BSD-like socket wrapper
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/*cstat -MISRAC2012-* */
#include "net_connect.h"
#include "net_internals.h"
/*cstat +MISRAC2012-* */
#include "mx_wifi.h"
#ifdef MX_WIFI_API_DEBUG
#define DEBUG_LOG(M, ...) printf(M, ##__VA_ARGS__);
#else
#define DEBUG_LOG(M, ...)
#endif /* MX_WIFI_API_DEBUG */
#define MXWIFI_MAX_CHANNEL_NBR 4
#define WIFI_FREE_SOCKET 0U
#define WIFI_ALLOCATED_SOCKET 1U
#define WIFI_BIND_SOCKET 2U
#define WIFI_SEND_OK 4U
#define WIFI_RECV_OK 8U
#define WIFI_CONNECTED_SOCKET 16U
#define WIFI_STARTED_CLIENT_SOCKET 32U
#define WIFI_STARTED_SERVER_SOCKET 64U
#define WIFI_CONNECTED_SOCKET_RW (WIFI_CONNECTED_SOCKET | WIFI_SEND_OK | WIFI_RECV_OK)
#define NET_ARTON(A) ((uint32_t)(((uint32_t)A[3] << 24U) |\
((uint32_t)A[2] << 16U) |\
((uint32_t)A[1] << 8U) |\
((uint32_t)A[0] << 0U)))
/* Declaration of generic class functions */
void HAL_Delay(uint32_t delay);
int32_t mx_wifi_driver(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_init(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_deinit(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_start(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_stop(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_yield(net_if_handle_t *pnetif, uint32_t timeout);
static int32_t mx_wifi_if_connect(net_if_handle_t *pnetif);
static int32_t mx_wifi_if_disconnect(net_if_handle_t *pnetif);
static int32_t mx_wifi_socket(int32_t domain, int32_t type, int32_t protocol);
static int32_t mx_wifi_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
static int32_t mx_wifi_listen(int32_t sock, int32_t backlog);
static int32_t mx_wifi_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
static int32_t mx_wifi_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
static int32_t mx_wifi_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
static int32_t mx_wifi_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
static int32_t mx_wifi_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
uint32_t tolen);
static int32_t mx_wifi_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
uint32_t *fromlen);
static int32_t mx_wifi_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
static int32_t mx_wifi_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
static int32_t mx_wifi_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
static int32_t mx_wifi_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
static int32_t mx_wifi_close(int32_t sock, bool isaclone);
static int32_t mx_wifi_shutdown(int32_t sock, int32_t mode);
static int32_t mx_wifi_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
static int32_t mx_wifi_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay,
int32_t response[]);
/* Declaration and definition of class-specific functions */
static int32_t mx_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
static int32_t mx_wifi_get_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
extern int32_t wifi_probe(void **ll_drv_context);
extern MX_WIFIObject_t *wifi_obj_get(void);
/* internal structure to mabage es_wfi socket */
typedef struct mxwifi_tls_data_s
{
char *tls_ca_certs; /**< Socket option. */
char *tls_ca_crl; /**< Socket option. */
char *tls_dev_cert; /**< Socket option. */
char *tls_dev_key; /**< Socket option. */
uint8_t *tls_dev_pwd; /**< Socket option. */
bool tls_srv_verification; /**< Socket option. */
char *tls_srv_name; /**< Socket option. */
} mxwifi_tls_data_t;
int32_t mx_wifi_driver(net_if_handle_t *pnetif)
{
return mx_wifi_if_init(pnetif);
}
int32_t mx_wifi_if_init(net_if_handle_t *pnetif)
{
int32_t ret;
net_if_drv_t *p;
void *ptmp;
ptmp = NET_MALLOC(sizeof(net_if_drv_t));
(void)memcpy(&p, &ptmp, sizeof(p));
if (p != NULL)
{
p->if_class = NET_INTERFACE_CLASS_WIFI;
p->if_init = mx_wifi_if_init;
p->if_deinit = mx_wifi_if_deinit;
p->if_start = mx_wifi_if_start;
p->if_stop = mx_wifi_if_stop;
p->if_yield = mx_wifi_if_yield;
p->if_connect = mx_wifi_if_connect;
p->if_disconnect = mx_wifi_if_disconnect;
p->psocket = mx_wifi_socket;
p->pbind = mx_wifi_bind;
p->plisten = mx_wifi_listen;
p->paccept = mx_wifi_accept;
p->pconnect = mx_wifi_connect;
p->psend = mx_wifi_send;
p->precv = mx_wifi_recv;
p->psendto = mx_wifi_sendto;
p->precvfrom = mx_wifi_recvfrom;
p->psetsockopt = mx_wifi_setsockopt;
p->pgetsockopt = mx_wifi_getsockopt;
p->pgetsockname = mx_wifi_getsockname;
p->pgetpeername = mx_wifi_getpeername;
p->pclose = mx_wifi_close;
p->pshutdown = mx_wifi_shutdown;
p->pgethostbyname = mx_wifi_gethostbyname;
p->pping = mx_wifi_ping;
p->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
if (NULL == p->extension.wifi)
{
NET_DBG_ERROR("can't allocate memory for mx_wifi_driver class\n");
NET_FREE(p);
ret = NET_ERROR_NO_MEMORY;
}
else
{
(void) memset(p->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
pnetif->dhcp_mode = true;
pnetif->pdrv = p;
p->extension.wifi->scan = mx_wifi_scan;
p->extension.wifi->get_scan_results = mx_wifi_get_scan_result;
ret = NET_OK;
}
}
else
{
NET_DBG_ERROR("can't allocate memory for mx_wifi_driver class\n");
ret = NET_ERROR_NO_MEMORY;
}
return ret;
}
static int32_t mx_wifi_if_deinit(net_if_handle_t *pnetif)
{
NET_FREE(pnetif->pdrv->extension.wifi);
pnetif->pdrv->extension.wifi = NULL;
NET_FREE(pnetif->pdrv);
pnetif->pdrv = NULL;
return NET_OK;
}
static int32_t mx_wifi_if_start(net_if_handle_t *pnetif)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj;
if (wifi_probe(&pnetif->pdrv->context) == NET_OK)
{
DEBUG_LOG("MX_WIFI IO [OK]\r\n");
pMxWifiObj = wifi_obj_get();
/* wifi module hardware reboot */
DEBUG_LOG("MX_WIFI REBOOT(HW) ...\r\n");
if (MX_WIFI_STATUS_OK != MX_WIFI_HardResetModule(pMxWifiObj))
{
ret = NET_ERROR_DEVICE_ERROR;
}
else
{
#ifdef NET_USE_RTOS
(void)osDelay(500);
#else
HAL_Delay(500);
#endif /* NET_USE_RTOS */
/* Init the WiFi module */
if (MX_WIFI_STATUS_OK != MX_WIFI_Init(pMxWifiObj))
{
ret = NET_ERROR_INTERFACE_FAILURE;
}
else
{
DEBUG_LOG("MX_WIFI_Init [OK]\r\n");
/* Retrieve the WiFi module information */
(void)strncpy(pnetif->DeviceName, (char_t *)pMxWifiObj->SysInfo.Product_Name, NET_DEVICE_NAME_LEN);
(void)strncpy(pnetif->DeviceID, (char_t *)pMxWifiObj->SysInfo.Product_ID, NET_DEVICE_ID_LEN);
(void)strncpy(pnetif->DeviceVer, (char_t *)pMxWifiObj->SysInfo.FW_Rev, NET_DEVICE_VER_LEN);
(void)MX_WIFI_GetMACAddress(pMxWifiObj, pnetif->macaddr.mac);
(void)net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
ret = NET_OK;
}
}
}
else
{
ret = NET_ERROR_DEVICE_ERROR;
}
return ret;
}
static int32_t mx_wifi_if_stop(net_if_handle_t *pnetif)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
if (MX_WIFI_STATUS_OK != MX_WIFI_DeInit(pMxWifiObj))
{
ret = NET_ERROR_GENERIC;
}
else
{
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
ret = NET_OK;
}
return ret;
}
static int32_t mx_wifi_if_yield(net_if_handle_t *pnetif, uint32_t timeout)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)pnetif;
ret = MX_WIFI_IO_YIELD(pMxWifiObj, timeout);
return ret;
}
static void mx_wifi_status_changed(uint8_t cate, uint8_t status, void *arg)
{
net_if_handle_t *pnetif;
uint8_t addr[4];
net_state_t net_state;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&pnetif, &arg, sizeof(pnetif));
if ((uint8_t)MC_STATION == cate)
{
switch (status)
{
case MC_STA_DOWN:
DEBUG_LOG("MC_STA_DOWN\r\n");
(void) net_if_getState(pnetif, &net_state);
if (NET_STATE_CONNECTED == net_state)
{
(void)net_state_manage_event(pnetif, NET_EVENT_LINK_DOWN);
}
else
{
(void)net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
}
break;
case MC_STA_UP:
DEBUG_LOG("MC_STA_UP\r\n");
(void)net_state_manage_event(pnetif, NET_EVENT_LINK_UP);
break;
case MC_STA_GOT_IP:
DEBUG_LOG("MC_STA_GOT_IP\r\n");
(void) memcpy(addr, pMxWifiObj->NetSettings.IP_Addr, 4);
pnetif->ipaddr.addr = NET_ARTON(pMxWifiObj->NetSettings.IP_Addr);
(void) memcpy(addr, pMxWifiObj->NetSettings.IP_Mask, 4);
pnetif->netmask.addr = NET_ARTON(pMxWifiObj->NetSettings.IP_Mask);
(void) memcpy(addr, pMxWifiObj->NetSettings.Gateway_Addr, 4);
pnetif->gateway.addr = NET_ARTON(pMxWifiObj->NetSettings.Gateway_Addr);
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
break;
default:
break;
}
}
else if ((uint8_t)MC_SOFTAP == cate)
{
switch (status)
{
case MC_AP_DOWN:
DEBUG_LOG("MC_AP_DOWN\r\n");
net_if_notify(pnetif, NET_EVENT_STATE_CHANGE, (uint32_t) NET_STATE_CONNECTION_LOST, NULL);
break;
case MC_AP_UP:
DEBUG_LOG("MC_AP_UP\r\n");
pnetif->ipaddr.addr = pnetif->static_ipaddr.addr;
pnetif->gateway.addr = pnetif->static_gateway.addr;
pnetif->netmask.addr = pnetif->static_netmask.addr;
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
break;
default:
break;
}
}
else
{
/* nothing */
}
}
static MX_WIFI_SecurityType_t convert(int security_mode)
{
#if 0
MX_WIFI_SEC_NONE, /**< Open system. */
MX_WIFI_SEC_WEP, /**< Wired Equivalent Privacy. WEP security. */
MX_WIFI_SEC_WPA_TKIP, /**< WPA /w TKIP */
MX_WIFI_SEC_WPA_AES, /**< WPA /w AES */
MX_WIFI_SEC_WPA2_TKIP, /**< WPA2 /w TKIP */
MX_WIFI_SEC_WPA2_AES, /**< WPA2 /w AES */
MX_WIFI_SEC_WPA2_MIXED, /**< WPA2 /w AES or TKIP */
#endif
return MX_WIFI_SEC_AUTO;
}
static int32_t mx_wifi_if_connect_sta(net_if_handle_t *pnetif)
{
int32_t ret;
MX_WIFI_SecurityType_t secure_type;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
if (false == pnetif->dhcp_mode)
{
pMxWifiObj->NetSettings.DHCP_IsEnabled = 0;
(void)memcpy(pMxWifiObj->NetSettings.IP_Addr, &(pnetif->ipaddr), 4);
(void)memcpy(pMxWifiObj->NetSettings.IP_Mask, &(pnetif->netmask), 4);
(void)memcpy(pMxWifiObj->NetSettings.Gateway_Addr, &(pnetif->gateway), 4);
}
else
{
pMxWifiObj->NetSettings.DHCP_IsEnabled = 1;
}
(void)MX_WIFI_RegisterStatusCallback(pMxWifiObj, mx_wifi_status_changed, pnetif);
secure_type = convert(credentials->security_mode);
ret = MX_WIFI_Connect(pMxWifiObj, credentials->ssid, credentials->psk, secure_type);
return ret;
}
#define BYTEN(A,n) ((A)>>(8u*(n))) & 0xffu
#define BYTE3(A) BYTEN((A),3u)
#define BYTE2(A) BYTEN((A),2u)
#define BYTE1(A) BYTEN((A),1u)
#define BYTE0(A) BYTEN((A),0u)
#define ADDR(a) BYTE0(a),BYTE1(a),BYTE2(a),BYTE3(a)
static int32_t mx_wifi_if_connect_ap(net_if_handle_t *pnetif)
{
int32_t ret = NET_ERROR_GENERIC;
MX_WIFI_APSettings_t ap_cfg;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
(void) memset(&ap_cfg, 0, sizeof(ap_cfg));
(void) strcpy(ap_cfg.SSID, credentials->ssid);
(void) strcpy(ap_cfg.pswd, credentials->psk);
ap_cfg.channel = pnetif->pdrv->extension.wifi->access_channel;
(void) sprintf(ap_cfg.ip.localip, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_ipaddr.addr));
(void) sprintf(ap_cfg.ip.netmask, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_gateway.addr));
(void) sprintf(ap_cfg.ip.gateway, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_netmask.addr));
(void) sprintf(ap_cfg.ip.dnserver, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_dnserver.addr));
(void) MX_WIFI_RegisterStatusCallback(pMxWifiObj, mx_wifi_status_changed, pnetif);
if (MX_WIFI_STATUS_OK == MX_WIFI_StartAP(pMxWifiObj, &ap_cfg))
{
ret = NET_OK;
}
return ret;
}
static int32_t mx_wifi_if_disconnect(net_if_handle_t *pnetif)
{
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
{
(void)MX_WIFI_Disconnect(pMxWifiObj);
}
else
{
(void) MX_WIFI_StopAP(pMxWifiObj);
}
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
return NET_OK;
}
static int32_t mx_wifi_if_connect(net_if_handle_t *pnetif)
{
int32_t ret;
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
{
ret = mx_wifi_if_connect_sta(pnetif);
}
else
{
ret = mx_wifi_if_connect_ap(pnetif);
}
return ret;
}
static int32_t mx_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char_t *ssid)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
uint32_t len = 0u;
(void) pnetif;
if (ssid != NULL)
{
len = strlen(ssid);
}
ret = MX_WIFI_Scan(pMxWifiObj, (uint8_t)mode, ssid, (int32_t) len);
return ret;
}
static int32_t mx_wifi_get_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *scan_bss_array,
uint8_t scan_bss_array_size)
{
int32_t ret;
uint8_t number = scan_bss_array_size;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
mc_wifi_ap_info_t *ap_list_head;
net_wifi_scan_results_t *scan_bss = scan_bss_array;
(void)pnetif;
static uint32_t mxsec[] =
{
NET_WIFI_SM_OPEN,
NET_WIFI_SM_WEP_PSK, /**< Wired Equivalent Privacy. WEP security. */
NET_WIFI_SM_WPA_TKIP_PSK, /**< WPA /w TKIP */
NET_WIFI_SM_WPA_AES_PSK, /**< WPA /w AES */
NET_WIFI_SM_WPA2_TKIP_PSK, /**< WPA2 /w TKIP */
NET_WIFI_SM_WPA2_AES_PSK, /**< WPA2 /w AES */
NET_WIFI_SM_WPA2_MIXED_PSK, /**< WPA2 /w AES or TKIP */
};
if ((NULL == scan_bss_array) || (0u == number))
{
ret = NET_ERROR_PARAMETER;
}
else
{
/* create buff for mc_wifi results */
void *ptmp = NET_MALLOC(sizeof(mc_wifi_ap_info_t) * number);
(void) memcpy(&ap_list_head, &ptmp, sizeof(ap_list_head));
if (NULL == ap_list_head)
{
ret = NET_ERROR_NO_MEMORY;
}
else
{
mc_wifi_ap_info_t *ap_info = ap_list_head;
(void) memset(ap_list_head, 0, sizeof(mc_wifi_ap_info_t) * number);
/* get real mc_wifi scan results data */
number = (uint8_t) MX_WIFI_Get_scan_result(pMxWifiObj, (uint8_t *) ap_info, number);
for (uint32_t i = 0U; i < number; i++)
{
(void) memset(scan_bss, 0, sizeof(net_wifi_scan_bss_t));
(void) memcpy(scan_bss->ssid.value, ap_info->ssid, NET_WIFI_MAX_SSID_SIZE);
scan_bss->ssid.length = (uint8_t) strlen(ap_info->ssid);
scan_bss->security = mxsec[ap_info->security];
(void) memcpy(&scan_bss->bssid, ap_info->bssid, NET_WIFI_MAC_ADDRESS_SIZE);
scan_bss->rssi = (int8_t)ap_info->rssi;
scan_bss->channel = ap_info->channel;
(void) memcpy(scan_bss->country, ".CN", 4); /* NOT SUPPORT for MX_WIFI */
scan_bss++;
ap_info++;
}
ret = (int32_t) number;
NET_FREE((void *) ap_list_head);
}
}
return ret;
}
static int32_t mx_wifi_socket(int32_t domain, int32_t type, int32_t protocol)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_create(pMxWifiObj, domain, type, protocol);
return ret;
}
static int32_t mx_wifi_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_setsockopt(pMxWifiObj, sock, level, optname, optvalue, (int32_t)optlen);
return ret;
}
static int32_t mx_wifi_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_getsockopt(pMxWifiObj, sock, level, optname, optvalue, optlen);
return ret;
}
static int32_t mx_wifi_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
ret = MX_WIFI_Socket_bind(pMxWifiObj, sock, &mx_addr, (int32_t)addrlen);
return ret;
}
static int32_t mx_wifi_listen(int32_t sock, int32_t backlog)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_listen(pMxWifiObj, sock, backlog);
return ret;
}
static int32_t mx_wifi_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
ret = MX_WIFI_Socket_accept(pMxWifiObj, sock, &mx_addr, addrlen);
return ret;
}
static int32_t mx_wifi_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
ret = MX_WIFI_Socket_connect(pMxWifiObj, sock, &mx_addr, (int32_t)addrlen);
return ret;
}
static int32_t mx_wifi_shutdown(int32_t sock, int32_t mode)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_shutdown(pMxWifiObj, sock, mode);
return ret;
}
static int32_t mx_wifi_close(int32_t sock, bool isaclone)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)isaclone;
ret = MX_WIFI_Socket_close(pMxWifiObj, sock);
return ret;
}
static int32_t mx_wifi_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_send(pMxWifiObj, sock, buf, len, flags);
return ret;
}
static int32_t mx_wifi_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
ret = MX_WIFI_Socket_recv(pMxWifiObj, sock, buf, len, flags);
return ret;
}
static int32_t mx_wifi_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
uint32_t tolen)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&mx_addr, to, sizeof(mx_addr));
ret = MX_WIFI_Socket_sendto(pMxWifiObj, sock, buf, len, flags, &mx_addr, (int32_t)tolen);
return ret;
}
static int32_t mx_wifi_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
uint32_t *fromlen)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)memcpy(&mx_addr, from, sizeof(mx_addr));
ret = MX_WIFI_Socket_recvfrom(pMxWifiObj, sock, buf, len, flags, &mx_addr, fromlen);
return ret;
}
static int32_t mx_wifi_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name)
{
int32_t ret;
struct sockaddr mx_addr;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
(void)pnetif;
ret = MX_WIFI_Socket_gethostbyname(pMxWifiObj, &mx_addr, (char_t *)name);
(void)memcpy(addr, &mx_addr, sizeof(mx_addr));
return ret;
}
int32_t mx_wifi_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t response[])
{
int32_t ret;
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
net_sockaddr_in_t addr_in;
net_ip_addr_t ip_addr;
(void)pnetif;
(void)memcpy(&addr_in, addr, sizeof(addr_in));
ip_addr.addr = addr_in.sin_addr.s_addr;
ret = MX_WIFI_Socket_ping(pMxWifiObj, (char_t *)net_ntoa(&ip_addr), count, delay, response);
return ret;
}
static int32_t mx_wifi_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
{
DEBUG_LOG("mx_wifi_getsockname UNSUPPORTED!");
(void)sock;
(void)name;
(void)namelen;
return NET_ERROR_UNSUPPORTED;
}
static int32_t mx_wifi_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
{
DEBUG_LOG("mx_wifi_getpeername UNSUPPORTED!");
(void)sock;
(void)name;
(void)namelen;
return NET_ERROR_UNSUPPORTED;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,556 @@
/**
******************************************************************************
* @file net_st_wifi.c
* @author MCD Application Team
* @brief ST Wi-Fi specific BSD-like socket wrapper
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#include "net_buffers.h"
#include "net_wifi.h"
#include "net_ip_lwip.h"
#include "wifi.h"
#define MAX_MTU 1500
/* Wi-Fi Driver */
extern wifi_driver_t stw_driver;
wifi_driver_t *wifi_driver = &stw_driver;
int32_t st_wifi_driver(net_if_handle_t *pnetif);
/* STM32 Network library Framework */
static int32_t st_wifi_if_init(net_if_handle_t *pnetif);
static int32_t st_wifi_if_deinit(net_if_handle_t *pnetif);
static int32_t st_wifi_if_start(net_if_handle_t *pnetif);
static int32_t st_wifi_if_stop(net_if_handle_t *pnetif);
static int32_t st_wifi_if_connect(net_if_handle_t *pnetif);
static int32_t st_wifi_if_disconnect(net_if_handle_t *pnetif);
static int32_t st_wifi_if_powersave_enable(net_if_handle_t *pnetif);
static int32_t st_wifi_if_powersave_disable(net_if_handle_t *pnetif);
/*static int32_t st_wifi_if_sleep(net_if_handle_t * pnetif); */
/*static int32_t st_wifi_if_wakeup(net_if_handle_t * pnetif); */
/* Class extension */
static int32_t st_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
static int32_t st_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
static int32_t st_wifi_get_system_info(net_wifi_system_info_t info, void *data);
static int32_t st_wifi_set_param(net_wifi_param_t info, void *data);
int32_t st_wifi_event_callback(void *context, wifi_event_t event, void *data);
static err_t net_wifi_if_init(struct netif *netif);
static int32_t st_wifi_transmit(struct netif *netif, net_buf_t *net_buf);
/*******************************************************************************
Wi-Fi Driver
*******************************************************************************/
int32_t st_wifi_driver(net_if_handle_t *pnetif)
{
net_ip_init();
return st_wifi_if_init(pnetif);
}
/*******************************************************************************
STM32 Network library Framework
*******************************************************************************/
/* Init */
int32_t st_wifi_if_init(net_if_handle_t *pnetif)
{
int32_t ret;
net_if_drv_t *p = NET_MALLOC(sizeof(net_if_drv_t));
if (p)
{
p->if_class = NET_INTERFACE_CLASS_WIFI;
p->if_init = st_wifi_if_init;
p->if_deinit = st_wifi_if_deinit;
p->if_start = st_wifi_if_start;
p->if_stop = st_wifi_if_stop;
p->if_connect = st_wifi_if_connect;
p->if_disconnect = st_wifi_if_disconnect;
p->if_powersave_enable = st_wifi_if_powersave_enable;
p->if_powersave_disable = st_wifi_if_powersave_disable;
p->pping = icmp_ping;
p->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
if (NULL == p->extension.wifi)
{
NET_DBG_ERROR("can't allocate memory for st_wifi_driver class\n");
NET_FREE(p);
ret = NET_ERROR_NO_MEMORY;
}
else
{
pnetif->pdrv = p;
(void) memset(p->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
p->extension.wifi->scan = st_wifi_scan;
p->extension.wifi->get_scan_results = st_wifi_get_scan_results;
p->extension.wifi->get_system_info = st_wifi_get_system_info;
p->extension.wifi->set_param = st_wifi_set_param;
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
ret = NET_OK;
}
}
else
{
NET_DBG_ERROR("can't allocate memory for st_wifi_driver class\n");
ret = NET_ERROR_NO_MEMORY;
}
if (wifi_probe(&pnetif->pdrv->context) == NET_OK)
{
if (wifi_init(wifi_driver, st_wifi_event_callback, NULL, pnetif) != WIFI_STATUS_OK)
{
ret = NET_ERROR_INTERFACE_FAILURE;
}
}
else
{
ret = NET_ERROR_DEVICE_ERROR;
}
return ret;
}
/* Deinit */
int32_t st_wifi_if_deinit(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
if (wifi_deinit(wifi_driver) != WIFI_STATUS_OK)
{
ret = NET_ERROR_INTERFACE_FAILURE;
}
else
{
ret = NET_OK;
}
NET_FREE(pnetif->pdrv->extension.wifi);
pnetif->pdrv->extension.wifi = NULL;
NET_FREE(pnetif->pdrv);
pnetif->pdrv = NULL;
return ret;
}
/* Start */
int32_t st_wifi_if_start(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
net_wifi_powersave_t wifi_powersave =
{
WIFI_POWERSAVE_LIGHT_SLEEP
};
if (wifi_start() != WIFI_STATUS_OK)
{
ret = NET_ERROR_INTERFACE_FAILURE;
}
else
{
/* STA mode */
if (wifi_obj->mode == WIFI_MODE_STA)
{
/* Retrieve Wi-Fi device information */
char device_name[NET_DEVICE_NAME_LEN];
wifi_get_system_info(WIFI_SYSINFO_DEVICE_NAME, (void *)device_name);
strncpy(pnetif->DeviceName, device_name, NET_DEVICE_NAME_LEN);
wifi_get_system_info(WIFI_SYSINFO_WLAN_MAC, pnetif->macaddr.mac);
/* Set default values */
pnetif->pdrv->extension.wifi->powersave = &wifi_powersave;
}
/* AP mode */
if (wifi_obj->mode == WIFI_MODE_AP)
{
#if 0
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
wifi_privacy_t privacy = WIFI_PRIVACY_NONE;
if (credentials->security_mode & NET_WPA_SECURITY)
{
privacy = WIFI_PRIVACY_WPA;
}
if (credentials->security_mode & NET_WPA2_SECURITY)
{
privacy = WIFI_PRIVACY_WPA;
}
#endif /* FIXME */
}
/* Add IP interface */
ret = net_ip_add_if(pnetif, net_wifi_if_init, NET_ETHERNET_FLAG_DEFAULT_IF);
if (ret == NET_OK)
{
/*Forcing a UP at that stage , would expect msg from WIFI to trigger it
netif_set_link_up(pnetif->netif); */
if (wifi_obj->mode == WIFI_MODE_STA)
{
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
}
}
}
return ret;
}
/* Stop */
int32_t st_wifi_if_stop(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
if (wifi_stop() != WIFI_STATUS_OK)
{
ret = NET_ERROR_INTERFACE_FAILURE;
}
if (ret == NET_OK)
{
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
}
return ret;
}
/* Connect */
static int32_t st_wifi_if_connect(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
wifi_privacy_t privacy = WIFI_PRIVACY_NONE;
if (credentials->security_mode & NET_WPA_SECURITY)
{
privacy = WIFI_PRIVACY_WPA;
}
if (credentials->security_mode & NET_WPA2_SECURITY)
{
privacy = WIFI_PRIVACY_WPA;
}
if (wifi_connect((char *)credentials->ssid, (char *)credentials->psk, privacy, 0) != WIFI_STATUS_OK)
{
ret = NET_ERROR_AUTH_FAILURE;
}
else
{
ret = net_ip_connect(pnetif);
}
return ret;
}
/* Disconnect */
static int32_t st_wifi_if_disconnect(net_if_handle_t *pnetif)
{
int32_t ret = NET_ERROR_FRAMEWORK;
if (wifi_disconnect() != WIFI_STATUS_OK)
{
ret = NET_ERROR_FRAMEWORK;
}
else
{
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
ret = NET_OK;
}
return ret;
}
/* Power-save */
static int32_t st_wifi_if_powersave_enable(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
wifi_power_mode(*(pnetif->pdrv->extension.wifi->powersave));
return ret;
}
static int32_t st_wifi_if_powersave_disable(net_if_handle_t *pnetif)
{
int32_t ret = NET_OK;
wifi_power_mode(WIFI_POWER_MODE_ACTIVE);
return ret;
}
/*******************************************************************************
Class extension
*******************************************************************************/
/* Scan */
static int32_t st_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid)
{
int32_t ret = NET_ERROR_FRAMEWORK;
(void) ssid;
wifi_scan_t params;
switch (mode)
{
case NET_WIFI_SCAN_PASSIVE:
params.mode = WIFI_SCAN_MODE_PASSIVE;
break;
case NET_WIFI_SCAN_ACTIVE:
params.mode = WIFI_SCAN_MODE_ACTIVE;
break;
case NET_WIFI_SCAN_AUTO:
params.mode = WIFI_SCAN_MODE_AUTO;
break;
default:
params.mode = WIFI_SCAN_MODE_AUTO;
}
params.ssid.length = 0;
params.channels = 0;
if (wifi_scan(params) != WIFI_STATUS_OK)
{
ret = NET_ERROR_GENERIC;
}
else
{
ret = NET_OK;
}
return ret;
}
/* Get scan results */
static int32_t st_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number)
{
int32_t ret = NET_ERROR_FRAMEWORK;
uint8_t nb;
wifi_get_system_info(WIFI_SYSINFO_LAST_SCAN_RESULTS_NUMBER, (void *)&nb);
if (nb > number)
{
nb = number;
}
wifi_scan_results_t res;
res.number = nb;
res.bss = NET_MALLOC(number * sizeof(wifi_scan_bss_t));
if (wifi_get_scan_results(&res, nb) == WIFI_STATUS_OK)
{
for (uint8_t i = 0; i < nb; i++)
{
results->ssid.length = res.bss[i].ssid.length;
memcpy(results->ssid.value, res.bss[i].ssid.value, res.bss[i].ssid.length);
memcpy(results->bssid, res.bss[i].bssid, sizeof(wifi_mac_t));
results->channel = res.bss[i].channel;
memcpy(results->country, res.bss[i].country, 3);
results->rssi = res.bss[i].rssi;
results++;
}
ret = nb;
}
else
{
ret = NET_ERROR_GENERIC;
}
NET_FREE((void *)(res.bss));
return ret;
}
/* Get system info */
static int32_t st_wifi_get_system_info(net_wifi_system_info_t info, void *data)
{
int32_t ret = NET_OK;
wifi_system_info_t wifi_info;
switch (info)
{
case NET_WIFI_SCAN_RESULTS_NUMBER:
wifi_info = WIFI_SYSINFO_LAST_SCAN_RESULTS_NUMBER;
break;
default:
return NET_ERROR_PARAMETER;
break;
}
if (wifi_get_system_info(wifi_info, data) != WIFI_STATUS_OK)
{
ret = NET_ERROR_PARAMETER;
}
else
{
ret = NET_OK;
}
return ret;
}
/* Set param */
static int32_t st_wifi_set_param(net_wifi_param_t param, void *data)
{
int32_t ret = NET_OK;
wifi_params_t wifi_param;
void *wifi_data;
switch (param)
{
case NET_WIFI_MODE:
{
wifi_param = WIFI_MODE;
wifi_data = wifi_os_malloc(1);
switch (*(uint8_t *)data)
{
case NET_WIFI_MODE_STA:
*(uint8_t *)wifi_data = WIFI_MODE_STA;
break;
case NET_WIFI_MODE_AP:
*(uint8_t *)wifi_data = WIFI_MODE_AP;
break;
default:
return NET_ERROR_PARAMETER;
break;
}
break;
}
default:
return NET_ERROR_PARAMETER;
break;
}
if (wifi_set_param(wifi_param, wifi_data) != WIFI_STATUS_OK)
{
ret = NET_ERROR_PARAMETER;
}
else
{
ret = NET_OK;
}
wifi_os_free(wifi_data);
return ret;
}
/* Event callback */
int32_t st_wifi_event_callback(void *context, wifi_event_t event, void *data)
{
net_if_handle_t *pnetif = context;
switch (event)
{
case WIFI_EVENT_LINK_DOWN:
if (wifi_obj->mode == WIFI_MODE_STA)
{
netif_set_link_down(pnetif->netif);
}
break;
case WIFI_EVENT_LINK_UP:
if (wifi_obj->mode == WIFI_MODE_STA)
{
netif_set_link_up(pnetif->netif);
}
if (wifi_obj->mode == WIFI_MODE_AP)
{
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
}
break;
case WIFI_EVENT_SCAN_COMPLETE:
net_if_notify(pnetif, NET_EVENT_WIFI, NET_WIFI_SCAN_RESULTS_READY, (void *)data);
break;
case WIFI_EVENT_POWER_MODE_COMPLETE:
net_if_notify(pnetif, NET_EVENT, NET_EVENT_POWERSAVE_ENABLED, (void *)data);
break;
case WIFI_EVENT_RX_DATA:
{
wifi_rx_data_t *eth_frame = (wifi_rx_data_t *)data;
net_buf_t *buf = NET_BUF_ALLOC(eth_frame->len + sizeof(wifi_eth_t));
if (buf == NULL)
{
wifi_os_delay(1);
}
wifi_eth_receive((uint8_t *)(buf->payload), data);
tcpip_input(buf, pnetif->netif);
break;
}
default:
break;
}
return 0;
}
static err_t net_wifi_if_init(struct netif *netif)
{
err_t ret = ERR_OK;
char *hostname = NET_MALLOC(sizeof(char) * ((uint16_t) NET_IP_HOSTNAME_MAX_LEN + 1U));
if (hostname == NULL)
{
return (err_t) ERR_MEM;
}
(void) snprintf(hostname, NET_IP_HOSTNAME_MAX_LEN + 1, "generic eth if #%d", netif->num);
netif->hostname = hostname;
netif->name[0] = 's';
netif->name[1] = 't';
netif->hwaddr_len = 6;
netif->mtu = MAX_MTU;
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
netif->output = etharp_output;
wifi_get_system_info(WIFI_SYSINFO_WLAN_MAC, netif->hwaddr);
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
/* set call back , here to not loose first linkup when if_init is performed */
netif_set_status_callback(netif, net_ip_status_cb);
netif_set_link_callback(netif, net_ip_status_cb);
/* output to the device */
netif->linkoutput = (netif_linkoutput_fn)st_wifi_transmit;
return ret;
}
/*******************************************************************************
TCP/IP Library
*******************************************************************************/
/* Transmit */
static int32_t st_wifi_transmit(struct netif *netif, net_buf_t *net_buf)
{
int32_t ret = NET_OK;
if (wifi_eth_transmit((uint8_t *)(net_buf->payload), (uint16_t)(net_buf->len)) != WIFI_STATUS_OK)
{
ret = NET_ERROR_DATA;
}
return ret;
}
@@ -0,0 +1,530 @@
/**
******************************************************************************
* @file net_ip_lwip.c
* @author MCD Application Team
* @brief lwIP network interface functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#include "net_ip_lwip.h"
#include "net_buffers.h"
#define YES (u8_t)1
#define NO (u8_t)0
static void link_socket_to_lwip(net_if_drv_t *drv);
#ifndef NET_BYPASS_NET_SOCKET
static int32_t net_lwip_socket(int32_t domain, int32_t type, int32_t protocol);
static int32_t net_lwip_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
static int32_t net_lwip_listen(int32_t sock, int32_t backlog);
static int32_t net_lwip_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
static int32_t net_lwip_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
static int32_t net_lwip_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
static int32_t net_lwip_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
static int32_t net_lwip_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
uint32_t tolen);
static int32_t net_lwip_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
uint32_t *fromlen);
static int32_t net_lwip_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
static int32_t net_lwip_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
static int32_t net_lwip_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
static int32_t net_lwip_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
static int32_t net_lwip_close(int32_t sock, bool clone);
static int32_t net_lwip_shutdown(int32_t sock, int32_t mode);
#endif /* NET_BYPASS_NET_SOCKET */
static int32_t net_lwip_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
#define NETIF_IS_LINK_UP(netif) (((netif)->flags & NETIF_FLAG_LINK_UP)!=0U)
/* Manage init of LWIP libraryu as a singleton */
void net_ip_init(void)
{
static bool tcpip_init_done = 0;
if (false == tcpip_init_done)
{
tcpip_init(NULL, NULL);
tcpip_init_done = true;
}
}
/* Add of a new network interface */
int32_t net_ip_add_if(net_if_handle_t *pnetif, err_t (*if_init)(struct netif *netif), uint32_t flag)
{
int32_t ret;
struct netif *netif;
/*cstat -MISRAC2012-Rule-11.5 Malloc*/
netif = (struct netif *)(void *) NET_MALLOC(sizeof(struct netif));
/*cstat +MISRAC2012-Rule-11.5 */
if (NULL != netif)
{
pnetif->netif = netif;
(void) memset(netif, 0x00, sizeof(struct netif));
netif = netif_add(netif, NULL, NULL, NULL, pnetif, if_init, tcpip_input);
if ((flag & NET_IP_FLAG_DEFAULT_INTERFACE) != 0U)
{
netif_set_default(netif);
}
/* Get MAC hardware address from netif */
(void) memcpy(pnetif->macaddr.mac, netif->hwaddr, sizeof(netif->hwaddr));
/* link current network interface to LWIP library */
link_socket_to_lwip(pnetif->pdrv);
#if 0 /*FIXME*/
#if LWIP_IPV6
/* Set the IPv6 linklocal address using our MAC */
NET_DBG_PRINT("Setting IPv6 link-local address\n");
netif_create_ip6_linklocal_address(netif, 1);
IP_HANDLE(interface).ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6 */
#endif /* FIXME */
ret = NET_OK;
}
else
{
ret = NET_ERROR_GENERIC;
}
return ret;
}
static ip4_addr_t const *ip4_addr(net_ip_addr_t *ipaddr)
{
/*cstat -MISRAC2012-Rule-11.3 Const casting*/
return (ip4_addr_t const *) ipaddr;
/*cstat +MISRAC2012-Rule-11.3*/
}
/* CONNECTION */
int32_t net_ip_connect(net_if_handle_t *pnetif)
{
int32_t ret;
struct netif *netif = (struct netif *)pnetif->netif;
if (NULL != netif)
{
if (!pnetif->dhcp_mode && (NET_IP_ADDR_ISANY_VAL(pnetif->static_ipaddr)))
{
ret = NET_ERROR_PARAMETER;
}
else
{
netif_set_up(netif);
if (pnetif->dhcp_mode)
{
(void) dhcp_start(netif);
}
else
{
netif_set_addr(netif, ip4_addr(&pnetif->static_ipaddr), ip4_addr(&pnetif->static_netmask),
ip4_addr(&pnetif->static_gateway));
dhcp_inform(netif);
}
ret = NET_OK;
}
}
else
{
ret = NET_ERROR_PARAMETER;
}
return ret;
}
int32_t net_ip_disconnect(net_if_handle_t *pnetif)
{
struct netif *netif = pnetif->netif;
/*cstat -MISRAC2012-Rule-11.5 LWIP function*/
if (netif_dhcp_data(netif) != NULL)
/*cstat +MISRAC2012-Rule-11.5 */
{
(void) dhcp_release(netif);
dhcp_stop(netif);
dhcp_cleanup(netif);
}
else
{
netif_set_addr(netif, NULL, NULL, NULL);
pnetif->dhcp_inform_flag = false;
dhcp_inform(netif);
}
return (int32_t) ERR_OK;
}
int32_t net_ip_remove_if(net_if_handle_t *pnetif, err_t (*if_deinit)(struct netif *netif))
{
if (pnetif != NULL)
{
struct netif *netif = pnetif->netif;
if (netif != NULL)
{
netif_set_down(netif);
netif_set_link_down(netif);
netif_remove(netif);
if (NULL != if_deinit)
{
(*if_deinit)(netif);
}
NET_FREE(netif);
pnetif->netif = NULL;
}
}
return NET_OK;
}
void net_ip_status_cb(struct netif *netif)
{
net_ip_addr_t ipaddr_zero;
/*cstat -MISRAC2012-Rule-11.5 casting state pointer by defintion from LWIP */
net_if_handle_t *pnetif = (net_if_handle_t *) netif->state;
/*cstat +MISRAC2012-Rule-11.5 */
NET_ZERO(ipaddr_zero);
if (pnetif->dhcp_enabled)
{
/* lost connection */
if (NET_DIFF(netif->ip_addr, ipaddr_zero) && (!NETIF_IS_LINK_UP(netif)) && pnetif->dhcp_release_on_link_lost)
{
NET_DBG_PRINT("Callback lost connection so release connection\n");
(void) dhcp_release(netif);
(void) dhcp_start(netif);
}
/* up connection , so need to inform other at first time */
if (pnetif->dhcp_inform_flag && NETIF_IS_LINK_UP(netif))
{
NET_DBG_PRINT("Callback get connection\n");
dhcp_inform(netif);
pnetif->dhcp_inform_flag = false;
}
}
if (!NET_IP_ADDR_CMP(&pnetif->ipaddr, &netif->ip_addr))
{
NET_IP_ADDR_COPY(pnetif->ipaddr, netif->ip_addr);
NET_IP_ADDR_COPY(pnetif->netmask, netif->netmask);
NET_IP_ADDR_COPY(pnetif->gateway, netif->gw);
/* FIXME for IPV6 support */
if (!NET_IP_ADDR_ISANY_VAL(pnetif->ipaddr))
{
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
}
}
if (NETIF_IS_LINK_UP(netif))
{
(void) net_state_manage_event(pnetif, NET_EVENT_LINK_UP);
}
else
{
(void) net_state_manage_event(pnetif, NET_EVENT_LINK_DOWN);
}
}
/* UTILITIES */
void link_socket_to_lwip(net_if_drv_t *drv)
{
#ifndef NET_BYPASS_NET_SOCKET
drv->psocket = net_lwip_socket;
drv->pbind = net_lwip_bind;
drv->plisten = net_lwip_listen;
drv->paccept = net_lwip_accept;
drv->pconnect = net_lwip_connect;
drv->psend = net_lwip_send;
drv->precv = net_lwip_recv;
drv->psendto = net_lwip_sendto;
drv->precvfrom = net_lwip_recvfrom;
drv->psetsockopt = net_lwip_setsockopt;
drv->pgetsockopt = net_lwip_getsockopt;
drv->pgetsockname = net_lwip_getsockname;
drv->pgetpeername = net_lwip_getpeername;
drv->pclose = net_lwip_close;
drv->pshutdown = net_lwip_shutdown;
#endif /* NET_BYPASS_NET_SOCKET */
/* Service */
drv->pgethostbyname = net_lwip_gethostbyname;
}
int32_t returncode_lwip2net(int32_t ret_in)
{
int32_t ret = ret_in;
if (ret_in == -1)
{
if (errno == EWOULDBLOCK)
{
ret = 0;
}
}
else if (ret_in == 0)
{
/* connection close */
ret = NET_ERROR_DISCONNECTED;
}
else
{
/* do not catch ret valie otherwise */
ret = ret_in;
}
return ret;
}
#ifndef NET_BYPASS_NET_SOCKET
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_socket(int32_t domain, int32_t type, int32_t protocol)
{
int32_t sock;
sock = (int32_t) lwip_socket(domain, type, protocol);
return (sock);
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static struct sockaddr *getsockaddr(const net_sockaddr_t *addr)
{
/*cstat -MISRAC2012-Rule-11.8 const*/
return (struct sockaddr *) addr;
/*cstat +MISRAC2012-Rule-11.8 const*/
}
static int32_t net_lwip_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
{
int32_t ret = lwip_bind(sock, getsockaddr(addr), addrlen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_listen(int32_t sock, int32_t backlog)
{
int32_t ret;
ret = lwip_listen(sock, backlog);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen)
{
int32_t ret;
ret = lwip_accept(sock, getsockaddr(addr), addrlen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
{
int32_t ret;
ret = lwip_connect(sock, getsockaddr(addr), addrlen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
{
int32_t ret;
ret = lwip_send(sock, buf, (uint32_t) len, flags);
return returncode_lwip2net(ret);
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
{
int32_t ret;
ret = lwip_recv(sock, buf, (uint32_t) len, flags);
return returncode_lwip2net(ret);
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
uint32_t tolen)
{
int32_t ret = lwip_sendto(sock, buf, (uint32_t) len, flags, getsockaddr(to), tolen);
return returncode_lwip2net(ret);
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
uint32_t *fromlen)
{
int32_t ret = lwip_recvfrom(sock, buf, (uint32_t) len, flags, getsockaddr(from), fromlen);
return returncode_lwip2net(ret);
}
/**
* @brief function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen)
{
int32_t ret = lwip_setsockopt(sock, level, optname, optvalue, optlen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen)
{
int32_t ret = lwip_getsockopt(sock, level, optname, optvalue, optlen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
{
int32_t ret = lwip_getsockname(sock, getsockaddr(name), namelen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
{
int32_t ret = lwip_getpeername(sock, getsockaddr(name), namelen);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_close(int32_t sock, bool clone)
{
(void) clone;
int32_t ret = lwip_close(sock);
return ret;
}
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_shutdown(int32_t sock, int32_t mode)
{
int32_t ret = lwip_shutdown(sock, mode);
return ret;
}
#endif /* NET_BYPASS_NET_SOCKET */
/**
* @brief Function description
* @param Params
* @retval socket status
*/
static int32_t net_lwip_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name)
{
int32_t ret = NET_ERROR_DNS_FAILURE;
struct addrinfo *hostinfo;
struct addrinfo hints;
(void) pnetif;
if (addr->sa_len < sizeof(net_sockaddr_in_t))
{
ret = NET_ERROR_PARAMETER;
}
else
{
(void) memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
if (0 == lwip_getaddrinfo((char_t *)name, NULL, &hints, &hostinfo))
{
if (hostinfo->ai_family == AF_INET)
{
uint8_t len = addr->sa_len;
net_sockaddr_in_t *saddr = (net_sockaddr_in_t *) addr;
(void) memset(saddr, 0, len);
saddr->sin_len = len;
saddr->sin_family = NET_AF_INET;
(void) memcpy(&saddr->sin_addr, &((net_sockaddr_in_t *)(hostinfo->ai_addr))->sin_addr, 4);
ret = NET_OK;
}
lwip_freeaddrinfo(hostinfo);
}
}
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,629 @@
/**
******************************************************************************
* @file net_mbedtls.c
* @author MCD Application Team
* @brief Network abstraction at transport layer level. mbedTLS implementation.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
#ifdef NET_MBEDTLS_HOST_SUPPORT
#if (osCMSIS >= 0x20000U)
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#else
#define OSSEMAPHOREWAIT osSemaphoreWait
#endif /* osCMSIS */
int32_t mbedtls_rng_raw(void *data, uchar_t *output, size_t len);
extern struct __RNG_HandleTypeDef hrng;
/* Private defines -----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void mbedtls_free_resource(net_socket_t *sock);
static int32_t mbedtls_net_recv(void *ctx, uchar_t *buf, size_t len, uint32_t timeout);
static int32_t mbedtls_net_send(void *ctx, const uchar_t *buf, size_t len);
#ifdef NET_USE_RTOS
extern void *pxCurrentTCB;
#ifdef MBEDTLS_THREADING_ALT
void mutex_init(mbedtls_threading_mutex_t *mutex);
void mutex_free(mbedtls_threading_mutex_t *mutex);
int32_t mutex_lock(mbedtls_threading_mutex_t *mutex);
int32_t mutex_unlock(mbedtls_threading_mutex_t *mutex);
void mutex_init(mbedtls_threading_mutex_t *mutex)
{
#if (osCMSIS >= 0x20000U)
mutex->id = osSemaphoreNew(1, 1, NULL);
#else
mutex->id = osSemaphoreCreate(&mutex->def, 1);
#endif /* osCMSIS */
}
void mutex_free(mbedtls_threading_mutex_t *mutex)
{
(void) osSemaphoreDelete(mutex->id);
}
#define WAITFOREVER 0xFFFFFFFFU /* redefined for MISRA checks */
int32_t mutex_lock(mbedtls_threading_mutex_t *mutex)
{
BaseType_t ret;
ret = (BaseType_t) OSSEMAPHOREWAIT(mutex->id, WAITFOREVER);
return (ret >= 0) ? 0 : -1;
}
int32_t mutex_unlock(mbedtls_threading_mutex_t *mutex)
{
BaseType_t ret;
ret = (BaseType_t) osSemaphoreRelease(mutex->id);
return (ret >= 0) ? 0 : -1;
}
#endif /* MBEDTLS_THREADING_ALT */
#endif /* NET_USE_RTOS */
void net_tls_init(void)
{
#ifdef MBEDTLS_THREADING_ALT
mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock);
#endif /* MBEDTLS_THREADING_ALT */
}
void net_tls_destroy(void)
{
#ifdef MBEDTLS_THREADING_ALT
mbedtls_threading_free_alt();
#endif /* MBEDTLS_THREADING_ALT */
}
/* Functions Definition ------------------------------------------------------*/
bool net_mbedtls_check_tlsdata(net_socket_t *sock)
{
bool ret = true;
void *p;
if (NULL == sock->tlsData)
{
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
p = NET_MALLOC(sizeof(net_tls_data_t));
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (p == NULL)
{
NET_DBG_ERROR("Error during setting option.\n");
ret = false;
}
else
{
/*cstat -MISRAC2012-Rule-11.5 */
sock->tlsData = p;
/*cstat +MISRAC2012-Rule-11.5 */
(void) memset(sock->tlsData, 0, sizeof(net_tls_data_t));
sock->tlsData->tls_srv_verification = true;
}
}
return ret;
}
static void DebugPrint(void *ctx,
int32_t level,
const char_t *file,
int32_t line,
const char_t *str)
{
/* Unused parameters. */
(void)ctx;
(void) level;
#ifdef NET_USE_RTOS
NET_PRINT_WO_CR("%p => %s:%04ld: %s\n", pxCurrentTCB, file, (int32_t) line, str);
#else
NET_PRINT_WO_CR("%s:%04ld: %s\n", file, (uint32_t) line, str);
#endif /* NET_USE_RTOS */
}
void net_mbedtls_set_read_timeout(net_socket_t *sock)
{
net_tls_data_t *tlsData = sock->tlsData;
if (tlsData != NULL)
{
mbedtls_ssl_conf_read_timeout(&tlsData->conf, (uint32_t) sock->read_timeout);
}
}
static void *net_wrapper_calloc(size_t n, size_t m)
{
/*cstat -MISRAC2012-Dir-4.12 -MISRAC2012-Rule-21.3 */
return NET_CALLOC(n, m);
/*cstat +MISRAC2012-Dir-4.12 +MISRAC2012-Rule-21.3 */
}
/*cstat -MISRAC2012-Dir-4.6_b */
typedef void (*mbedtls_debug_func_t)(void *, int, const char *, int, const char *);
typedef int (*mbedtls_rng_func_t)(void *, unsigned char *, size_t);
/*cstat +MISRAC2012-Dir-4.6_b */
static void net_wrapper_free(void *p)
{
/*cstat -MISRAC2012-Rule-21.3 */
NET_FREE(p);
/*cstat +MISRAC2012-Rule-21.3 */
}
uint32_t NET_TICK(void);
int32_t net_mbedtls_start(net_socket_t *sock)
{
int32_t ret = NET_OK;
net_tls_data_t *tlsData = sock->tlsData;
uint32_t start_tick;
(void) mbedtls_platform_set_calloc_free(net_wrapper_calloc, net_wrapper_free);
mbedtls_ssl_init(&tlsData->ssl);
mbedtls_ssl_config_init(&tlsData->conf);
/*cstat -MISRAC2012-Rule-11.1 */
mbedtls_ssl_conf_dbg(&tlsData->conf, (mbedtls_debug_func_t) DebugPrint, NULL);
/*cstat +MISRAC2012-Rule-11.1 */
mbedtls_debug_set_threshold(NET_MBEDTLS_DEBUG_LEVEL);
mbedtls_x509_crt_init(&tlsData->cacert);
if (tlsData->tls_dev_cert != NULL)
{
mbedtls_x509_crt_init(&tlsData->clicert);
}
if (tlsData->tls_dev_key != NULL)
{
mbedtls_pk_init(&tlsData->pkey);
}
/* Root CA */
if (tlsData->tls_ca_certs != NULL)
{
ret = mbedtls_x509_crt_parse(&tlsData->cacert, (uchar_t const *) tlsData->tls_ca_certs,
strlen((char_t const *) tlsData->tls_ca_certs) + 1U);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_x509_crt_parse returned 0x%lx while parsing root cert\n", ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_CRT_PARSE;
}
}
else
{
/*no root so cannot check server identification ?
tlsData->tls_srv_verification = */
}
/* Client cert. and key */
if ((ret == NET_OK) && (tlsData->tls_dev_cert != NULL) && (tlsData->tls_dev_key != NULL))
{
ret = mbedtls_x509_crt_parse(&tlsData->clicert, (uchar_t const *) tlsData->tls_dev_cert,
strlen((char_t const *)tlsData->tls_dev_cert) + 1U);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%lx while parsing device cert\n", -ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_CRT_PARSE;
}
else
{
ret = mbedtls_pk_parse_key(&tlsData->pkey, (uchar_t const *)tlsData->tls_dev_key,
strlen((char_t const *)tlsData->tls_dev_key) + 1U,
(uchar_t const *)tlsData->tls_dev_pwd, tlsData->tls_dev_pwd_len);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%lx while parsing private key\n\n", -ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_KEY_PARSE;
}
}
}
/* TLS Connection */
if (ret == NET_OK)
{
ret = mbedtls_ssl_config_defaults(&tlsData->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%lx\n\n", -ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_CONFIG;
}
}
if (ret == NET_OK)
{
/* Allow the user to select a TLS profile? */
if (tlsData->tls_cert_prof != NULL)
{
mbedtls_ssl_conf_cert_profile(&tlsData->conf, tlsData->tls_cert_prof);
}
/* Only for debug
* mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); */
if (tlsData->tls_srv_verification == true)
{
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
}
else
{
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
}
/* no verification because no certificat */
/*
if (tlsData->tls_ca_certs == NULL)
{
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_NONE);
}
*/
/*cstat -MISRAC2012-Rule-11.1 */
mbedtls_ssl_conf_rng(&tlsData->conf, (mbedtls_rng_func_t) mbedtls_rng_raw, &hrng);
/*cstat +MISRAC2012-Rule-11.1 */
mbedtls_ssl_conf_ca_chain(&tlsData->conf, &tlsData->cacert, NULL);
if ((tlsData->tls_dev_cert != NULL) && (tlsData->tls_dev_key != NULL))
{
ret = mbedtls_ssl_conf_own_cert(&tlsData->conf, &tlsData->clicert, &tlsData->pkey);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned -0x%lx\n\n", -ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_CONFIG;
}
}
}
if (ret == NET_OK)
{
ret = mbedtls_ssl_setup(&tlsData->ssl, &tlsData->conf);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%lx\n\n", -ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_SSL_SETUP;
}
}
if ((ret == NET_OK) && (tlsData->tls_srv_name != NULL))
{
ret = mbedtls_ssl_set_hostname(&tlsData->ssl, (char_t const *)tlsData->tls_srv_name);
if (ret != 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %ld\n\n", ret);
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_SET_HOSTNAME;
}
}
if (ret == NET_OK)
{
/*cstat -MISRAC2012-Rule-11.1 */
mbedtls_ssl_set_bio(&tlsData->ssl, sock, (mbedtls_ssl_send_t *) mbedtls_net_send, NULL,
(mbedtls_ssl_recv_timeout_t *) mbedtls_net_recv);
/*cstat +MISRAC2012-Rule-11.1 */
mbedtls_ssl_conf_read_timeout(&tlsData->conf, (uint32_t)sock->read_timeout);
NET_DBG_INFO("\n\nSSL state connect : %d ", sock->tlsData->ssl.state);
NET_DBG_INFO("\n\nSSL state connect : %d ", sock->tlsData->ssl.state);
NET_DBG_INFO(" . Performing the SSL/TLS handshake...");
ret = mbedtls_ssl_handshake(&tlsData->ssl);
start_tick = NET_TICK();
while (ret != 0)
{
uint32_t elapsed_tick = NET_TICK() - start_tick;
if (elapsed_tick > NET_MBEDTLS_CONNECT_TIMEOUT)
{
mbedtls_free_resource(sock);
ret = NET_ERROR_MBEDTLS_CONNECT;
break;
}
if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE))
{
tlsData->flags = mbedtls_ssl_get_verify_result(&tlsData->ssl);
if (tlsData->flags != 0U)
{
char_t vrfy_buf[512];
(void) mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsData->flags);
if (tlsData->tls_srv_verification == true)
{
NET_DBG_ERROR("Server verification:\n%s\n", vrfy_buf);
}
else
{
NET_DBG_INFO("Server verification:\n%s\n", vrfy_buf);
}
}
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%lx\n", -ret);
mbedtls_free_resource(sock);
ret = (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ? NET_ERROR_MBEDTLS_REMOTE_AUTH : NET_ERROR_MBEDTLS_CONNECT;
/*cstat -MISRAC2012-Rule-15.4 */
break;
/*cstat +MISRAC2012-Rule-15.4 */
}
ret = mbedtls_ssl_handshake(&tlsData->ssl);
}
if (ret == NET_OK)
{
int32_t exp;
NET_DBG_INFO(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
mbedtls_ssl_get_version(&sock->tlsData->ssl),
mbedtls_ssl_get_ciphersuite(&sock->tlsData->ssl));
exp = mbedtls_ssl_get_record_expansion(&tlsData->ssl);
if (exp >= 0)
{
NET_DBG_INFO(" [ Record expansion is %d ]\n", exp);
}
else
{
NET_DBG_INFO(" [ Record expansion is unknown (compression) ]\n");
}
NET_DBG_INFO(" . Verifying peer X.509 certificate...");
#ifdef NET_DBG_INFO
#define NET_CERTIFICATE_DISPLAY_LEN 2048U
if (mbedtls_ssl_get_peer_cert(&sock->tlsData->ssl) != NULL)
{
/*cstat -MISRAC2012-Rule-11.5 -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
char_t *buf = NET_MALLOC(sizeof(char_t) * NET_CERTIFICATE_DISPLAY_LEN);
/*cstat +MISRAC2012-Rule-11.5 +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
if (buf != NULL)
{
NET_DBG_INFO(" . Peer certificate information ...\n");
(void) mbedtls_x509_crt_info(buf, NET_CERTIFICATE_DISPLAY_LEN - 1U, " ",
mbedtls_ssl_get_peer_cert(&sock->tlsData->ssl));
NET_DBG_INFO("%s\n", buf);
/*cstat -MISRAC2012-Rule-21.3 */
NET_FREE(buf);
/*cstat +MISRAC2012-Rule-21.3 */
}
else
{
NET_DBG_INFO(" . Cannot allocate memory to display certificate information ...\n");
}
}
#endif /* NET_DBG_INFO */
}
}
return ret;
}
int32_t net_mbedtls_sock_recv(net_socket_t *sock, uint8_t *buf, size_t len)
{
net_tls_data_t *tlsData = sock->tlsData;
int32_t ret;
ret = mbedtls_ssl_read(&tlsData->ssl, buf, len);
if (ret <= 0)
{
switch (ret)
{
case 0:
ret = NET_ERROR_DISCONNECTED;
break;
case MBEDTLS_ERR_SSL_TIMEOUT: /* In case a blocking read function was passed through mbedtls_ssl_set_bio() */
ret = NET_TIMEOUT;
break;
case MBEDTLS_ERR_SSL_WANT_READ:
ret = NET_TIMEOUT;
break;
default:
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_read returned -0x%lx\n\n", -ret);
ret = NET_ERROR_MBEDTLS;
break;
}
}
return ret;
}
int32_t net_mbedtls_sock_send(net_socket_t *sock, const uint8_t *buf, size_t len)
{
int32_t ret;
net_tls_data_t *tlsData = sock->tlsData;
#if PERF
stat.mbedtls_send_cycle -= net_get_cycle();
#endif /* PERF */
ret = mbedtls_ssl_write(&tlsData->ssl, buf, len);
if (ret == 0)
{
ret = NET_ERROR_DISCONNECTED;
}
else if (ret < 0)
{
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_write returned -0x%lx\n\n", -ret);
ret = NET_ERROR_MBEDTLS;
}
else
{
/* ret > 0 nothing to do , MISRA checks */
}
#if PERF
stat.mbedtls_send_cycle += net_get_cycle();
#endif /* PERF */
return (ret);
}
int32_t net_mbedtls_stop(net_socket_t *sock)
{
int32_t ret;
/* Closure notification is required by TLS if the session was not already closed by the remote host. */
net_tls_data_t *tlsData = sock->tlsData;
do
{
ret = mbedtls_ssl_close_notify(&tlsData->ssl);
} while ((ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ));
/* All other negative return values indicate connection needs to be reset.
* No further action required since this is disconnect call */
mbedtls_free_resource(sock);
return NET_OK;
}
static void mbedtls_free_resource(net_socket_t *sock)
{
net_tls_data_t *tlsData = sock->tlsData;
mbedtls_x509_crt_free(&tlsData->clicert);
mbedtls_pk_free(&tlsData->pkey);
mbedtls_x509_crt_free(&tlsData->cacert);
mbedtls_ssl_free(&tlsData->ssl);
mbedtls_ssl_config_free(&tlsData->conf);
/*cstat -MISRAC2012-Rule-21.3 */
NET_FREE(tlsData);
/*cstat +MISRAC2012-Rule-21.3 */
sock->tlsData = 0;
return;
}
/* received interface implementation.*/
static int32_t mbedtls_net_recv(void *ctx, uchar_t *buf, size_t len, uint32_t timeout)
{
int32_t ret = NET_OK;
int32_t flags = 0;
/*cstat -MISRAC2012-Rule-11.5 */
net_socket_t *pSocket = (net_socket_t *) ctx;
/*cstat +MISRAC2012-Rule-11.5 */
if (pSocket->read_timeout != (int32_t)timeout)
{
ret = pSocket->pnetif->pdrv->psetsockopt(pSocket->ulsocket,
NET_SOL_SOCKET, NET_SO_RCVTIMEO, &timeout, sizeof(uint32_t));
if (ret == NET_OK)
{
pSocket->read_timeout = (int32_t) timeout;
}
}
if (ret == NET_OK)
{
if (pSocket->read_timeout == 0)
{
flags = (int8_t) NET_MSG_DONTWAIT;
}
UNLOCK_SOCK(pSocket->idx);
ret = pSocket->pnetif->pdrv->precv(pSocket->ulsocket, buf, len, flags);
LOCK_SOCK(pSocket->idx);
if (ret <= 0)
{
switch (ret)
{
case 0:
ret = MBEDTLS_ERR_SSL_WANT_READ;
break;
case NET_TIMEOUT:
/* According to mbedtls headers, MBEDTLS_ERR_SSL_TIMEOUT should be returned. */
/* But it saturates the error log with false errors. By contrast, */
/* MBEDTLS_ERR_SSL_WANT_READ does not raise any error. */
ret = MBEDTLS_ERR_SSL_WANT_READ;
break;
default:
NET_DBG_ERROR("mbedtls_net_recv() : error %ld in recv() - requestedLen=%d\n", ret, len);
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
break;
}
}
}
return ret;
}
static int32_t mbedtls_net_send(void *ctx, const uchar_t *buf, size_t len)
{
/*cstat -MISRAC2012-Rule-11.5 */
net_socket_t *pSocket = (net_socket_t *) ctx;
/*cstat +MISRAC2012-Rule-11.5 */
int32_t ret;
int32_t flags = 0;
if (pSocket->write_timeout == 0)
{
flags = (int8_t) NET_MSG_DONTWAIT;
}
UNLOCK_SOCK(pSocket->idx);
/*cstat -MISRAC2012-Rule-11.8 removing const attribute */
ret = pSocket->pnetif->pdrv->psend(pSocket->ulsocket, (uchar_t *) buf, len, flags);
/*cstat +MISRAC2012-Rule-11.8 */
LOCK_SOCK(pSocket->idx);
if (ret >= 0)
{
if (ret == 0)
{
ret = MBEDTLS_ERR_SSL_WANT_WRITE;
}
}
else
{
NET_DBG_ERROR("mbedtls_net_send(): error %ld in send() - requestedLen=%d\n", ret, len);
/* TODO: The underlying layers do not allow to distinguish between
* MBEDTLS_ERR_SSL_INTERNAL_ERROR,
* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY,
* MBEDTLS_ERR_SSL_CONN_EOF.
* Most often, the error is due to the closure of the connection by the remote host. */
ret = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
}
return ret;
}
#endif /* NET_MBEDTLS_HOST_SUPPORT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,187 @@
/**
******************************************************************************
* @file net_ping.c
* @author MCD Application Team
* @brief application to send icmp ping
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
#include "net_internals.h"
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
#include "lwip/tcpip.h"
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/api.h" /* HAL_GetTick() */
#include "lwip/ip4.h"
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
#define PING_ID 0xAFAF
#endif /* PING_ID */
/** ping additional data size to include in the packet */
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif /* PING_DATA_SIZE */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len, uint16_t ping_seq_num)
{
size_t i;
size_t data_len = len - sizeof(struct icmp_echo_hdr);
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
ICMPH_CODE_SET(iecho, 0);
iecho->chksum = 0;
iecho->id = PING_ID;
iecho->seqno = (uint16_t) lwip_htons(ping_seq_num);
/* fill the additional data buffer with some data */
for (i = 0; i < data_len; i++)
{
((char_t *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char_t)i;
}
/* Ping data are sent in RAM mode , so LWIP is not computing the checksum by SW */
#ifndef CHECKSUM_BY_HARDWARE
iecho->chksum = inet_chksum(iecho, len);
#endif /* CHECKSUM_BY_HARDWARE */
}
uint32_t sys_now(void);
#define NET_IPH_HL(hdr) ((hdr)->_v_hl & 0x0fU)
int32_t icmp_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t timeout, int32_t response[])
{
int32_t sock;
int32_t ret = 0;
uint32_t ping_start_time;
net_sockaddr_t from;
uint32_t fromlen;
int32_t len;
static int32_t ping_seq_num = 1;
char_t buf[64] = "";
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho, *pecho = NULL;
size_t ping_size = sizeof(struct icmp_echo_hdr) + (uint32_t) PING_DATA_SIZE;
u16_t seqnum;
(void) pnetif;
sock = net_socket(NET_AF_INET, NET_SOCK_RAW, NET_IPPROTO_ICMP);
if (sock < 0)
{
NET_DBG_ERROR("ping: socket fail\r\n");
ret = -1;
}
else if (net_setsockopt(sock, NET_SOL_SOCKET, NET_SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
{
NET_DBG_ERROR("ping: setsockopt() fail\r\n");
ret = -1;
}
else
{
/*cstat -MISRAC2012-Rule-11.5 Malloc */
pecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
/*cstat +MISRAC2012-Rule-11.5 */
if (pecho == NULL)
{
NET_DBG_ERROR("ping_client_process : message alloc fails\r\n");
ret = -1;
}
}
if (ret == 0)
{
addr->sa_family = NET_AF_INET;
net_set_port(addr, 0U);
for (int32_t i = 0; i < count; i++)
{
response[i] = -1;
/* add useless test for MISRA on pecho */
if (pecho != NULL)
{
ping_prepare_echo(pecho, (uint16_t) ping_size, (uint16_t) ping_seq_num);
}
if (net_sendto(sock, (uint8_t *)pecho, (int32_t) ping_size, 0, addr, (int32_t) sizeof(net_sockaddr_t)) < 0)
{
NET_DBG_INFO("ping_client_process : send fail\r\n");
break;
}
ping_start_time = sys_now();
do
{
len = net_recvfrom(sock, (uint8_t *)buf, (int32_t) ping_size, 0, &from, &fromlen);
if (len >= (int32_t)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
{
/*cstat -MISRAC2012-Rule-11.3 Cast */
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf + ((NET_IPH_HL(iphdr)) * 4U));
/*cstat +MISRAC2012-Rule-11.3 Cast */
seqnum = lwip_htons((uint16_t) ping_seq_num);
if ((iecho->id == (uint16_t)PING_ID) && (iecho->seqno == seqnum))
{
if (ICMPH_TYPE(iecho) == (uint8_t) ICMP_ER)
{
uint32_t delta;
ret = 0;
delta = sys_now() - ping_start_time;
response[i] = (int32_t) delta;
break;
}
else
{
NET_DBG_ERROR("ICMP Other Response received \r\n");
}
}
}
else
{
uint32_t now = sys_now();
NET_DBG_ERROR("no data start %ld : %lu .. %lu\r\n", len, ping_start_time, now);
}
} while (sys_now() < (ping_start_time + (uint32_t) timeout));
ping_seq_num++;
}
if (pecho != NULL)
{
mem_free(pecho);
}
(void) net_closesocket(sock);
}
return ret;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,62 @@
/**
******************************************************************************
* @file net_conf.c
* @author MCD Application Team
* @brief Implement cellular_probe() called to initialize the Cellular low level driver
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "net_connect.h"
/* Private functions ---------------------------------------------------------*/
int32_t cellular_probe(void **ll_drv_context);
int32_t cellular_probe(void **ll_drv_context)
{
return 0;
}
#ifdef GENERATOR_AWS_CLOUD
#include "mbedtls/x509_crt.h"
/*
* Amazon Profile
*/
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
{
/* Only SHA-256 and 384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
/* Only ECDSA */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
#if defined(MBEDTLS_ECP_C)
/* Only NIST P-256 and P-384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
#else
0,
#endif /* MBEDTLS_ECP_C */
2048
};
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
#endif /* GENERATOR_AWS_CLOUD */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,79 @@
/**
******************************************************************************
* @file net_conf.h
* @author MCD Application Team
* @brief This file provides the configuration for net
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONF_H
#define NET_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#define MDM_SIM_SELECT_0_Pin GPIO_PIN_2
#define MDM_SIM_SELECT_0_GPIO_Port GPIOC
#define MDM_SIM_SELECT_1_Pin GPIO_PIN_3
#define MDM_SIM_SELECT_1_GPIO_Port GPIOI
#define MDM_SIM_CLK_Pin GPIO_PIN_4
#define MDM_SIM_CLK_GPIO_Port GPIOA
#define MDM_SIM_DATA_Pin GPIO_PIN_12
#define MDM_SIM_DATA_GPIO_Port GPIOB
#define MDM_SIM_RST_Pin GPIO_PIN_7
#define MDM_SIM_RST_GPIO_Port GPIOC
#define MDM_PWR_EN_Pin GPIO_PIN_3
#define MDM_PWR_EN_GPIO_Port GPIOD
#define MDM_DTR_Pin GPIO_PIN_0
#define MDM_DTR_GPIO_Port GPIOA
#define MDM_RST_Pin GPIO_PIN_2
#define MDM_RST_GPIO_Port GPIOB
#define USART1_TX_Pin GPIO_PIN_6
#define USART1_TX_GPIO_Port GPIOB
#define UART1_RX_Pin GPIO_PIN_10
#define UART1_RX_GPIO_Port GPIOG
#define UART1_CTS_Pin GPIO_PIN_11
#define UART1_CTS_GPIO_Port GPIOG
#define UART1_RTS_Pin GPIO_PIN_12
#define UART1_RTS_GPIO_Port GPIOG
#define NET_USE_RTOS
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
#define NET_MBEDTLS_HOST_SUPPORT
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
#include "net_conf_template.h"
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,834 @@
/**
******************************************************************************
* @file es_wifi_io.c
* @author MCD Application Team
* @brief This file implements the IO operations to deal with the es-wifi
* module. It mainly Inits and Deinits the SPI interface. Send and
* receive data over it.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#if defined(TARGET_STM32F413H_DISCOVERY)
#include "stm32f4xx_hal.h"
#define DATA_READY_IRQ EXTI15_10_IRQn
#endif /* TARGET_STM32F413H_DISCOVERY */
#if defined(TARGET_B_L475E_IOT01)
#include "stm32l4xx_hal.h"
#define DATA_READY_IRQ EXTI1_IRQn
#endif /* TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
#include "stm32h7xx_hal.h"
#define DATA_READY_IRQ EXTI9_5_IRQn
#endif /* TARGET_STM32H7B3I_DISCOVERY */
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
#include <core_cm4.h>
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
#include <core_cm7.h>
#endif /* TARGET_STM32H7B3I_DISCOVERY */
#include <string.h>
#include "es_wifi.h"
#include "es_wifi_conf.h"
#include "net_conf.h"
#ifdef GENERATOR_AWS_CLOUD
#include "mbedtls/x509_crt.h"
#endif /* GENERATOR_AWS_CLOUD */
/* Global variables --------------------------------------------------------*/
SPI_HandleTypeDef hspi;
/* Function definitions --------------------------------------------------------*/
static void SPI_WIFI_MspInit(SPI_HandleTypeDef *hspi);
/* Private define ------------------------------------------------------------*/
#if defined(TARGET_STM32F413H_DISCOVERY)
#define WIFI_RESET_MODULE() do{\
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_RESET);\
HAL_Delay(10);\
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_SET);\
HAL_Delay(500);\
}while(0);
#define WIFI_ENABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOG, GPIO_PIN_11, GPIO_PIN_RESET );\
}while(0);
#define WIFI_DISABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOG, GPIO_PIN_11, GPIO_PIN_SET );\
}while(0);
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_12) == GPIO_PIN_SET)
#endif /* TARGET_STM32F413H_DISCOVERY */
#if defined(TARGET_B_L475E_IOT01)
#define WIFI_RESET_MODULE() do{\
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);\
HAL_Delay(10);\
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);\
HAL_Delay(500);\
}while(0);
#define WIFI_ENABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOE, GPIO_PIN_0, GPIO_PIN_RESET );\
}while(0);
#define WIFI_DISABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOE, GPIO_PIN_0, GPIO_PIN_SET );\
}while(0);
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_1) == GPIO_PIN_SET)
#endif /* TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
#define WIFI_RESET_MODULE() do{\
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_RESET);\
HAL_Delay(10);\
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_SET);\
HAL_Delay(500);\
}while(0);
#define WIFI_ENABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_RESET );\
}while(0);
#define WIFI_DISABLE_NSS() do{ \
HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_SET );\
}while(0);
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_5) == GPIO_PIN_SET)
#define SPI_INTERFACE_PRIO 0
#endif /* TARGET_STM32H7B3I_DISCOVERY */
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static int32_t __IO spi_rx_event = 0;
static int32_t __IO spi_tx_event = 0;
static int32_t __IO cmddata_rdy_rising_event = 0;
#ifdef WIFI_USE_CMSIS_OS
osMutexId es_wifi_mutex;
osMutexDef(es_wifi_mutex);
static osMutexId spi_mutex;
osMutexDef(spi_mutex);
static osSemaphoreId spi_rx_sem;
osSemaphoreDef(spi_rx_sem);
static osSemaphoreId spi_tx_sem;
osSemaphoreDef(spi_tx_sem);
static osSemaphoreId cmddata_rdy_rising_sem;
osSemaphoreDef(cmddata_rdy_rising_sem);
#endif /* WIFI_USE_CMSIS_OS */
/* Private function prototypes -----------------------------------------------*/
static int32_t wait_cmddata_rdy_high(int32_t timeout);
static int32_t wait_cmddata_rdy_rising_event(int32_t timeout);
static int32_t wait_spi_tx_event(int32_t timeout);
static int32_t wait_spi_rx_event(int32_t timeout);
static void SPI_WIFI_DelayUs(uint32_t);
static int8_t SPI_WIFI_DeInit(void);
static int8_t SPI_WIFI_Init(uint16_t mode);
static int8_t SPI_WIFI_ResetModule(void);
static int16_t SPI_WIFI_ReceiveData(uint8_t *pData, uint16_t len, uint32_t timeout);
static int16_t SPI_WIFI_SendData(uint8_t *pData, uint16_t len, uint32_t timeout);
/* Private functions ---------------------------------------------------------*/
#ifdef GENERATOR_AWS_CLOUD
/*
* Amazon Profile
*/
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
{
/* Only SHA-256 and 384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
/* Only ECDSA */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
#if defined(MBEDTLS_ECP_C)
/* Only NIST P-256 and P-384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
#else
0,
#endif /* MBEDTLS_ECP_C */
2048
};
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
#endif /* GENERATOR_AWS_CLOUD */
int32_t wifi_probe(void **ll_drv_context);
ES_WIFIObject_t EsWifiObj;
/*******************************************************************************
COM Driver Interface (SPI)
*******************************************************************************/
/**
* @brief Initialize SPI MSP
* @param hspi: SPI handle
* @retval None
*/
static void SPI_WIFI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_Init;
#if defined(TARGET_STM32F413H_DISCOVERY)
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* configure Wake up pin */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
GPIO_Init.Pin = GPIO_PIN_15;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
/* configure Data ready pin */
GPIO_Init.Pin = GPIO_PIN_12;
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOG, &GPIO_Init);
/* configure Reset pin */
GPIO_Init.Pin = GPIO_PIN_1;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_Init.Alternate = 0;
HAL_GPIO_Init(GPIOH, &GPIO_Init);
/* configure SPI NSS pin pin */
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_11, GPIO_PIN_SET);
GPIO_Init.Pin = GPIO_PIN_11;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOG, &GPIO_Init);
/* configure SPI CLK pin */
GPIO_Init.Pin = GPIO_PIN_12;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF7_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
/* configure SPI MOSI pin */
GPIO_Init.Pin = GPIO_PIN_5;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
/* configure SPI MISO pin */
GPIO_Init.Pin = GPIO_PIN_4;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
#endif /* TARGET_STM32F413H_DISCOVERY */
#if defined(TARGET_B_L475E_IOT01)
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* configure Wake up pin */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
GPIO_Init.Pin = GPIO_PIN_13;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_Init);
/* configure Data ready pin */
GPIO_Init.Pin = GPIO_PIN_1;
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_Init);
/* configure Reset pin */
GPIO_Init.Pin = GPIO_PIN_8;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_Init.Alternate = 0;
HAL_GPIO_Init(GPIOE, &GPIO_Init);
/* configure SPI NSS pin pin */
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_SET);
GPIO_Init.Pin = GPIO_PIN_0;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOE, &GPIO_Init);
/* configure SPI CLK pin */
GPIO_Init.Pin = GPIO_PIN_10;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_Init);
/* configure SPI MOSI pin */
GPIO_Init.Pin = GPIO_PIN_12;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_Init);
/* configure SPI MISO pin */
GPIO_Init.Pin = GPIO_PIN_11;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_Init);
#endif /* TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
/* configure Wake up pin */
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_2, GPIO_PIN_RESET);
GPIO_Init.Pin = GPIO_PIN_2;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOI, &GPIO_Init);
/* configure Data ready pin */
GPIO_Init.Pin = GPIO_PIN_5;
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOI, &GPIO_Init);
/* configure Reset pin */
GPIO_Init.Pin = GPIO_PIN_1;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_Init.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOI, &GPIO_Init);
/* configure SPI NSS pin pin */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
GPIO_Init.Pin = GPIO_PIN_11;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, &GPIO_Init);
/* configure SPI CLK pin */
GPIO_Init.Pin = GPIO_PIN_12;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_Init.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOA, &GPIO_Init);
/* configure SPI MOSI pin */
GPIO_Init.Pin = GPIO_PIN_3;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_Init.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_Init);
/* configure SPI MISO pin */
GPIO_Init.Pin = GPIO_PIN_2;
GPIO_Init.Mode = GPIO_MODE_AF_PP;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_Init.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_Init);
#endif /* TARGET_STM32H7B3I_DISCOVERY */
}
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
/**
* @brief Initialize the SPI3
* @param None
* @retval None
*/
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
/**
* @brief Initialize the SPI2
* @param None
* @retval None
*/
#endif /* TARGET_STM32H7B3I_DISCOVERY */
static int8_t SPI_WIFI_Init(uint16_t mode)
{
int8_t rc = 0;
if (mode == ES_WIFI_INIT)
{
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
hspi.Instance = SPI3;
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
hspi.Instance = SPI2;
#endif /* TARGET_STM32H7B3I_DISCOVERY */
SPI_WIFI_MspInit(&hspi);
hspi.Init.Mode = SPI_MODE_MASTER;
hspi.Init.Direction = SPI_DIRECTION_2LINES;
hspi.Init.DataSize = SPI_DATASIZE_16BIT;
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi.Init.NSS = SPI_NSS_SOFT;
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; /* 80/8= 10MHz (Inventek WIFI module supports up to 20MHz)*/
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi.Init.TIMode = SPI_TIMODE_DISABLE;
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi.Init.CRCPolynomial = 0;
if (HAL_SPI_Init(&hspi) != HAL_OK)
{
return -1;
}
/* Enable Interrupt for Data Ready pin , GPIO_PIN1 */
HAL_NVIC_SetPriority((IRQn_Type)DATA_READY_IRQ, SPI_INTERFACE_PRIO, 0x00);
HAL_NVIC_EnableIRQ((IRQn_Type)DATA_READY_IRQ);
/* Enable Interrupt for SPI tx and rx */
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
HAL_NVIC_SetPriority((IRQn_Type)SPI3_IRQn, SPI_INTERFACE_PRIO, 0);
HAL_NVIC_EnableIRQ((IRQn_Type)SPI3_IRQn);
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
#if defined(TARGET_STM32H7B3I_DISCOVERY)
HAL_NVIC_SetPriority((IRQn_Type)SPI2_IRQn, SPI_INTERFACE_PRIO, 0);
HAL_NVIC_EnableIRQ((IRQn_Type)SPI2_IRQn);
#endif /* TARGET_STM32H7B3I_DISCOVERY */
#ifdef WIFI_USE_CMSIS_OS
cmddata_rdy_rising_event = 0;
es_wifi_mutex = osMutexCreate(osMutex(es_wifi_mutex));
spi_mutex = osMutexCreate(osMutex(spi_mutex));
spi_rx_sem = osSemaphoreCreate(osSemaphore(spi_rx_sem), 1);
spi_tx_sem = osSemaphoreCreate(osSemaphore(spi_tx_sem), 1);
cmddata_rdy_rising_sem = osSemaphoreCreate(osSemaphore(cmddata_rdy_rising_sem), 1);
/* take semaphore */
SEM_WAIT(cmddata_rdy_rising_sem, 1);
SEM_WAIT(spi_rx_sem, 1);
SEM_WAIT(spi_tx_sem, 1);
#endif /* WIFI_USE_CMSIS_OS */
/* first call used for calibration */
SPI_WIFI_DelayUs(10);
}
rc = SPI_WIFI_ResetModule();
return rc;
}
static int8_t SPI_WIFI_ResetModule(void)
{
uint32_t tickstart = HAL_GetTick();
uint8_t Prompt[6];
uint8_t count = 0;
HAL_StatusTypeDef Status;
WIFI_RESET_MODULE();
WIFI_ENABLE_NSS();
SPI_WIFI_DelayUs(15);
while (WIFI_IS_CMDDATA_READY())
{
Status = HAL_SPI_Receive(&hspi, &Prompt[count], 1, 0xFFFF);
count += 2;
if (((HAL_GetTick() - tickstart) > 0xFFFF) || (Status != HAL_OK))
{
WIFI_DISABLE_NSS();
return -1;
}
}
WIFI_DISABLE_NSS();
if ((Prompt[0] != 0x15) || (Prompt[1] != 0x15) || (Prompt[2] != '\r') ||
(Prompt[3] != '\n') || (Prompt[4] != '>') || (Prompt[5] != ' '))
{
return -1;
}
return 0;
}
/**
* @brief DeInitialize the SPI
* @param None
* @retval None
*/
static int8_t SPI_WIFI_DeInit(void)
{
HAL_SPI_DeInit(&hspi);
#ifdef WIFI_USE_CMSIS_OS
osMutexDelete(spi_mutex);
osMutexDelete(es_wifi_mutex);
osSemaphoreDelete(spi_tx_sem);
osSemaphoreDelete(spi_rx_sem);
osSemaphoreDelete(cmddata_rdy_rising_sem);
#endif /* WIFI_USE_CMSIS_OS */
return 0;
}
/**
* @brief Receive wifi Data from SPI
* @param pdata : pointer to data
* @param len : Data length
* @param timeout : send timeout in mS
* @retval Length of received data (payload)
*/
int32_t wait_cmddata_rdy_high(int32_t timeout)
{
int32_t tickstart = HAL_GetTick();
while (WIFI_IS_CMDDATA_READY() == 0)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
return 0;
}
int32_t wait_cmddata_rdy_rising_event(int32_t timeout)
{
#ifdef SEM_WAIT
return SEM_WAIT(cmddata_rdy_rising_sem, timeout);
#else
int32_t tickstart = HAL_GetTick();
while (cmddata_rdy_rising_event == 1)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
return 0;
#endif /* SEM_WAIT */
}
int32_t wait_spi_rx_event(int32_t timeout)
{
#ifdef SEM_WAIT
return SEM_WAIT(spi_rx_sem, timeout);
#else
int32_t tickstart = HAL_GetTick();
while (spi_rx_event == 1)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
return 0;
#endif /* SEM_WAIT */
}
int32_t wait_spi_tx_event(int32_t timeout)
{
#ifdef SEM_WAIT
return SEM_WAIT(spi_tx_sem, timeout);
#else
int32_t tickstart = HAL_GetTick();
while (spi_tx_event == 1)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
return 0;
#endif /* SEM_WAIT */
}
int16_t SPI_WIFI_ReceiveData(uint8_t *pData, uint16_t len, uint32_t timeout)
{
int16_t length = 0;
uint8_t tmp[2];
WIFI_DISABLE_NSS();
UNLOCK_SPI();
SPI_WIFI_DelayUs(3);
if (wait_cmddata_rdy_rising_event(timeout) < 0)
{
return ES_WIFI_ERROR_WAITING_DRDY_FALLING;
}
LOCK_SPI();
WIFI_ENABLE_NSS();
SPI_WIFI_DelayUs(15);
while (WIFI_IS_CMDDATA_READY())
{
if ((length < len) || (!len))
{
spi_rx_event = 1;
if (HAL_SPI_Receive_IT(&hspi, tmp, 1) != HAL_OK)
{
WIFI_DISABLE_NSS();
UNLOCK_SPI();
return ES_WIFI_ERROR_SPI_FAILED;
}
wait_spi_rx_event(timeout);
pData[0] = tmp[0];
pData[1] = tmp[1];
length += 2;
pData += 2;
if (length >= ES_WIFI_DATA_SIZE)
{
WIFI_DISABLE_NSS();
SPI_WIFI_ResetModule();
UNLOCK_SPI();
return ES_WIFI_ERROR_STUFFING_FOREVER;
}
}
else
{
break;
}
}
WIFI_DISABLE_NSS();
UNLOCK_SPI();
return length;
}
/**
* @brief Send wifi Data thru SPI
* @param pdata : pointer to data
* @param len : Data length
* @param timeout : send timeout in mS
* @retval Length of sent data
*/
int16_t SPI_WIFI_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout)
{
uint8_t Padding[2];
if (wait_cmddata_rdy_high(timeout) < 0)
{
return ES_WIFI_ERROR_SPI_FAILED;
}
/* arm to detect rising event */
cmddata_rdy_rising_event = 1;
LOCK_SPI();
WIFI_ENABLE_NSS();
SPI_WIFI_DelayUs(15);
if (len > 1)
{
spi_tx_event = 1;
if (HAL_SPI_Transmit_IT(&hspi, (uint8_t *)pdata, len / 2) != HAL_OK)
{
WIFI_DISABLE_NSS();
UNLOCK_SPI();
return ES_WIFI_ERROR_SPI_FAILED;
}
wait_spi_tx_event(timeout);
}
if (len & 1)
{
Padding[0] = pdata[len - 1];
Padding[1] = '\n';
spi_tx_event = 1;
if (HAL_SPI_Transmit_IT(&hspi, Padding, 1) != HAL_OK)
{
WIFI_DISABLE_NSS();
UNLOCK_SPI();
return ES_WIFI_ERROR_SPI_FAILED;
}
wait_spi_tx_event(timeout);
}
return len;
}
/**
* @brief Delay
* @param Delay in us
* @retval None
*/
void SPI_WIFI_DelayUs(uint32_t n)
{
__IO uint32_t ct = 0;
uint32_t loop_per_us = 0;
static uint32_t cycle_per_loop = 0;
/* calibration happen on first call for a duration of 1 ms * nbcycle per loop */
/* 10 cycle for STM32L4 */
if (cycle_per_loop == 0)
{
uint32_t cycle_per_ms = (SystemCoreClock / 1000UL);
uint32_t tick = 0;
ct = cycle_per_ms;
tick = HAL_GetTick();
while (ct)
{
ct--;
}
cycle_per_loop = HAL_GetTick() - tick;
if (cycle_per_loop == 0)
{
cycle_per_loop = 1;
}
}
loop_per_us = SystemCoreClock / 1000000UL / cycle_per_loop;
ct = n * loop_per_us;
while (ct)
{
ct--;
}
return;
}
/**
* @brief Rx Transfer completed callback.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (spi_rx_event)
{
SEM_SIGNAL(spi_rx_sem);
spi_rx_event = 0;
}
}
/**
* @brief Tx Transfer completed callback.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (spi_tx_event)
{
SEM_SIGNAL(spi_tx_sem);
spi_tx_event = 0;
}
}
/**
* @brief Interrupt handler for Data RDY signal
* @param None
* @retval None
*/
void SPI_WIFI_ISR(void)
{
if (cmddata_rdy_rising_event == 1)
{
SEM_SIGNAL(cmddata_rdy_rising_sem);
cmddata_rdy_rising_event = 0;
}
}
/**
* @brief probe function to register wifi to Network library framework
* @param None
* @retval None
*/
int32_t wifi_probe(void **ll_drv_context)
{
if (ES_WIFI_RegisterBusIO(&EsWifiObj,
SPI_WIFI_Init,
SPI_WIFI_DeInit,
HAL_Delay,
SPI_WIFI_SendData,
SPI_WIFI_ReceiveData) == 0)
{
*ll_drv_context = &EsWifiObj;
return 0;
}
return -1;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,53 @@
/**
******************************************************************************
* @file net_conf.h
* @author MCD Application Team
* @brief This file provides the configuration for net
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONF_H
#define NET_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
#define NET_MBEDTLS_HOST_SUPPORT
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
#include "net_conf_template.h"
/* to use Inventek Wifi native TLS */
#if 0
#undef NET_MBEDTLS_HOST_SUPPORT
#define NET_MBEDTLS_WIFI_MODULE_SUPPORT
#endif /* 9 */
int32_t wifi_probe(void **ll_drv_obj);
void SPI_WIFI_ISR(void);
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,709 @@
/**
******************************************************************************
* @file LwIP/LwIP_TCP_Echo_Client/Src/ethernetif.c
* @author MCD Application Team
* @brief This file implements Ethernet network interface drivers for lwIP
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal.h"
#include "stm32h7xx_ll_utils.h"
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "net_connect.h"
#include "net_buffers.h"
#define GENERATOR_WAKAAMACLIENT_CLOUD
#ifdef NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS
#include "mbedtls/sha256.h"
#endif /* NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS */
#include "../Components/lan8742/lan8742.h"
#include <string.h>
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif);
void ethernet_link_check_state(struct netif *netif);
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#if (osCMSIS >= 0x20000U)
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#else
#define OSSEMAPHOREWAIT osSemaphoreWait
#endif /* osCMSIS */
/* Network interface name */
#define IFNAME0 's'
#define IFNAME1 't'
#define ETH_RX_BUFFER_SIZE (1536UL)
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
/* Stack size of the interface thread */
#define INTERFACE_THREAD_STACK_SIZE 1024
#define TIME_WAITING_FOR_INPUT ( 250 ) /*( portMAX_DELAY )*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*
@Note: This interface is implemented to operate in zero-copy mode only:
- Rx buffers are allocated statically and passed directly to the LwIP stack
they will return back to DMA after been processed by the stack.
- Tx Buffers will be allocated from LwIP stack memory heap,
then passed to ETH HAL driver.
@Notes:
1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4,
to customize it please redefine ETH_RX_DESC_CNT in stm32xxxx_hal_conf.h
1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4,
to customize it please redefine ETH_TX_DESC_CNT in stm32xxxx_hal_conf.h
2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
*/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location=0x30040000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location=0x30040060
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#pragma location=0x30040200
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef
DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef
DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
__attribute__((section(".RxArraySection"))) uint8_t
Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
#elif defined ( __GNUC__ ) /* GNU Compiler */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((
section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT
__attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((
section(".RxArraySection"))); /* Ethernet Receive Buffers */
#endif /* __ICCARM__ */
/* Semaphore to signal incoming packets */
static osSemaphoreId s_xSemaphore = NULL;
static osThreadId ethernetif_thread_handle = NULL;
static void ethernetif_task(void *context);
#if (osCMSIS >= 0x20000U )
static const osThreadAttr_t attr =
{
.name = "EthIf",
.priority = osPriorityHigh,
. stack_size = INTERFACE_THREAD_STACK_SIZE
};
#endif /* osCMSIS */
ETH_HandleTypeDef EthHandle;
ETH_TxPacketConfig TxConfig;
lan8742_Object_t LAN8742;
/* Private function prototypes -----------------------------------------------*/
u32_t sys_now(void);
void pbuf_free_custom(struct pbuf *p);
int32_t ETH_PHY_IO_Init(void);
int32_t ETH_PHY_IO_DeInit(void);
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
int32_t ETH_PHY_IO_GetTick(void);
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
ETH_PHY_IO_DeInit,
ETH_PHY_IO_WriteReg,
ETH_PHY_IO_ReadReg,
ETH_PHY_IO_GetTick
};
LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool");
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
LL Driver Interface ( LwIP stack --> ETH)
*******************************************************************************/
/**
* @brief In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void low_level_init(struct netif *netif)
{
uint32_t idx = 0;
uint8_t macaddress[6] = {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
/* Generate an MCU-unique MAC address */
#ifdef NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS
#define HASH_OUTPUT_LENGTH 32
unsigned char output[HASH_OUTPUT_LENGTH];
uint32_t UID[3];
/* Generate a hash digest from the unique CPU ID */
UID[0] = LL_GetUID_Word0();
UID[1] = LL_GetUID_Word1();
UID[2] = LL_GetUID_Word2();
/* Hash with mbedTLS */
int32_t hash_success = 0;
mbedtls_sha256_context sha_context;
mbedtls_sha256_init(&sha_context);
if (0 == mbedtls_sha256_starts_ret(&sha_context, 0))
{
if (0 == mbedtls_sha256_update_ret(&sha_context, (const unsigned char *) UID, sizeof(UID)))
{
if (0 == mbedtls_sha256_finish_ret(&sha_context, output))
{
hash_success = 1;
}
}
}
mbedtls_sha256_free(&sha_context);
while (hash_success == 0)
{
;
}
/* Copy the 3 first bytes of the digest to the second half of the MAC address. */
memcpy(&macaddress[3], output, 3);
#endif /* NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS */
EthHandle.Instance = ETH;
EthHandle.Init.MACAddr = macaddress;
EthHandle.Init.MediaInterface = HAL_ETH_RMII_MODE;
EthHandle.Init.RxDesc = DMARxDscrTab;
EthHandle.Init.TxDesc = DMATxDscrTab;
EthHandle.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;
/* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
HAL_ETH_Init(&EthHandle);
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
for (uint32_t i = 0; i < sizeof(macaddress) / sizeof(uint8_t); i++)
{
netif->hwaddr[i] = macaddress[i];
}
/* maximum transfer unit */
netif->mtu = ETH_MAX_PAYLOAD;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
for (idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
{
HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
}
/* Initialize the RX POOL */
LWIP_MEMPOOL_INIT(RX_POOL);
/* Set Tx packet config common parameters */
memset(&TxConfig, 0, sizeof(ETH_TxPacketConfig));
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
/* Set PHY IO functions */
LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
/* Initialize the LAN8742 ETH PHY */
LAN8742_Init(&LAN8742);
ethernet_link_check_state(netif);
}
/**
* @brief This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
uint32_t i = 0;
uint32_t framelen = 0;
struct pbuf *q;
err_t errval = ERR_OK;
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
memset(Txbuffer, 0, ETH_TX_DESC_CNT * sizeof(ETH_BufferTypeDef));
for (q = p; q != NULL; q = q->next)
{
if (i >= ETH_TX_DESC_CNT)
{
return ERR_IF;
}
Txbuffer[i].buffer = q->payload;
Txbuffer[i].len = q->len;
framelen += q->len;
if (i > 0)
{
Txbuffer[i - 1].next = &Txbuffer[i];
}
if (q->next == NULL)
{
Txbuffer[i].next = NULL;
}
i++;
}
TxConfig.Length = framelen;
TxConfig.TxBuffer = Txbuffer;
HAL_ETH_Transmit(&EthHandle, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
return errval;
}
/**
* @brief Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *low_level_input(struct netif *netif)
{
struct pbuf *p = NULL;
ETH_BufferTypeDef RxBuff;
uint32_t framelength = 0;
struct pbuf_custom *custom_pbuf;
if (HAL_ETH_IsRxDataAvailable(&EthHandle))
{
HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff);
HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
/* Build Rx descriptor to be ready for next data reception */
HAL_ETH_BuildRxDescriptors(&EthHandle);
/* Invalidate data cache for ETH Rx Buffers */
SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff.buffer, framelength);
custom_pbuf = (struct pbuf_custom *)LWIP_MEMPOOL_ALLOC(RX_POOL);
custom_pbuf->custom_free_function = pbuf_free_custom;
p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff.buffer, ETH_RX_BUFFER_SIZE);
return p;
}
else
{
return NULL;
}
}
/**
* @brief Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
/* create a semaphore used for informing ethernetif of frame reception */
/* ethernet link list is 4 buffers, set semaphore size to 4 to not miss */
/* interrupt (1 is not working ) */
#if (osCMSIS >= 0x20000U)
s_xSemaphore = osSemaphoreNew(4, 4, NULL);
#else
osSemaphoreDef(SEM);
s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM), 4);
#endif /* osCMSIS */
/* create the task that handles the received data */
#if (osCMSIS < 0x20000U )
osThreadDef(EthIf, (os_pthread) ethernetif_task, osPriorityHigh, 0, INTERFACE_THREAD_STACK_SIZE);
ethernetif_thread_handle = osThreadCreate(osThread(EthIf), netif);
#else
ethernetif_thread_handle = osThreadNew((osThreadFunc_t)ethernetif_task, netif, &attr);
#endif /* osCMSIS */
return ERR_OK;
}
err_t ethernetif_deinit(struct netif *netif)
{
/* join will be welcome first ? */
(void) osThreadTerminate(ethernetif_thread_handle);
return ERR_OK;
}
/**
* @brief Custom Rx pbuf free callback
* @param pbuf: pbuf to be freed
* @retval None
*/
void pbuf_free_custom(struct pbuf *p)
{
struct pbuf_custom *custom_pbuf = (struct pbuf_custom *)p;
/* Invalidate data cache: lwIP and/or application may have written into buffer */
SCB_InvalidateDCache_by_Addr((uint32_t *)p->payload, p->tot_len);
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
}
/**
* @brief Returns the current time in milliseconds
* when LWIP_TIMERS == 1 and NO_SYS == 1
* @param None
* @retval Current Time value
*/
u32_t sys_now(void)
{
return HAL_GetTick();
}
/*******************************************************************************
Ethernet MSP Routines
*******************************************************************************/
/**
* @brief Initializes the ETH MSP.
* @param heth: ETH handle
* @retval None
*/
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Ethernett MSP init: RMII Mode
RX_CLK --------------> PA1
TXD0 --------------> PB12
TXD1 --------------> PB13
RXD0 --------------> PC4
RXD1 --------------> PC5
TX_EN --------------> PB11
RX_DV --------------> PA7
MDC --------------> PC1
MDIO --------------> PA2
*/
/* Enable GPIOs clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Configure PA1, PA2 , PA7 */
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PG11, PG12 and PG13 */
GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
/* Configure PC1, PC4 and PC5 */
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable the Ethernet global Interrupt */
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
/* Enable Ethernet clocks */
__HAL_RCC_ETH1MAC_CLK_ENABLE();
__HAL_RCC_ETH1TX_CLK_ENABLE();
__HAL_RCC_ETH1RX_CLK_ENABLE();
}
/**
* @brief Ethernet Rx Transfer completed callback
* @param heth: ETH handle
* @retval None
*/
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
osSemaphoreRelease(s_xSemaphore);
}
/*******************************************************************************
PHI IO Functions
*******************************************************************************/
/**
* @brief Initializes the MDIO interface GPIO and clocks.
* @param None
* @retval 0 if OK, -1 if ERROR
*/
int32_t ETH_PHY_IO_Init(void)
{
/* We assume that MDIO GPIO configuration is already done
in the ETH_MspInit() else it should be done here
*/
/* Configure the MDIO Clock */
HAL_ETH_SetMDIOClockRange(&EthHandle);
return 0;
}
/**
* @brief De-Initializes the MDIO interface .
* @param None
* @retval 0 if OK, -1 if ERROR
*/
int32_t ETH_PHY_IO_DeInit(void)
{
return 0;
}
/**
* @brief Read a PHY register through the MDIO interface.
* @param DevAddr: PHY port address
* @param RegAddr: PHY register address
* @param pRegVal: pointer to hold the register value
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
{
if (HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK)
{
return -1;
}
return 0;
}
/**
* @brief Write a value to a PHY register through the MDIO interface.
* @param DevAddr: PHY port address
* @param RegAddr: PHY register address
* @param RegVal: Value to be written
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
{
if (HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK)
{
return -1;
}
return 0;
}
/**
* @brief Get the time in millisecons used for internal PHY driver process.
* @retval Time value
*/
int32_t ETH_PHY_IO_GetTick(void)
{
return HAL_GetTick();
}
/**
* @brief
* @retval None
*/
void ethernet_link_check_state(struct netif *netif)
{
ETH_MACConfigTypeDef MACConf;
uint32_t PHYLinkState;
uint32_t linkchanged = 0;
uint32_t speed = 0;
uint32_t duplex = 0;
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if (netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
{
HAL_ETH_Stop_IT(&EthHandle);
netif_set_down(netif);
netif_set_link_down(netif);
}
else if (!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
{
switch (PHYLinkState)
{
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
default:
break;
}
if (linkchanged)
{
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
HAL_ETH_Start_IT(&EthHandle);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
}
uint8_t ethernetif_low_get_link_status(void)
{
uint8_t ret;
uint32_t PHYLinkState;
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if (PHYLinkState > LAN8742_STATUS_LINK_DOWN)
{
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
static void ethernetif_task(void *context)
{
struct netif *netif = context;
int32_t semaphore_retval;
static uint8_t link_status = 0;
if (link_status)
{
netif_set_link_up(netif);
}
else netif_set_link_down(netif);
for (;;)
{
semaphore_retval = OSSEMAPHOREWAIT(s_xSemaphore, TIME_WAITING_FOR_INPUT);
if (ethernetif_low_get_link_status() != link_status)
{
link_status = 1U - link_status;
if (link_status)
{
netif_set_link_up(netif);
}
else netif_set_link_down(netif);
}
if (semaphore_retval == (int32_t) osOK)
{
struct pbuf *p;
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p)
{
err_t err;
/* entry point to the LwIP stack */
err = netif->input(p, netif);
if (err != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
}
}
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,57 @@
/**
******************************************************************************
* @file net_conf.h
* @author MCD Application Team
* @brief This file provides the configuration for net
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONF_H
#define NET_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void ethernetif_low_init(void (*event_callback)(void), void (*buffer_output_callback)(uint8_t *));
void ethernetif_low_deinit(void);
int16_t ethernetif_low_inputsize(void);
int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
uint8_t ethernetif_low_get_link_status(void);
#define NET_USE_RTOS
#define ETHERNET_MAC_GENERATION_FROM_SHA256
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
#define USE_TINY_DTLS
#else
#define NET_MBEDTLS_HOST_SUPPORT
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
#include "net_conf_template.h"
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,835 @@
/**
******************************************************************************
* @file Ethernetif.c
* @author MCD Application Team
* @brief Implement functions called to initialize the Ethernet low level driver
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifdef STM32F429xx
#include "stm32f4xx_hal.h"
#include "stm32f4xx_ll_utils.h"
#endif /* STM32F429xx */
#ifdef STM32F769xx
#include "stm32f7xx_hal.h"
#include "stm32f7xx_ll_utils.h"
#endif /* STM32F769xx */
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip/etharp.h"
#include "net_connect.h"
#include "net_buffers.h"
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
#define USED_TINY_DTLS
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
/* Use a tinydtls hash function to generate an 'MCU-unique' MAC address */
#ifdef ETHERNET_MAC_GENERATION_FROM_SHA256
#ifdef USED_TINY_DTLS
#include "sha2/sha2.h"
#ifndef WITH_SHA256
#error "WITH_SHA256 must be enabled in the tinydtls configuration file"
#endif /* WITH_SHA256 */
#define HASH_OUTPUT_LENGTH DTLS_SHA256_DIGEST_STRING_LENGTH
#else /* USED_TINY_DTLS */
#include "mbedtls/sha256.h"
#define HASH_OUTPUT_LENGTH 32
#endif /* USED_TINY_DTLS */
#endif /* ETHERNET_MAC_GENERATION_FROM_SHA256 */
err_t ethernetif_init(struct netif *netif);
void ethernetif_deinit(struct netif *netif);
#define MAX_MTU 1500
#if (osCMSIS >= 0x20000U)
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#else
#define OSSEMAPHOREWAIT osSemaphoreWait
#endif /* osCMSIS */
/* The time to block waiting for input. */
#define TIME_WAITING_FOR_INPUT ( 250 ) /*( portMAX_DELAY )*/
/* Stack size of the interface thread */
#define INTERFACE_THREAD_STACK_SIZE 1024
/* buffer management list */
#define BUFFER_LIST_SIZE 10
#define CIRCULAR_INC(a) (a)++;if ((a)==BUFFER_LIST_SIZE) {(a)=0;}
/* Within 'USER CODE' section, code will be kept by default at each generation */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* Private function ---------------------------------------------------------*/
static void ethernetif_low_init(void);
static void ethernetif_low_deinit(void);
static void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
static uint8_t ethernetif_low_get_link_status(void);
static int16_t ethernetif_low_inputsize(void);
static int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
static int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
static int32_t ethernetif_output(void *context, net_buf_t *netbuf);
static void ethernetif_low_errhandle(void);
static void ethernetif_task(void *context);
static void ethernetif_write_done(void);
/* Private variables ---------------------------------------------------------*/
static uint8_t MACAddr[6];
/* Semaphore to signal incoming packets */
static osSemaphoreId s_xSemaphore = NULL;
static osThreadId ethernetif_thread_handle = NULL;
static __IO int32_t free_buffer_index;
static int32_t write_buffer_index;
static int32_t busy_buffer_index;
static net_buf_t *sent_write_buffer[BUFFER_LIST_SIZE];
/* Global Ethernet handle */
ETH_HandleTypeDef EthHandle;
#ifdef DATA_CACHE_ENABLED
#ifdef USE_CACHED_ETH_BUFFERS
#define SECTION_ETHERNET_BUFFERS ".ram_cache"
#else
#define SECTION_ETHERNET_BUFFERS ".sram2_non_cached_normal"
#endif /* USE_CACHED_ETH_BUFFERS */
#else
#define SECTION_ETHERNET_BUFFERS ".ram"
#endif /* DATA_CACHE_ENABLED */
#if defined ( __ICCARM__ )
#pragma data_alignment = 4
#pragma location = ".sram2_non_cached_device"
static ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
#pragma data_alignment = 4
#pragma location = ".sram2_non_cached_device"
static ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
#pragma data_alignment = 4
#pragma location = SECTION_ETHERNET_BUFFERS
static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
#pragma data_alignment = 4
#pragma location = SECTION_ETHERNET_BUFFERS
static uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
#elif defined(__CC_ARM)
ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((section(".sram2_non_cached_device"),
zero_init)); /* Ethernet Rx DMA Descriptor */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((section(".sram2_non_cached_device"),
zero_init)); /* Ethernet Tx DMA Descriptor */
uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((section(".sram2_non_cached_normal"),
zero_init)); /* Ethernet Receive Buffer */
uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((section(".sram2_non_cached_normal"),
zero_init)); /* Ethernet Transmit Buffer */
#elif defined (__GNUC__)
/* Ethernet Rx MA Descriptor */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((
section(".sram2_non_cached_device")));
/* Ethernet Tx DMA Descriptor */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((
section(".sram2_non_cached_device")));
/* Ethernet Received Buffer */
uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((
section(".sram2_non_cached_normal")));
/* Ethernet Transmit Buffer */
uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((
section(".sram2_non_cached_normal")));
#endif /* __CC_ARM */
void HAL_ETH_MspInit(ETH_HandleTypeDef *EthHandle)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Ethernet pins configuration ************************************************/
/*
RMII_REF_CLK ----------------------> PA1
RMII_MDIO -------------------------> PA2
RMII_MDC --------------------------> PC1
RMII_MII_CRS_DV -------------------> PA7
RMII_MII_RXD0 ---------------------> PC4
RMII_MII_RXD1 ---------------------> PC5
RMII_MII_RXER ---------------------> PG2
RMII_MII_TX_EN --------------------> PG11
RMII_MII_TXD0 ---------------------> PG13
RMII_MII_TXD1 ---------------------> PG14
*/
#ifdef STM32F429xx
GPIO_InitStructure.Pin = RMII_MDC_Pin | RMII_RXD0_Pin | RMII_RXD1_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = RMII_REF_CLK_Pin | RMII_MDIO_Pin | RMII_CRS_DV_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pin = RMII_TXD1_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStructure);
GPIO_InitStructure.Pin = RMII_TX_EN_Pin | RMII_TXD0_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
#endif /* STM32F429xx */
#ifdef STM32F769xx
/* Configure PA1, PA2 and PA7 */
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PC1, PC4 and PC5 */
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PG2, PG11, PG13 and PG14 */
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
#endif /* STM32F769xx */
/* Enable the Ethernet global Interrupt */
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
/* Enable ETHERNET clock */
__HAL_RCC_ETH_CLK_ENABLE();
}
void HAL_ETH_MspDeInit(ETH_HandleTypeDef *ethHandle)
{
if (ethHandle->Instance == ETH)
{
/* USER CODE BEGIN ETH_MspDeInit 0 */
/* USER CODE END ETH_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ETH_CLK_DISABLE();
/**ETH GPIO Configuration
PC1 ------> ETH_MDC
PA1 ------> ETH_REF_CLK
PA2 ------> ETH_MDIO
PA7 ------> ETH_CRS_DV
PC4 ------> ETH_RXD0
PC5 ------> ETH_RXD1
PB13 ------> ETH_TXD1
PG11 ------> ETH_TX_EN
PG13 ------> ETH_TXD0
*/
#if 0
HAL_GPIO_DeInit(GPIOC, RMII_MDC_Pin | RMII_RXD0_Pin | RMII_RXD1_Pin);
HAL_GPIO_DeInit(GPIOA, RMII_REF_CLK_Pin | RMII_MDIO_Pin | RMII_CRS_DV_Pin);
HAL_GPIO_DeInit(RMII_TXD1_GPIO_Port, RMII_TXD1_Pin);
HAL_GPIO_DeInit(GPIOG, RMII_TX_EN_Pin | RMII_TXD0_Pin);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(ETH_IRQn);
#endif /* 0 */
/* USER CODE BEGIN ETH_MspDeInit 1 */
/* USER CODE END ETH_MspDeInit 1 */
}
}
/**
* @brief Ethernet Rx Transfer completed callback
* @param EthHandle: ETH handle
* @retval None
*/
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *EthHandle)
{
(void) osSemaphoreRelease(s_xSemaphore);
}
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *EthHandle)
{
if (__HAL_ETH_DMA_GET_FLAG(EthHandle, ETH_DMASR_RBUS))
{
/* The Receive Buffer Unavailable interrupt is cleared by the Ethernet HAL handler before the
Ethernet task is scheduled.
Temporarily mask it so that the Ethernet task is scheduled before a new IT is trigged.
*/
__HAL_ETH_DMA_DISABLE_IT(EthHandle, ETH_DMA_IT_RBU);
}
}
static void ethernetif_low_init(void)
{
#ifdef PHY_ISFR
uint32_t regvalue;
#endif /* PHY_ISFR */
/* Init ETH */
EthHandle.Instance = ETH;
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
EthHandle.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x01;
/* Generate an MCU-unique MAC address */
#ifdef ETHERNET_MAC_GENERATION_FROM_SHA256
unsigned char output[HASH_OUTPUT_LENGTH];
uint32_t UID[3];
/* Generate a hash digest from the unique CPU ID */
UID[0] = LL_GetUID_Word0();
UID[1] = LL_GetUID_Word1();
UID[2] = LL_GetUID_Word2();
#ifdef USE_TINY_DTLS
/* Hash with tinydtls */
dtls_sha256_data((uint8_t *) UID, sizeof(UID), (char *) output);
#else /* USED_TINY_DTLS */
/* Hash with mbedTLS */
int32_t hash_success = 0;
mbedtls_sha256_context sha_context;
mbedtls_sha256_init(&sha_context);
if (0 == mbedtls_sha256_starts_ret(&sha_context, 0))
{
if (0 == mbedtls_sha256_update_ret(&sha_context, (const unsigned char *) UID, sizeof(UID)))
{
if (0 == mbedtls_sha256_finish_ret(&sha_context, output))
{
hash_success = 1;
}
}
}
mbedtls_sha256_free(&sha_context);
while (hash_success == 0)
{
;
}
#endif /* USE_TINY_DTLS */
/* Copy the 3 first bytes of the digest to the second half of the MAC address. */
memcpy(&MACAddr[3], output, 3);
#endif /* ETHERNET_MAC_GENERATION_FROM_SHA256 */
EthHandle.Init.MACAddr = &MACAddr[0];
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
#ifdef CHECKSUM_BY_HARDWARE
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
#else
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
#endif /* CHECKSUM_BY_HARDWARE */
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
EthHandle.Init.Speed = ETH_SPEED_100M;
EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
HAL_ETH_Init(&EthHandle);
/* Enable both the transmission and the read buffer underflow interrupts. */
__HAL_ETH_DMA_ENABLE_IT(&EthHandle, ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T | ETH_DMA_IT_AIS | ETH_DMA_IT_RBU);
/* Initialize Tx Descriptors list: Chain Mode */
HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, 0, ETH_TXBUFNB);
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
{
DMATxDscrTab[i].Buffer1Addr = 0;
}
/* Initialize Rx Descriptors list: Chain Mode */
HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
/* Enable MAC and DMA transmission and reception */
HAL_ETH_Start(&EthHandle);
/* USER CODE BEGIN PHY_PRE_CONFIG */
/* USER CODE END PHY_PRE_CONFIG */
#ifdef PHY_ISFR
/* Read Register Configuration */
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, &regvalue);
regvalue |= (PHY_ISFR_INT4);
/* Enable Interrupt on change of link status */
HAL_ETH_WritePHYRegister(&EthHandle, PHY_ISFR, regvalue);
/* Read Register Configuration */
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, &regvalue);
#endif /* PHY_ISFR */
/* USER CODE BEGIN PHY_POST_CONFIG */
/* USER CODE END PHY_POST_CONFIG */
}
static void ethernetif_low_deinit(void)
{
#ifdef PHY_ISFR
uint32_t regvalue;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, &regvalue);
regvalue &= (~PHY_ISFR_INT4);
HAL_ETH_WritePHYRegister(&EthHandle, PHY_ISFR, regvalue);
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, &regvalue);
#endif /* PHY_ISFR */
HAL_ETH_Stop(&EthHandle);
memset(&EthHandle, 0x00, sizeof(EthHandle));
memset(MACAddr, 0x00, 6);
/* return pending buffers */
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
{
if ((DMATxDscrTab[i].Buffer1Addr != 0))
{
ethernetif_write_done();
DMATxDscrTab[i].Buffer1Addr = 0;
}
}
}
static int16_t ethernetif_low_inputsize(void)
{
if (HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK)
{
ethernetif_low_errhandle();
return -1;
}
return EthHandle.RxFrameInfos.length;
}
static int16_t ethernetif_low_input(uint8_t *payload, uint16_t len)
{
__IO ETH_DMADescTypeDef *dmarxdesc;
uint32_t rlen = 0;
/* Obtain the size of the packet and put it into the "len" variable. */
rlen = EthHandle.RxFrameInfos.length;
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
if ((payload == NULL) || (len < rlen))
{
NET_DBG_INFO("LwIP pool is full or buffer is too small. Dropping an Ethernet RX frame of size %lu.\n", rlen);
}
else
{
#if defined(DATA_CACHE_ENABLE) && defined(USE_CACHED_ETH_BUFFERS)
SCB_InvalidateDCache_by_Addr((uint32_t *)dmarxdesc->Buffer1Addr, rlen);
#endif /* USE_CACHED_ETH_BUFFERS */
memcpy(payload, (uint8_t *) dmarxdesc->Buffer1Addr, rlen);
}
/* Clear Segment_Count */
NET_ASSERT(EthHandle.RxFrameInfos.SegCount == 1, " multiple segments only 1 supported\n");
EthHandle.RxFrameInfos.SegCount = 0;
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
/* ETH_DMA_IT_R and ETH_DMA_IT_RBU may be raised simultaneously.
Run the error handling.
*/
ethernetif_low_errhandle();
return rlen;
}
static void ethernetif_low_errhandle(void)
{
if (__HAL_ETH_DMA_GET_FLAG(&EthHandle, ETH_DMASR_RBUS))
{
NET_DBG_INFO("DMA underflow\n");
/* Re-enable the Receive Buffer Unavailable interrupt */
__HAL_ETH_DMA_ENABLE_IT(&EthHandle, ETH_DMA_IT_RBU);
/* Clear RBUS ETHERNET DMA flag */
__HAL_ETH_DMA_CLEAR_FLAG(&EthHandle, ETH_DMASR_RBUS);
/* Resume DMA reception */
EthHandle.Instance->DMARPDR = 0;
/* The ETH_DMA_IT_R interrupt is not raised when restarting after a Receive Buffer Unavailable.
Poll again.
*/
}
}
static int16_t ethernetif_low_output(uint8_t *payload, uint16_t len)
{
int16_t errval = 0;
__IO ETH_DMADescTypeDef *DmaTxDesc = EthHandle.TxDesc;
/* NET_DBG_PRINT ("ethernetif_low_output %d\n",len); */
/* Count number of buffer that have been sent */
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
{
if ((DMATxDscrTab[i].Buffer1Addr != 0) && !(DMATxDscrTab[i].Status & ETH_DMATXDESC_OWN))
{
CIRCULAR_INC(free_buffer_index);
DMATxDscrTab[i].Buffer1Addr = 0;
}
}
if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{
errval = -1;
goto error;
}
DmaTxDesc->Buffer1Addr = (uint32_t) payload;
#if defined(DATA_CACHE_ENABLE) && defined(USE_CACHED_ETH_BUFFERS)
SCB_CleanDCache_by_Addr(((uint32_t *)DmaTxDesc->Buffer1Addr), len + 32);
#endif /* Cache Buffers */
/* Prepare transmit descriptors to give to DMA */
if (HAL_ETH_TransmitFrame(&EthHandle, len))
{
errval = -1;
}
error:
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
{
/* Clear TUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_TUS;
/* Resume DMA transmission*/
EthHandle.Instance->DMATPDR = 0;
}
return errval;
}
static void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in)
{
MACAddr_in[0] = MACAddr[0];
MACAddr_in[1] = MACAddr[1];
MACAddr_in[2] = MACAddr[2];
MACAddr_in[3] = MACAddr[3];
MACAddr_in[4] = MACAddr[4];
MACAddr_in[5] = MACAddr[5];
}
static uint8_t ethernetif_low_get_link_status(void)
{
uint32_t phyreg;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, &phyreg);
return (uint8_t)((phyreg & PHY_LINKED_STATUS) > 0);
}
static int32_t ethernetif_output(void *context, net_buf_t *netbuf)
{
int32_t ret;
uint16_t len = 0u;
int32_t nb = 0;
net_buf_t *q;
/* release returned buffers */
while (busy_buffer_index != free_buffer_index)
{
CIRCULAR_INC(busy_buffer_index);
(void) NET_BUF_FREE(sent_write_buffer[busy_buffer_index]);
sent_write_buffer[busy_buffer_index] = 0;
}
for (q = netbuf; q != NULL ; q = q->next)
{
len += q->len;
nb++;
}
if (nb == 1)
{
NET_BUF_REF(netbuf);
CIRCULAR_INC(write_buffer_index);
sent_write_buffer[write_buffer_index] = netbuf;
ret = ethernetif_low_output(netbuf->payload, netbuf->len);
}
else
{
net_buf_t *p;
p = NET_BUF_ALLOC(len);
if (p != NULL)
{
uint8_t *pp = p->payload;
for (q = netbuf; q != NULL ; q = q->next)
{
(void) memcpy(pp, q->payload, q->len);
pp = &pp[q->len];
}
p->len = (uint16_t) len;
CIRCULAR_INC(write_buffer_index);
sent_write_buffer[write_buffer_index] = p;
ret = ethernetif_low_output(p->payload, p->len);
}
else
{
while (true) {};
}
}
return ret;
}
static void ethernetif_write_done(void)
{
CIRCULAR_INC(free_buffer_index);
}
static void ethernetif_task(void *context)
{
struct netif *netif = context;
int32_t semaphore_retval;
net_buf_t *netbuf;
uint8_t *payload;
int16_t len;
static uint8_t link_status = 0;
if (link_status)
{
netif_set_link_up(netif);
}
else netif_set_link_down(netif);
for (;;)
{
semaphore_retval = OSSEMAPHOREWAIT(s_xSemaphore, TIME_WAITING_FOR_INPUT);
if (ethernetif_low_get_link_status() != link_status)
{
link_status = 1U - link_status;
if (link_status)
{
netif_set_link_up(netif);
}
else netif_set_link_down(netif);
}
if (semaphore_retval == (int32_t) osOK)
{
/*NET_DBG_PRINT ("Wakeup Input data\n");*/
while ((len = ethernetif_low_inputsize()) > 0)
{
payload = NULL;
netbuf = NET_BUF_ALLOC((uint16_t)len);
if (netbuf != NULL)
{
payload = netbuf->payload;
}
if (ethernetif_low_input(payload, (uint16_t) len) > 0)
{
tcpip_input(netbuf, netif);
}
}
}
}
}
#if (osCMSIS >= 0x20000U )
static const osThreadAttr_t attr =
{
.name = "EthIf",
.priority = osPriorityHigh,
. stack_size = INTERFACE_THREAD_STACK_SIZE
};
#endif /* osCMSIS */
err_t ethernetif_init(struct netif *netif)
{
err_t ret = ERR_OK;
char *hostname = NET_MALLOC(sizeof(char) * ((uint16_t) NET_IP_HOSTNAME_MAX_LEN + 1U));
if (hostname == NULL)
{
return (err_t) ERR_MEM;
}
(void) snprintf(hostname, NET_IP_HOSTNAME_MAX_LEN + 1, "generic eth if #%d", netif->num);
netif->hostname = hostname;
netif->name[0] = 's';
netif->name[1] = 't';
netif->hwaddr_len = 6;
netif->mtu = MAX_MTU;
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
netif->output = etharp_output;
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
/* output to the device */
netif->linkoutput = (netif_linkoutput_fn)ethernetif_output;
free_buffer_index = 0;
write_buffer_index = 0;
busy_buffer_index = 0;
(void) memset(sent_write_buffer, 0, sizeof(sent_write_buffer));
/* create a semaphore used for informing ethernetif of frame reception */
/* ethernet link list is 4 buffers, set semaphore size to 4 to not miss */
/* interrupt (1 is not working ) */
#if (osCMSIS >= 0x20000U)
s_xSemaphore = osSemaphoreNew(4, 4, NULL);
#else
osSemaphoreDef(SEM);
s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM), 4);
#endif /* osCMSIS */
ethernetif_low_init();
ethernetif_low_get_mac_addr(netif->hwaddr);
/* create the task that handles the ETH_MAC */
#if (osCMSIS < 0x20000U )
osThreadDef(EthIf, (os_pthread) ethernetif_task, osPriorityHigh, 0, INTERFACE_THREAD_STACK_SIZE);
ethernetif_thread_handle = osThreadCreate(osThread(EthIf), netif);
#else
ethernetif_thread_handle = osThreadNew((osThreadFunc_t)ethernetif_task, netif, &attr);
#endif /* osCMSIS */
/* USER CODE BEGIN LOW_LEVEL_INIT */
/* USER CODE END LOW_LEVEL_INIT */
return ret;
}
void ethernetif_deinit(struct netif *netif)
{
while (busy_buffer_index != free_buffer_index)
{
CIRCULAR_INC(busy_buffer_index);
(void) NET_BUF_FREE(sent_write_buffer[busy_buffer_index]);
sent_write_buffer[busy_buffer_index] = 0;
}
if (netif->hostname)
{
NET_FREE((void *) netif->hostname);
netif->hostname = 0;
}
(void) osThreadTerminate(ethernetif_thread_handle);
ethernetif_thread_handle = NULL;
(void) osSemaphoreDelete(s_xSemaphore);
s_xSemaphore = NULL;
ethernetif_low_deinit();
}
#ifdef GENERATOR_AWS_CLOUD
#include "mbedtls/x509_crt.h"
/*
* Amazon Profile
*/
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
{
/* Only SHA-256 and 384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
/* Only ECDSA */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
#if defined(MBEDTLS_ECP_C)
/* Only NIST P-256 and P-384 */
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
#else
0,
#endif /* MBEDTLS_ECP_C */
2048
};
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
#endif /* GENERATOR_AWS_CLOUD */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,49 @@
/**
******************************************************************************
* @file net_conf.h
* @author MCD Application Team
* @brief This file provides the configuration for net
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONF_H
#define NET_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#define NET_USE_RTOS
#define NET_USE_HARDWARE_CHKSUM
#define ETHERNET_MAC_GENERATION_FROM_SHA256
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
#define USE_TINY_DTLS
#else
#define NET_MBEDTLS_HOST_SUPPORT
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
#include "net_conf_template.h"
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,488 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file mx_wifi_io.c
* @author MCD Application Team
* @brief This file implements the IO operations to deal with the mx_wifi
* module. It mainly Inits and Deinits the SPI/UART interface. Send and
* receive data over it.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <main.h>
#include <string.h>
#include "net_conf.h"
#include "mx_wifi.h"
#if (MX_WIFI_USE_SPI == 1)
/* Private define ------------------------------------------------------------*/
#if (osCMSIS < 0x20000U )
#define OSSEMAPHOREWAIT osSemaphoreWait
#else
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#endif /* osCMSIS */
#define SPI_READ (0xBE)
#define SPI_WRITE (0xEF)
#define MX_WIFI_RESET_MODULE() do{\
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_RESET);\
HAL_Delay(10);\
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);\
HAL_Delay(10);\
}while(0);
#define MX_WIFI_SPI_CS_ENABLE() do{ \
HAL_GPIO_WritePin( MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_RESET );\
}while(0);
#define MX_WIFI_SPI_CS_DISABLE() do{ \
HAL_GPIO_WritePin( MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_SET );\
}while(0);
/* Private variables ---------------------------------------------------------*/
static MX_WIFIObject_t MxWifiObj;
static __IO int32_t spi_slave_notify_event = 0;
static __IO int32_t spi_slave_flow_event = 0;
#if MX_WIFI_USE_CMSIS_OS
osSemaphoreId slave_notify_sem;
osSemaphoreDef(slave_notify_sem);
osSemaphoreId slave_flow_sem;
osSemaphoreDef(slave_flow_sem);
#endif /* WIFI_USE_CMSIS_OS */
/* Global variables --------------------------------------------------------*/
SPI_HandleTypeDef hspi_mx;
DMA_HandleTypeDef hdma_spi_mxc_tx;
DMA_HandleTypeDef hdma_spi_mxc_rx;
MX_WIFIObject_t *wifi_obj_get(void);
static void MX_WIFI_IO_DELAY(uint32_t ms)
{
#if MX_WIFI_USE_CMSIS_OS
osDelay(ms);
#else
HAL_Delay(ms);
#endif /* WIFI_USE_CMSIS_OS */
}
MX_WIFIObject_t *wifi_obj_get(void)
{
return &MxWifiObj;
}
/**
* @brief GPIO Initialization Function for WIFI reset IO
* @param None
* @retval None
*/
static void MX_WIFI_RESET_IO_Init(void)
{
GPIO_InitTypeDef GPIO_Init;
MX_WIFI_RESET_IO_CLK_ENABLE();
/* configure Reset pin PA4 */
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);
GPIO_Init.Pin = MX_WIFI_RESET_IO_PIN;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MX_WIFI_RESET_IO_PORT, &GPIO_Init);
}
/**
* @brief Initialize the flow, notify and software CS IO for SPI
* @param None
* @retval None
*/
static void MX_WIFI_SPI_IO_Init(void)
{
GPIO_InitTypeDef GPIO_Init;
/* GPIO Ports Clock Enable */
MX_WIFI_SPI_IO_FLOW_CLK_ENABLE();
MX_WIFI_SPI_IO_NOTIFY_CLK_ENABLE();
MX_WIFI_SPI_SW_CS_CLK_ENABLE();
/* configure slave data notify pin */
GPIO_Init.Pin = MX_WIFI_SPI_IO_NOTIFY_PIN;
GPIO_Init.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MX_WIFI_SPI_IO_NOTIFY_PORT, &GPIO_Init);
/* configure slave flow control pin */
GPIO_Init.Pin = MX_WIFI_SPI_IO_FLOW_PIN;
GPIO_Init.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MX_WIFI_SPI_IO_FLOW_PORT, &GPIO_Init);
/* Enable Interrupt for slave flow control pin , PA3 */
HAL_NVIC_SetPriority((IRQn_Type)MX_WIFI_SPI_IO_FLOW_IRQ, SPI_INTERFACE_IO_PRIO, 0x00);
HAL_NVIC_EnableIRQ((IRQn_Type)MX_WIFI_SPI_IO_FLOW_IRQ);
/* Enable Interrupt for slave Data Ready pin , PB0 */
HAL_NVIC_SetPriority((IRQn_Type)MX_WIFI_SPI_IO_NOTIFY_IRQ, SPI_INTERFACE_IO_PRIO, 0x00);
HAL_NVIC_EnableIRQ((IRQn_Type)MX_WIFI_SPI_IO_NOTIFY_IRQ);
/* SPI soft-NSS */
HAL_GPIO_WritePin(MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_RESET);
GPIO_Init.Pin = MX_WIFI_SPI_SW_CS_PIN;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MX_WIFI_SPI_SW_CS_PORT, &GPIO_Init);
}
/**
* @brief Initialize the SPI1 hardware
* @param None
* @retval None
*/
static void MX_SPI_Init(void)
{
/* SPI1 parameter configuration*/
hspi_mx.Instance = SPI1;
hspi_mx.Init.Mode = SPI_MODE_MASTER;
hspi_mx.Init.Direction = SPI_DIRECTION_2LINES;
hspi_mx.Init.DataSize = SPI_DATASIZE_8BIT;
hspi_mx.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi_mx.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi_mx.Init.NSS = SPI_NSS_SOFT;
hspi_mx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi_mx.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi_mx.Init.TIMode = SPI_TIMODE_DISABLE;
hspi_mx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi_mx.Init.CRCPolynomial = 7;
hspi_mx.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi_mx.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi_mx) != HAL_OK)
{
/*Error_Handler();*/
}
}
/**
* @brief Initialize the SPI1
* @param None
* @retval None
*/
static int8_t MX_WIFI_SPI_Init(uint16_t mode)
{
int8_t rc = 0;
MX_WIFI_RESET_IO_Init();
if (MX_WIFI_RESET == mode)
{
MX_WIFI_RESET_MODULE();
rc = 0;
}
else
{
MX_WIFI_SPI_IO_Init();
MX_SPI_Init();
#if MX_WIFI_USE_CMSIS_OS
#if (osCMSIS < 0x20000U )
slave_notify_sem = osSemaphoreCreate(osSemaphore(slave_notify_sem), 1);
slave_flow_sem = osSemaphoreCreate(osSemaphore(slave_flow_sem), 1);
#else
slave_notify_sem = osSemaphoreNew(1, 1, NULL);
slave_flow_sem = osSemaphoreNew(1, 1, NULL);
#endif /* osCMSIS < 0x20000U*/
/* take semaphore */
OSSEMAPHOREWAIT(slave_notify_sem, 1);
OSSEMAPHOREWAIT(slave_flow_sem, 1);
#endif /* WIFI_USE_CMSIS_OS */
rc = 0;
}
return rc;
}
/**
* @brief DeInitialize the SPI
* @param None
* @retval None
*/
static int8_t MX_WIFI_SPI_DeInit(void)
{
HAL_SPI_DeInit(&hspi_mx);
#ifdef WIFI_USE_CMSIS_OS
osSemaphoreDelete(slave_notify_sem);
osSemaphoreDelete(slave_flow_sem);
#endif /* WIFI_USE_CMSIS_OS */
return 0;
}
/**
* @brief SPI read/write cmd byte
*/
static int32_t wait_wifi_notify_event(int32_t timeout)
{
#ifdef WIFI_USE_CMSIS_OS
if (osOK != OSSEMAPHOREWAIT(slave_notify_sem, timeout))
{
return -1;
}
#else
int32_t tickstart = HAL_GetTick();
while (0 == spi_slave_notify_event)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
spi_slave_notify_event = 0;
#endif /* WIFI_USE_CMSIS_OS */
return 0;
}
static int32_t wait_wifi_idle(int32_t timeout)
{
#ifdef WIFI_USE_CMSIS_OS
if (osOK != OSSEMAPHOREWAIT(slave_flow_sem, timeout))
{
return -1;
}
#else
int32_t tickstart = HAL_GetTick();
while (0 == spi_slave_flow_event)
{
if ((HAL_GetTick() - tickstart) > timeout)
{
return -1;
}
}
spi_slave_flow_event = 0;
#endif /* WIFI_USE_CMSIS_OS */
return 0;
}
/**
* @brief Interrupt handler for Data RDY signal
* @param None
* @retval None
*/
void SPI_WIFI_ISR(uint16_t isr_source)
{
if (MX_WIFI_SPI_IO_NOTIFY_PIN == isr_source)
{
#ifdef WIFI_USE_CMSIS_OS
osSemaphoreRelease(slave_notify_sem);
#else
spi_slave_notify_event = 1;
#endif /* WIFI_USE_CMSIS_OS */
}
else if (MX_WIFI_SPI_IO_FLOW_PIN == isr_source)
{
#ifdef WIFI_USE_CMSIS_OS
osSemaphoreRelease(slave_flow_sem);
#else
spi_slave_flow_event = 1;
#endif /* WIFI_USE_CMSIS_OS */
}
else
{
}
}
/**
* @brief Recv wifi Data thru SPI
* @param pdata : pointer to data
* @param len : Data length
* @param timeout : send timeout in mS
* @retval Length of recved data
*/
int16_t MX_WIFI_SPI_ReceiveData(uint8_t *pdata, uint16_t len, uint32_t timeout_ms)
{
int16_t rc = -1;
uint8_t type = SPI_READ;
uint16_t read_len = 0;
MX_WIFI_SPI_CS_ENABLE();
if (wait_wifi_notify_event(timeout_ms) < 0)
{
/*DEBUG_LOG("DEBUG: spi recv: wait wifi data timeout.\r\n");*/
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (HAL_SPI_Transmit(&hspi_mx, &type, 1, 5) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi recv: send READ(1) error !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms + 10) < 0)
{
DEBUG_LOG("** ERROR: spi recv: wait READ ack timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
DEBUG_LOG("spi READ cmd ok.\r\n");
if (HAL_SPI_Receive(&hspi_mx, (uint8_t *)&read_len, 2, 10) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi recv: recv READ_LEN(2) error !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms + 10) < 0)
{
DEBUG_LOG("** ERROR: spi recv: wait READ len ack timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
read_len = (read_len > len) ? len : read_len;
DEBUG_LOG("spi READ len(%d) ok.\r\n", read_len);
if (HAL_SPI_Receive(&hspi_mx, pdata, read_len, 200) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi recv: recv DATA(%d) error !\r\n", read_len);
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms + 100) < 0)
{
DEBUG_LOG("** ERROR: spi recv: wait DATA ack timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
DEBUG_LOG("spi READ data(%d) ok.\r\n", read_len);
rc = read_len;
error_exit:
MX_WIFI_SPI_CS_DISABLE();
return rc;
}
/**
* @brief Send wifi Data thru SPI
* @param pdata : pointer to data
* @param len : Data length
* @param timeout : send timeout in mS
* @retval Length of sent data
*/
static int16_t MX_WIFI_SPI_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout_ms)
{
int16_t rc = -1;
uint8_t type = SPI_WRITE;
uint16_t send_len = len;
MX_WIFI_SPI_CS_ENABLE();
#ifdef WIFI_USE_CMSIS_OS
OSSEMAPHOREWAIT(slave_flow_sem, 1);
OSSEMAPHOREWAIT(slave_notify_sem, 1);
#else
spi_slave_notify_event = 0;
spi_slave_flow_event = 0;
#endif /* WIFI_USE_CMSIS_OS */
if (HAL_SPI_Transmit(&hspi_mx, (uint8_t *)&type, 1, 5) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi send: send WRITE(1) error !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms) < 0)
{
DEBUG_LOG("** ERROR: spi send: wait WRITE ACK timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
DEBUG_LOG("spi WRITE cmd ok.\r\n");
if (HAL_SPI_Transmit(&hspi_mx, (uint8_t *)&send_len, 2, 10) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi send: send WRITE_LEN(2) error !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms) < 0)
{
DEBUG_LOG("** ERROR: spi send: wait WRITE_LEN ACK timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
DEBUG_LOG("spi WRITE len(%d) ok.\r\n", send_len);
if (HAL_SPI_Transmit(&hspi_mx, pdata, send_len, 200) != HAL_OK)
{
DEBUG_LOG("** ERROR: spi send: send DATA(%d) error !\r\n", send_len);
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
if (wait_wifi_idle(timeout_ms + 100) < 0)
{
DEBUG_LOG("** ERROR: spi send: wait DATA ACK timeout !\r\n");
rc = MX_WIFI_STATUS_IO_ERROR;
goto error_exit;
}
DEBUG_LOG("spi WRITE data(%d) ok.\r\n", send_len);
rc = send_len;
error_exit:
MX_WIFI_SPI_CS_DISABLE();
return rc;
}
/**
* @brief probe function to register wifi to connectivity framwotk
* @param None
* @retval None
*/
int32_t wifi_probe(void **ll_drv_context)
{
if (MX_WIFI_RegisterBusIO(&MxWifiObj,
MX_WIFI_SPI_Init,
MX_WIFI_SPI_DeInit,
MX_WIFI_IO_DELAY,
MX_WIFI_SPI_SendData,
MX_WIFI_SPI_ReceiveData) == 0)
{
*ll_drv_context = &MxWifiObj;
return 0;
}
return -1;
}
#endif /* (MX_WIFI_USE_SPI == 1) */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,408 @@
/**
******************************************************************************
* @file mx_wifi_io.c
* @author MCD Application Team
* @brief This file implements the IO operations to deal with the mx_wifi
* module. It mainly Inits and Deinits the UART interface. Send and
* receive data over it.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/*****************************************************************************
* this file can be copy and renamed as net_conf.c or use directly from its
* orginal location STM32_Network_lib/templates. There is no need to chnage it.
*
* It performs the connection between the mxchip BSP driver and the UART
*
* Expectaction is that UART pins labels are defined in main.h (when using
* CUbeMX) or in net_conf.h.
*
* function HAL_UART_MspInit(UART_HandleTypeDef* huart) in file
* stm32xxxx_hal_msp.c must performed the init of the selected UART interface
* This function can be manualy written or generated by cubeMX
*
* UART parameter init is done in this file in a redundant way from
* the HAL_UART_MspInit function.CubeMX user does not have to know the exact
* configuratino of the UART , but only the pin out connections.
*
* When interrupt are used (NET_USE_RTOS) , the function MXchip_UART_RxCpltCallback
* must be called from HAL_UART_RxCpltCallback located in main.c. A dedicated
* IRQHandler must be added to the file stm32xxx_it.C to call the HAL_UART_IRQHandler
*
* the function MX_WIFI_RESET_IO_Initconfigure the reset pins. It should be generated by
* CubeMX et being located in main.c
*/
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
#include <main.h>
#include <string.h>
#include "net_conf.h"
#include "mx_wifi.h"
#if (MX_WIFI_USE_SPI == 0)
/* Private define ------------------------------------------------------------*/
#if (osCMSIS < 0x20000U )
#define OSSEMAPHOREWAIT osSemaphoreWait
#else
#define OSSEMAPHOREWAIT osSemaphoreAcquire
#endif /* osCMSIS */
#define MX_WIFI_RESET_MODULE() do{\
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_RESET);\
HAL_Delay(10);\
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);\
HAL_Delay(10);\
}while(0);
#if MX_WIFI_USE_UART_INTERRUPT
#define RING_BUFFER_SIZE (MX_WIFI_DATA_SIZE + 500)
typedef struct
{
uint8_t data[RING_BUFFER_SIZE];
__IO uint16_t tail;
__IO uint16_t head;
} RingBuffer_t;
#endif /* MX_WIFI_USE_UART_INTERRUPT */
MX_WIFIObject_t *wifi_obj_get(void);
UART_HandleTypeDef mx_uart;
static MX_WIFIObject_t MxWifiObj;
#if MX_WIFI_USE_UART_INTERRUPT
__IO RingBuffer_t WiFiRxBuffer;
#endif /* MX_WIFI_USE_UART_INTERRUPT */
#ifdef NET_USE_RTOS
osSemaphoreId wifi_uart_rx_sem;
osSemaphoreDef(wifi_uart_rx_sem);
#endif /* NET_USE_RTOS */
/* Private variables ---------------------------------------------------------*/
MX_WIFIObject_t *wifi_obj_get(void)
{
return &MxWifiObj;
}
static void MX_WIFI_IO_DELAY(uint32_t ms)
{
#if MX_WIFI_USE_CMSIS_OS
osDelay(ms);
#else
HAL_Delay(ms);
#endif /* MX_WIFI_USE_CMSIS_OS */
}
/**
* @brief GPIO Initialization Function for WIFI reset IO
* @param None
* @retval None
*/
static void MX_WIFI_RESET_IO_Init(void)
{
GPIO_InitTypeDef GPIO_Init;
MX_WIFI_RESET_IO_CLK_ENABLE();
/* configure Reset pin for Mxchip */
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);
GPIO_Init.Pin = MX_WIFI_RESET_IO_PIN;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MX_WIFI_RESET_IO_PORT, &GPIO_Init);
}
#ifdef NET_MXCHIP_LOCAL_MSP
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (huart->Instance == USARTmxc)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USARTmxc_TX_GPIO_CLK_ENABLE();
USARTmxc_RX_GPIO_CLK_ENABLE();
/* Enable USARTx clock */
USARTmxc_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTmxc_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = USARTmxc_TX_AF;
HAL_GPIO_Init(USARTmxc_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTmxc_RX_PIN;
GPIO_InitStruct.Alternate = USARTmxc_RX_AF;
HAL_GPIO_Init(USARTmxc_RX_GPIO_PORT, &GPIO_InitStruct);
}
}
/**
* @brief UART MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
if (huart->Instance == USARTmxc)
{
USARTmxc_FORCE_RESET();
USARTmxc_RELEASE_RESET();
USARTmxc_CLK_DISABLE();
/*##-2- Disable peripherals and GPIO Clocks ################################*/
/* Configure UART Tx as alternate function */
HAL_GPIO_DeInit(USARTmxc_TX_GPIO_PORT, USARTmxc_TX_PIN);
/* Configure UART Rx as alternate function */
HAL_GPIO_DeInit(USARTmxc_RX_GPIO_PORT, USARTmxc_RX_PIN);
}
}
#endif /* NET_MXCHIP_LOCAL_MSP */
/**
* @brief Initialize the UART
* @param None
* @retval None
*/
static int8_t MX_WIFI_UART_Init(uint16_t mode)
{
int8_t rc = 0;
MX_WIFI_RESET_IO_Init();
if (MX_WIFI_RESET == mode)
{
MX_WIFI_RESET_MODULE();
}
else
{
/* Configurate the UART to correct speed */
mx_uart.Instance = USARTmxc;
mx_uart.Init.BaudRate = MX_WIFI_UART_BAUDRATE;
mx_uart.Init.WordLength = UART_WORDLENGTH_8B;
mx_uart.Init.StopBits = UART_STOPBITS_1;
mx_uart.Init.Parity = UART_PARITY_NONE;
mx_uart.Init.Mode = UART_MODE_TX_RX;
mx_uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
mx_uart.Init.OverSampling = UART_OVERSAMPLING_16;
mx_uart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
#ifdef UART_PRESCALER_DIV1
mx_uart.Init.ClockPrescaler = UART_PRESCALER_DIV1;
#endif /* UART_PRESCALER_DIV1 */
mx_uart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&mx_uart) != HAL_OK)
{
while (1);
}
#if MX_WIFI_USE_UART_INTERRUPT
WiFiRxBuffer.head = 0;
WiFiRxBuffer.tail = 0;
#endif /* MX_WIFI_USE_UART_INTERRUPT */
#ifdef NET_USE_RTOS
#if (osCMSIS < 0x20000U )
wifi_uart_rx_sem = osSemaphoreCreate(osSemaphore(wifi_uart_rx_sem), 1);
#else
wifi_uart_rx_sem = osSemaphoreNew(1, 1, NULL);
#endif /* osCMSIS */
OSSEMAPHOREWAIT(wifi_uart_rx_sem, 1);
HAL_NVIC_SetPriority(UARTmxc_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
#else
HAL_NVIC_SetPriority(UARTmxc_IRQn, 16, 0);
#endif /* NET_USE_RTOS */
HAL_NVIC_EnableIRQ(UARTmxc_IRQn);
#if MX_WIFI_USE_UART_INTERRUPT
HAL_UART_Receive_IT(&mx_uart, (uint8_t *)&WiFiRxBuffer.data[WiFiRxBuffer.tail], 1);
#endif /* MX_WIFI_USE_UART_INTERRUPT */
}
return rc;
}
/**
* @brief Deinitialize the UART
* @param None
* @retval None
*/
static int8_t MX_WIFI_UART_DeInit(void)
{
int8_t rc = 0;
if (HAL_UART_DeInit(&mx_uart) != HAL_OK)
{
while (1);
}
#ifdef NET_USE_RTOS
osSemaphoreDelete(wifi_uart_rx_sem);
#endif /* NET_USE_RTOS */
return rc;
}
#if MX_WIFI_USE_UART_INTERRUPT
/**
* @brief Rx Callback when new data is received on the UART.
* @param UartHandle: Uart handle receiving the data.
* @retval None.
*/
void MXchip_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle);
void MXchip_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint32_t tail;
/* WIFI UART */
/* If ring buffer end is reached reset tail pointer to start of buffer */
if (++WiFiRxBuffer.tail >= RING_BUFFER_SIZE)
{
WiFiRxBuffer.tail = 0;
}
/* ringbuffer full, overlap head */
tail = WiFiRxBuffer.tail;
if (tail == WiFiRxBuffer.head)
{
WiFiRxBuffer.head++;
}
// fired next reception
HAL_UART_Receive_IT(UartHandle, (uint8_t *)&WiFiRxBuffer.data[WiFiRxBuffer.tail], 1);
#ifdef NET_USE_RTOS
osSemaphoreRelease(wifi_uart_rx_sem);
#endif /* NET_USE_RTOS */
}
#endif /* MX_WIFI_USE_UART_INTERRUPT */
/**
* @brief Send wifi Data thru UART
* @param pdata : pointer to data
* @param len : Data length
* @param timeout : send timeout in mS
* @retval Length of sent data
*/
static int16_t MX_WIFI_UART_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout)
{
int16_t rc = 0;
if (HAL_UART_Transmit(&mx_uart, pdata, len, timeout) != HAL_OK)
{
return MX_WIFI_STATUS_IO_ERROR;
}
rc = len;
/*DEBUG_LOG("MX_WIFI_TX: %d bytes, [%.*s]\r\n", len, len, pdata);*/
return rc;
}
static int16_t MX_WIFI_UART_ReceiveData(uint8_t *pdata, uint16_t request_len, uint32_t timeout)
{
int16_t len = 0;
#if MX_WIFI_USE_UART_INTERRUPT==0
len = request_len;
if (HAL_UART_Receive(&mx_uart, pdata, len, timeout) != HAL_OK)
{
return MX_WIFI_STATUS_IO_ERROR;
}
/*DEBUG_LOG("MX_WIFI_RX: %d bytes, [%.*s]\r\n", len, len, pdata);*/
#else
int32_t tail;
#ifdef NET_USE_RTOS
OSSEMAPHOREWAIT(wifi_uart_rx_sem, 1);
#endif /* NET_USE_RTOS */
tail = WiFiRxBuffer.tail;
len = ((RING_BUFFER_SIZE + tail - WiFiRxBuffer.head) % RING_BUFFER_SIZE);
if (len == 0)
{
return 0;
}
if (len > request_len)
{
len = request_len;
}
/*copy from buffer */
for (uint32_t i = 0; i < len; i++)
{
*pdata++ = WiFiRxBuffer.data[WiFiRxBuffer.head++];
if (WiFiRxBuffer.head >= RING_BUFFER_SIZE)
{
/* wrap */
WiFiRxBuffer.head = 0;
}
}
#endif /* MX_WIFI_USE_UART_INTERRUPT */
return len;
}
/**
* @brief probe function to register wifi to connectivity framwotk
* @param None
* @retval None
*/
int32_t wifi_probe(void **ll_drv_context)
{
if (MX_WIFI_RegisterBusIO(&MxWifiObj,
MX_WIFI_UART_Init,
MX_WIFI_UART_DeInit,
MX_WIFI_IO_DELAY,
MX_WIFI_UART_SendData,
MX_WIFI_UART_ReceiveData) == 0)
{
*ll_drv_context = &MxWifiObj;
return 0;
}
return -1;
}
#endif /* MX_WIFI_USE_SPI */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,66 @@
/**
******************************************************************************
* @file net_conf.h
* @author MCD Application Team
* @brief This file provides the configuration for net
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#ifndef NET_CONF_H
#define NET_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/*#define NET_MBEDTLS_HOST_SUPPORT*/
#define NET_DBG_INFO(...)
#define NET_DBG_ERROR(...)
#define NET_DBG_PRINT(...)
#define NET_ASSERT(a,b) do { } while((a)==false)
#define NET_PRINT(...)
#define NET_PRINT_WO_CR(...)
#define NET_WARNING(...)
#define NET_USE_LWIP_DEFINITIONS
#define NET_ALLOC_BREAK 0xFFFFFFFFU
/*#define NET_ALLOC_DEBUG*/
#define NET_BYPASS_NET_SOCKET
#include <stdint.h>
void ethernetif_low_init(void (*event_callback)(void), void (*buffer_output_callback)(uint8_t *));
void ethernetif_low_deinit(void);
int16_t ethernetif_low_inputsize(void);
int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
uint8_t ethernetif_low_get_link_status(void);
#define NET_USE_RTOS
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
/*#define NET_MBEDTLS_HOST_SUPPORT*/
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
/*cstat -MISRAC2012-Rule-20.1 */
#include "net_conf_template.h"
/*cstat +MISRAC2012-Rule-20.1 */
#ifdef __cplusplus
}
#endif
#endif /* NET_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/