From e14dd1ab283b523813536b4d91640f8c77a5e3a2 Mon Sep 17 00:00:00 2001 From: "Morgan 'ARR\\!' Allen" Date: Thu, 28 Dec 2023 18:14:40 -0800 Subject: [PATCH] first pass and mostly working --- CMakeLists.txt | 7 ++ README.md | 45 ++++++++++++ include/esp_netif_now.h | 14 ++++ main/esp_netif_now.c | 155 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 include/esp_netif_now.h create mode 100644 main/esp_netif_now.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ac55e8e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +idf_component_register(SRCS + "main/esp_netif_now.c" + + REQUIRES esp_netif esp_wifi + + INCLUDE_DIRS "include" +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..482306e --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# `esp_netif_now` + +An ESP-NETIF driver for ESP-Now + +# usage +Installing this on two devices with LwIP debugging turned up and you will see packets being exchanged. + +This could also be the basis for using any other system that is capable of using LwIP. + +Install with +``` +git clone https://git.oit.cloud/morgan/esp_netif_now/ components/esp_netif_now +``` + +## complete example +``` +#include "esp_mac.h" +#include "esp_wifi.h" + +#include "nvs_flash.h" + +#include "esp_netif_now.h" + +void app_main() { + esp_netif_now_config_t config; + + esp_efuse_mac_get_default((uint8_t*)&config.mac); + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE)); + + esp_netif_set_ip4_addr(&config.ip_info.ip, 10, 10 , 0, config.mac[5]); + esp_netif_set_ip4_addr(&config.ip_info.gw, 10, 10 , 0, 1); + esp_netif_set_ip4_addr(&config.ip_info.netmask, 255, 255 , 255, 0); + + esp_netif_now_init(&config); +} +``` diff --git a/include/esp_netif_now.h b/include/esp_netif_now.h new file mode 100644 index 0000000..e76f3d4 --- /dev/null +++ b/include/esp_netif_now.h @@ -0,0 +1,14 @@ +#ifndef __ESP_NETIF_NOW_H__ +#define __ESP_NETIF_NOW_H__ + +#include "esp_netif.h" +#include "esp_now.h" + +typedef struct esp_netif_now_config_t { + uint8_t mac[6]; + esp_netif_ip_info_t ip_info; +} esp_netif_now_config_t; + +esp_err_t esp_netif_now_init(esp_netif_now_config_t *netif_now_config); + +#endif diff --git a/main/esp_netif_now.c b/main/esp_netif_now.c new file mode 100644 index 0000000..7741c85 --- /dev/null +++ b/main/esp_netif_now.c @@ -0,0 +1,155 @@ +#include "esp_log.h" +#include "esp_mac.h" +#include "esp_netif.h" +#include "esp_wifi.h" + +#include "lwip/netdb.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" + +#include "esp_netif_now.h" + +#define TAG "esp_netif_now" + +static uint8_t broadcast_addr[ESP_NOW_ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +esp_netif_t* netif; +void esp_netif_now_io_free_rx_buffer(void *h, void *buffer); +static esp_err_t esp_netif_now_io_transmit(void *h, void *buffer, size_t len); +static esp_err_t esp_netif_now_io_transmit_wrap(void *h, void *buffer, size_t len, void *netstack_buf); +static esp_err_t esp_netif_now_io_attach(esp_netif_t * esp_netif, void * args); + +const esp_netif_driver_ifconfig_t esp_netif_now_ifconfig = { + .driver_free_rx_buffer = esp_netif_now_io_free_rx_buffer, + .transmit = esp_netif_now_io_transmit, + .transmit_wrap = esp_netif_now_io_transmit_wrap, + .handle = "esp-netif-now" +}; + +const esp_netif_driver_base_t esp_netif_now_driver_base = { + .post_attach = esp_netif_now_io_attach +}; + +void esp_netif_now_io_free_rx_buffer(void *h, void *buffer) { + // TODO +} + +esp_err_t esp_netif_now_add_peer(uint8_t *mac) { + esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t)); + if (peer == NULL) { + return -1; + } + + memset(peer, 0, sizeof(esp_now_peer_info_t)); + peer->channel = 1; + peer->ifidx = ESP_IF_WIFI_STA; + memcpy(peer->peer_addr, mac, ESP_NOW_ETH_ALEN); + + // check for some conditions + esp_err_t ret = esp_now_add_peer(peer); + + free(peer); + + return ret; +} + +static esp_err_t esp_netif_now_io_transmit(void *h, void *buffer, size_t len) { + uint8_t *buf = buffer; + + uint8_t peer[6]; + memcpy(&peer, buf, 6); + + ESP_LOGI(TAG, "sending %d bytes to: %02X:%02X:%02X:%02X:%02X:%02X", len, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]); + for(uint8_t i = 0; i < len; i++) { + printf("0x%02X ", buf[i]); + if(i % 16 == 15) printf("\n"); + } + printf("\n"); + + esp_err_t ret = ESP_OK; + + ret = esp_now_send(peer, buffer, len); + + if(ret == ESP_ERR_ESPNOW_NOT_FOUND) { + ESP_LOGE("esp-netif-now", "ESP-Now peer not found"); + } else if(ret == ESP_ERR_ESPNOW_INTERNAL) { + ESP_LOGE("esp-netif-now", "ESP-Now experienced an internal error"); + } else if(ret != ESP_OK) { + ESP_ERROR_CHECK(ret); + } + + return ret; +} + +static esp_err_t esp_netif_now_io_transmit_wrap(void *h, void *buffer, size_t len, void *netstack_buf) { + return esp_netif_now_io_transmit(h, buffer, len); +} + +static esp_err_t esp_netif_now_io_attach(esp_netif_t * esp_netif, void * args) { + ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &esp_netif_now_ifconfig)); + + return ESP_OK; +} + +void * esp_netif_now_new_handler(void) { + return (void*)&esp_netif_now_driver_base; +} + +static void esp_netif_now_recv_cb(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len) { + // TODO + // * Handle MAC related, peering, broadcast, etc + // * Pipe received data into LwIP + + uint8_t peer[6]; + memcpy(&peer, recv_info->src_addr, 6); + + ESP_LOGI(TAG, "receiving %d bytes from: %02X:%02X:%02X:%02X:%02X:%02X", len, peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]); + + esp_netif_now_add_peer((uint8_t*)&peer); + + for(uint8_t i = 0; i < len; i++) { + printf("0x%02X ", data[i]); + if(i % 16 == 15) printf("\n"); + } + + printf("\n"); + + esp_netif_receive(netif, (void*)data, len, NULL); +} + +static void esp_netif_now_send_cb(const uint8_t *mac_addr, esp_now_send_status_t status) { + // TODO free any memory allocated during io_transmit +} + + +esp_err_t esp_netif_now_init(esp_netif_now_config_t *netif_now_config) { + esp_netif_inherent_config_t netif_common_config = { + .flags = ESP_NETIF_FLAG_AUTOUP, + .ip_info = &netif_now_config->ip_info, + .if_key = "TEST", + .if_desc = "net_test_if" + }; + + esp_netif_config_t config = { + .base = &netif_common_config, // use specific behaviour configuration + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, // use default WIFI-like network stack configuration + }; + + ESP_LOGI(TAG, "esp_now_init()"); + ESP_ERROR_CHECK(esp_now_init()); + ESP_ERROR_CHECK(esp_now_register_recv_cb(esp_netif_now_recv_cb)); + ESP_ERROR_CHECK(esp_now_register_send_cb(esp_netif_now_send_cb)); + esp_netif_now_add_peer(broadcast_addr); + + // Netif creation and configuration + // + netif = esp_netif_new(&config); + + esp_netif_attach(netif, esp_netif_now_new_handler()); + + // Start the netif in a manual way, no need for events + // + esp_netif_set_mac(netif, netif_now_config->mac); + esp_netif_action_start(netif, NULL, 0, NULL); + + return ESP_OK; +}