Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add Wi-Fi callback example #388

Open
owenthewizard opened this issue Mar 16, 2024 · 10 comments
Open

Feature Request: Add Wi-Fi callback example #388

owenthewizard opened this issue Mar 16, 2024 · 10 comments
Labels
enhancement New feature or request

Comments

@owenthewizard
Copy link
Contributor

I'm trying to use WifiDriver::set_callbacks but I'm not successful. I think an example would be helpful.
Context: I'm trying to implement this in idiomatic Rust: https://github.com/dokmic/eth2wlan/blob/master/main/main.c

@owenthewizard
Copy link
Contributor Author

This is my non-working code. It seems the callbacks never get called.

    // Wrap your drivers in Arc<Mutex<_>> to allow shared mutable access.
    let eth_mutex = Arc::new(Mutex::new(eth));
    let wifi_mutex = Arc::new(Mutex::new(wifi));

    // Clone the Arcs for use in closures
    let eth_mutex_clone = eth_mutex.clone();
    let wifi_mutex_clone = wifi_mutex.clone();

    // Forward from eth to wifi
    eth_mutex
        .lock()
        .unwrap()
        .driver_mut()
        .set_rx_callback(move |frame| {
            info!("Forwarding frame from eth to wifi...");
            if let Err(e) = wifi_mutex_clone
                .lock()
                .unwrap()
                .send(WifiDeviceId::Sta, frame)
            {
                error!("Failed to forward eth frame to wifi: {}", e);
            }
        })?;

    // Forward from wifi to eth
    wifi_mutex.lock().unwrap().set_callbacks(move |_, frame| {
        info!("Forwarding frame from wifi to eth...");
        if let Err(e) = eth_mutex_clone.lock().unwrap().driver_mut().send(frame) {
            error!("Failed to forward wifi frame to eth: {}", e);
        }
        Ok(())
    }, |_, _, _| {})?;

@owenthewizard
Copy link
Contributor Author

Hm, when callbacks are set the interfaces are stopped.

@owenthewizard
Copy link
Contributor Author

The C functions are noted to be internal to ESP and not recommended for customers to use. Regardless, they seem to function. Better documentation is needed.

@Vollbrecht
Copy link
Collaborator

I wrote a esp sniffer using the promiscuous mode and streamed the data via callback's as PCAP packets back over uart directly into wireshark on a host machine.

I am telling you this because you need to be really careful using the callbacks. By that i am talking about that the callbacks are working inside the wifi thread with a high system priority. You should not do any blocking there as you will stale the complete wifi driver. Best is to just grab the data/info you want and just push it out. Don't use Mutex's that maybe can deadlock you or are to slow. Just stream out the data via a mpsc channel or something.

At that time i didn't use this callbacks but the unsafe esp-idf-sys methods directly but it should be similar-

@owenthewizard
Copy link
Contributor Author

Another development, the callback functions seem to be broken, there's a workaround in https://github.com/makischu/ESP_eth2wifi.

@ivmarkov
Copy link
Collaborator

ivmarkov commented Mar 19, 2024

The original purpose of these callbacks was not to do what you are trying to do (i.e., have the callbacks and the netif stack on top running together somehow), but to rather allow users to have a driver (eth and/or wifi) that operates purely on L2 level, and then potentially layer a user-provided IP stack layer on top of the callbacks. Say - the pure Rust smoltcp one.

With that said, I have not tried whether that would work, as I don't yet have that usecase, but I don't see why it wouldn't given that the ESP IDF netif layer uses these very same callbacks.

With that said, your use case is different, so you probably need to inspect or even patch the netif stack so that callbacks or their equivalents are usable even when the netif stack continues to run on top.

@owenthewizard
Copy link
Contributor Author

@ivmarkov Can I just patch the esp-idf sources in .embuild or is there a "proper" way to do it that I can integrate into build.rs?

@ivmarkov
Copy link
Collaborator

Just use your own esp idf git fork. You can pass the git url and/or the path to your local ESP IDF to esp-idf-sys.

@owenthewizard
Copy link
Contributor Author

You can pass the git url and/or the path to your local ESP IDF to esp-idf-sys.

Is there a doc or somewhere I can read more directions for this? Sorry if I'm dense, this is my first endeavor into Rust on ESP32 (and the ESP32 itself for that matter).

For anyone reading along, it looks like there's an up to date example here (sta2eth): https://github.com/espressif/esp-idf/tree/master/examples/network
I'm going to try it out.

@ivmarkov
Copy link
Collaborator

https://github.com/esp-rs/esp-idf-sys/blob/master/BUILD-OPTIONS.md

@Vollbrecht Vollbrecht added the enhancement New feature or request label Jun 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

3 participants