espressif / esp-idf-cxx

C++ wrapper classes for ESP-IDF components.
Apache License 2.0
79 stars 14 forks source link

Add of the new parts of the esp-idf library (netif, nvs_flash, wifi, adc) #32

Open safocl opened 22 hours ago

safocl commented 22 hours ago

Checklist

Feature description

I propose a possible variant of additional components in the C++ wrapper (esp-idf-cxx). Please indicate -- in what form would it be possible to add this to your library?

https://github.com/safocl/ext-esp32-idf-cxx-test

this is just a rough draft (I am currently using some of the functionality myself)

Use cases

Using networking, wifi, adc, nvsflash in C++ code style. (-std=c++23)_

#include <esp_netif.h>
#include <esp_netif_ip_addr.h>
#include <esp_netif_types.h>
#include <esp_event_cxx.hpp>

#include "connect.hpp"
#include "netif.hpp"
#include "oscilloscopeLib.hpp"
#include "wifi.hpp"

#include <algorithm>
#include <memory>
#include <print>
#include <stdexcept>
#include <string_view>
#include <vector>

core::NetIfHandler wifiIfHandler {};

idf::event::ESPEventLoop loop {};

using Connect::Wifi;

std::vector< std::unique_ptr< idf::event::ESPEventReg > > eventregs;

extern "C" int app_main() {
    try {
        wifi_pmf_config_t pfm {};
        pfm.required = true;

        constexpr std::string_view ssid( "esp32osc" );
        constexpr std::string_view passwd( "esp32osc" );

        wifi_ap_config_t apConf {};
        std::ranges::copy( ssid, &apConf.ssid[ 0 ] );
        std::ranges::copy( passwd, &apConf.password[ 0 ] );
        apConf.channel        = 5;
        apConf.authmode       = wifi_auth_mode_t::WIFI_AUTH_WPA2_PSK;
        apConf.max_connection = 5;
        apConf.pmf_cfg        = pfm;

        wifi_config_t cfg = { .ap = apConf };
        wifiIfHandler     = Wifi::createDefaultWithHandler< Connect::ApProvider >( cfg, Wifi::Storage::eRam );

        if ( !bool( wifiIfHandler.getFlags() & ESP_NETIF_DHCP_SERVER ) )
            throw std::runtime_error( "DHCP flag not selected.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );

        eventregs.push_back(
        loop.register_event( idf::event::ESPEvent( IP_EVENT, idf::event::ESPEventID( ESP_NETIF_IP_EVENT_GOT_IP ) ),
                             []( const idf::event::ESPEvent &, void * params ) {
                                 auto evt = reinterpret_cast< ip_event_got_ip_t * >( params );
                                 std::print( "-------Got IP: {}.{}.{}.{}\n",
                                             esp_ip4_addr1_16( &evt->ip_info.ip ),
                                             esp_ip4_addr2_16( &evt->ip_info.ip ),
                                             esp_ip4_addr3_16( &evt->ip_info.ip ),
                                             esp_ip4_addr4_16( &evt->ip_info.ip ) );
                             } ) );

        Wifi::start();

        esp_netif_ip_info_t ipInfo {};
        IP4_ADDR( &ipInfo.ip, 192, 168, 88, 1 );
        IP4_ADDR( &ipInfo.netmask, 255, 255, 255, 0 );
        IP4_ADDR( &ipInfo.gw, 192, 168, 88, 1 );

        std::print( "Setted IP: {}.{}.{}.{}\n",
                    esp_ip4_addr1_16( &ipInfo.ip ),
                    esp_ip4_addr2_16( &ipInfo.ip ),
                    esp_ip4_addr3_16( &ipInfo.ip ),
                    esp_ip4_addr4_16( &ipInfo.ip ) );

        wifiIfHandler.dhcpsStop();
        wifiIfHandler.setIpInfo( ipInfo );
        wifiIfHandler.dhcpsStart();

        const auto currentIpInfo = wifiIfHandler.getIpInfo();
        std::print( "Current IP: {}.{}.{}.{}\n",
                    esp_ip4_addr1_16( &currentIpInfo.ip ),
                    esp_ip4_addr2_16( &currentIpInfo.ip ),
                    esp_ip4_addr3_16( &currentIpInfo.ip ),
                    esp_ip4_addr4_16( &currentIpInfo.ip ) );

        const auto oldIpInfo = wifiIfHandler.getOldIpInfo();
        std::print( "Old IP: {}.{}.{}.{}\n",
                    esp_ip4_addr1_16( &oldIpInfo.ip ),
                    esp_ip4_addr2_16( &oldIpInfo.ip ),
                    esp_ip4_addr3_16( &oldIpInfo.ip ),
                    esp_ip4_addr4_16( &oldIpInfo.ip ) );

        while ( wifiIfHandler.dhcpsGetStatus() != ESP_NETIF_DHCP_STARTED ) {
            std::print( "WAIT FOR DHCPS STARTED !!!\n" );
            using namespace std::chrono_literals;
            std::this_thread::sleep_for( 1000ms );
        }
    } catch ( const std::exception & e ) { std::print( "MAIN EXCEPTION: {}\n", e.what() ); }

    return 0;
}

Alternatives

No response

Additional context

No response

safocl commented 21 hours ago

Unfortunately, the original C library does not provide the ability to track the initialization of some entities, such as the WiFi, NVS, and NetIF subsystems -- for this reason, it is necessary to additionally hold variables to identify the status.