| /* |
| * Copyright (c) 2019 Tobias Svehagen |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_DRIVERS_WIFI_ESP_H_ |
| #define ZEPHYR_INCLUDE_DRIVERS_WIFI_ESP_H_ |
| |
| #include <kernel.h> |
| #include <net/net_context.h> |
| #include <net/net_if.h> |
| #include <net/net_ip.h> |
| #include <net/net_pkt.h> |
| #include <net/wifi_mgmt.h> |
| |
| #include "modem_context.h" |
| #include "modem_cmd_handler.h" |
| #include "modem_iface_uart.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* Define the commands that differ between the AT versions */ |
| #if defined(CONFIG_WIFI_ESP_AT_VERSION_1_7) |
| #define _CWMODE "CWMODE_CUR" |
| #define _CWSAP "CWSAP_CUR" |
| #define _CWJAP "CWJAP_CUR" |
| #define _CIPSTA "CIPSTA_CUR" |
| #define _CIPSTAMAC "CIPSTAMAC_CUR" |
| #else |
| #define _CWMODE "CWMODE" |
| #define _CWSAP "CWSAP" |
| #define _CWJAP "CWJAP" |
| #define _CIPSTA "CIPSTA" |
| #define _CIPSTAMAC "CIPSTAMAC" |
| #endif |
| |
| #define ESP_BUS DT_BUS(DT_DRV_INST(0)) |
| |
| #if DT_PROP(ESP_BUS, hw_flow_control) == 1 |
| #define _FLOW_CONTROL "3" |
| #else |
| #define _FLOW_CONTROL "0" |
| #endif |
| |
| #define _UART_CUR \ |
| STRINGIFY(DT_PROP(ESP_BUS, current_speed))",8,1,0,"_FLOW_CONTROL |
| |
| #define CONN_CMD_MAX_LEN (sizeof("AT+"_CWJAP"=\"\",\"\"") + \ |
| WIFI_SSID_MAX_LEN + WIFI_PSK_MAX_LEN) |
| |
| #define ESP_MAX_SOCKETS 5 |
| |
| /* Maximum amount that can be sent with CIPSEND and read with CIPRECVDATA */ |
| #define ESP_MTU 2048 |
| #define CIPRECVDATA_MAX_LEN ESP_MTU |
| |
| #define INVALID_LINK_ID 255 |
| |
| #define MDM_RING_BUF_SIZE 1024 |
| #define MDM_RECV_MAX_BUF 30 |
| #define MDM_RECV_BUF_SIZE 128 |
| #define CMD_BUF_ALLOC_TIMEOUT K_SECONDS(1) |
| |
| #define ESP_CMD_TIMEOUT K_SECONDS(10) |
| #define ESP_SCAN_TIMEOUT K_SECONDS(10) |
| #define ESP_CONNECT_TIMEOUT K_SECONDS(20) |
| #define ESP_INIT_TIMEOUT K_SECONDS(10) |
| |
| extern struct esp_data esp_driver_data; |
| |
| enum esp_socket_flags { |
| ESP_SOCK_IN_USE = BIT(1), |
| ESP_SOCK_CONNECTING = BIT(2), |
| ESP_SOCK_CONNECTED = BIT(3) |
| }; |
| |
| struct esp_socket { |
| /* internal */ |
| u8_t idx; |
| u8_t link_id; |
| u8_t flags; |
| |
| /* socket info */ |
| sa_family_t family; |
| enum net_sock_type type; |
| enum net_ip_protocol ip_proto; |
| struct sockaddr src; |
| struct sockaddr dst; |
| |
| /* for +CIPRECVDATA */ |
| size_t bytes_avail; |
| |
| /* packets */ |
| struct k_fifo fifo_rx_pkt; |
| struct net_pkt *tx_pkt; |
| |
| /* sem */ |
| struct k_sem sem_data_ready; |
| |
| /* work */ |
| struct k_work connect_work; |
| struct k_work send_work; |
| struct k_work recv_work; |
| struct k_work recvdata_work; |
| |
| /* net context */ |
| struct net_context *context; |
| net_context_connect_cb_t connect_cb; |
| net_context_send_cb_t send_cb; |
| net_context_recv_cb_t recv_cb; |
| |
| /* callback data */ |
| void *conn_user_data; |
| void *send_user_data; |
| void *recv_user_data; |
| }; |
| |
| enum esp_data_flag { |
| EDF_STA_CONNECTING = BIT(1), |
| EDF_STA_CONNECTED = BIT(2) |
| }; |
| |
| /* driver data */ |
| struct esp_data { |
| struct net_if *net_iface; |
| |
| u8_t flags; |
| |
| char conn_cmd[CONN_CMD_MAX_LEN]; |
| |
| /* addresses */ |
| struct in_addr ip; |
| struct in_addr gw; |
| struct in_addr nm; |
| u8_t mac_addr[6]; |
| |
| /* modem context */ |
| struct modem_context mctx; |
| |
| /* modem interface */ |
| struct modem_iface_uart_data iface_data; |
| u8_t iface_isr_buf[MDM_RECV_BUF_SIZE]; |
| u8_t iface_rb_buf[MDM_RING_BUF_SIZE]; |
| |
| /* modem cmds */ |
| struct modem_cmd_handler_data cmd_handler_data; |
| u8_t cmd_read_buf[MDM_RECV_BUF_SIZE]; |
| u8_t cmd_match_buf[MDM_RECV_BUF_SIZE]; |
| |
| /* socket data */ |
| struct esp_socket sockets[ESP_MAX_SOCKETS]; |
| struct esp_socket *rx_sock; |
| |
| /* work */ |
| struct k_work_q workq; |
| struct k_work init_work; |
| struct k_delayed_work ip_addr_work; |
| struct k_work scan_work; |
| struct k_work connect_work; |
| |
| scan_result_cb_t scan_cb; |
| |
| /* response semaphore */ |
| struct k_sem sem_tx_ready; |
| struct k_sem sem_response; |
| struct k_sem sem_if_up; |
| }; |
| |
| int esp_offload_init(struct net_if *iface); |
| |
| struct net_pkt *esp_prepare_pkt(struct esp_data *dev, struct net_buf *src, |
| size_t offset, size_t len); |
| struct esp_socket *esp_socket_get(); |
| int esp_socket_put(struct esp_socket *sock); |
| struct esp_socket *esp_socket_from_link_id(struct esp_data *data, |
| u8_t link_id); |
| void esp_socket_init(struct esp_data *data); |
| |
| static inline struct esp_data *esp_socket_to_dev(struct esp_socket *sock) |
| { |
| return CONTAINER_OF(sock - sock->idx, struct esp_data, sockets); |
| } |
| |
| static inline bool esp_socket_in_use(struct esp_socket *sock) |
| { |
| return (sock->flags & ESP_SOCK_IN_USE) != 0; |
| } |
| |
| static inline bool esp_socket_connected(struct esp_socket *sock) |
| { |
| return (sock->flags & ESP_SOCK_CONNECTED) != 0; |
| } |
| |
| static inline void esp_flag_set(struct esp_data *dev, |
| enum esp_data_flag flag) |
| { |
| dev->flags |= flag; |
| } |
| |
| static inline void esp_flag_clear(struct esp_data *dev, |
| enum esp_data_flag flag) |
| { |
| dev->flags &= (~flag); |
| } |
| |
| static inline bool esp_flag_is_set(struct esp_data *dev, |
| enum esp_data_flag flag) |
| { |
| return (dev->flags & flag) != 0; |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ZEPHYR_INCLUDE_DRIVERS_WIFI_ESP_H_ */ |