esp-idf-svc icon indicating copy to clipboard operation
esp-idf-svc copied to clipboard

Cannot change network interface after creation

Open torkleyy opened this issue 1 year ago • 5 comments
trafficstars

Many methods of EspNetif are not exposed, such as setters and dhcp control. Without this, the ip configuration of an established connection cannot be changed.

torkleyy avatar Dec 20 '23 13:12 torkleyy

If you have concrete methods that need to be exposed (as well as justification why just re-creating the interface is not ideal), please go ahead and justify.

But in its current shape, this issue is hardly actionable.

ivmarkov avatar Dec 20 '23 16:12 ivmarkov

as well as justification why just re-creating the interface is not ideal

You cannot just recreate the interface. You would at least have to rotate the key, because it has to be unique. And swapping the interface does not allow setting an IP for an existing connection:

    log::info!("Starting...");
    wifi.start()?;
    log::info!("Connecting...");
    wifi.connect()?;
    log::info!("Connected");
    wifi.wait_netif_up()?;
    log::info!("Ready");

    log::info!("Changing ip");

    wifi.wifi_mut().swap_netif_sta(EspNetif::new_with_conf(&NetifConfiguration {
        key: "test".into(),
        ip_configuration: ipv4::Configuration::Client(ipv4::ClientConfiguration::Fixed(ipv4::ClientSettings {
            ip: ipv4::Ipv4Addr::new(192, 168, 178, 244),
            subnet: ipv4::Subnet {
                gateway: ipv4::Ipv4Addr::new(192, 168, 178, 1),
                mask: ipv4::Mask(24),
            },
            dns: Some(ipv4::Ipv4Addr::new(1, 1, 1, 1)),
            secondary_dns: None,
        })),
        ..NetifConfiguration::wifi_default_client()
    }).unwrap()).unwrap();

    log::info!("Changed ip");
    wifi.wait_netif_up()?;

    log::info!("Netif up again");

Above code will simply timeout.

torkleyy avatar Dec 21 '23 08:12 torkleyy

If you believe this is possible to do at runtime without destroying the EspNetif object, by all means demonstrate how, and I'll merge.

As for the the above code timing out, what is the root cause? You can't just say "you need to do B. because there is some bug with A, which I don't know the reason for".

ivmarkov avatar Dec 21 '23 09:12 ivmarkov

As for the the above code timing out, what is the root cause? You can't just say "you need to do B. because there is some bug with A, which I don't know the reason for".

You're correct. I assumed you're not supposed to swap network interfaces during an active connection, but maybe it's also a bug. I have not investigated it further. It's hard to tell whether it can be considered a bug because esp-idf doesn't really document what esp_netif_attach is even supposed to do.

If you believe this is possible to do at runtime without destroying the EspNetif object, by all means demonstrate how, and I'll merge.

I can do that. The esp-idf docs for esp_netif_set_ip_info lead me to believe that it's possible.

torkleyy avatar Dec 21 '23 10:12 torkleyy

For anyone curious about how to get around this, we have this snippet:

static IF_COUNTER: AtomicUsize = AtomicUsize::new(1);

/// A global interface ID that prevents creating duplicate interface keys.
fn get_id() -> usize {
    IF_COUNTER.fetch_add(1, Ordering::Relaxed)
}

// and then later:
let new_netif = EspNetif::new_with_conf(&NetifConfiguration {
                            ip_configuration: ipv4::Configuration::Client(...),
                            key: format!("ETH_CL_{}", get_id()).as_str().try_into().unwrap(),
                            ..NetifConfiguration::eth_default_client()
                        })


 eth.eth_mut()
      .swap_netif(new_netif);
log::info!("Starting Eth"); 
eth.start().await; 
info!("Eth started.");

DaneSlattery avatar Jul 22 '24 12:07 DaneSlattery