-
Notifications
You must be signed in to change notification settings - Fork 264
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
Allow switching between AP, STA etc at runtime #2224
Comments
@Karuso33 Are you trying to make the ApSta and then use the raw interface for TX/RX of raw frames? I am trying to do the same here. |
Thanks for the suggestion! I think we could allow to degrade from ApSta to either Ap or Sta but we cannot allow going from Ap to Sta, Sta to Ap etc. since the user doesn't have access to the device/interface But we should do that by either consuming the ap-device/ap-interface or the sta-device/sta-interface since otherwise the user could try to continue using them. Maybe something like |
As I said, I am not deeply familiar with the code base, so take everything I say with a grain of salt. But I think it might actually be kind of fine to let the user keep control of the While failing silently is not ideal, it is pretty much the same situation that the user currently faces when trying to send data in Sta mode, while not connected to an access point (that also returns 12294 - ESP_ERR_WIFI_STATE). And I feel like if that behavior is okay in Sta mode, then it would also not be the worst thing to have this behavior for Ap mode as well. I think that this is realistically the best solution there is here. Especially since it is not possible to "get back" the WifiApDevice once an embassy-net |
I think the current The above makes it very difficult to switch - at runtime - from AP to STA mode and back, as one has to tear down the whole network stack, along with all the apps (HTTPD, etc.) that sit on top of it. This does not play well with use cases where - say - the HTTPD server, or other network-layer futures are modeled with embassy-executor-tasks each, as in that case, the network stack - by necessity - needs to be passed in a What the above entails, is that either:
In the STD hal we are able to switch between AP and STA at runtime without any issues so this "AP-and-STA-are-typestates" design in Also, I just looked at the cyw SPI wifi, and it does seem to be able to switch between AP and STA at runtime?, so the issue seems to be unique to |
pinging @Dominaezzz as he expressed interest in this topic. |
I have some ideas what I would want to do if I had time 😄 - will try to write them down here (Spoiler: would result in a totally different API) |
JFYI with @Dominaezzz we had a similar idea: you could leave the existing driver intact, and then implement an embassy-net driver proxy (possibly, by using However I think the above ^^^ is best suited when somebody wants to workaround the status quo where the existing wifi driver has to be completely torn down to go from say ap to sta, and perhaps not really the best approach if the esp-wifi driver is to be rewritten/changed internally. Anyway, mentioning for completeness. |
Does the std hal use embassy-net as well or does it still use lwIP or whatever idf uses normally? I'm still trying to reason about the network stack is supposed to deal with the switch. |
This. Even though the std hal now have the facility to RX/TX raw ethernet packets as well, so in theory you can slap But the point is, the std stack does not destroy the ap and sta "netifs" (the equivalent of
Ideally, we should have two |
Ahhh now that makes a lot of sense to me. |
That would be my plan |
I promised to write down my ideas here but to avoid writing non-sense I did a reality check in #3027 The idea is
For user code it looks like this ...
// no change here - we obviously need to call init before actually using esp-wifi
let esp_wifi_ctrl = &*mk_static!(
EspWifiController<'static>,
init(timg0.timer0, rng.clone(), peripherals.RADIO_CLK).unwrap()
);
// we can take the network interfaces / devices any time
let interfaces = esp_wifi::wifi::take().unwrap();
let wifi_interface = interfaces.sta;
// get the controller - we can switch modes at will
let controller = esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
... Not that much of a drastic change as I thought but as a side-effect it makes the API less weird (e.g. I was never able to use esp-wifi before without looking at the examples). In my testing things look good but there might be oversights and edge-cases I didn't think of. For now, it's meant as a discussion starter but I'm also happy to get it in mergeable shape (if we don't agree on s.th. totally different) |
@bjoernQ What I don't like that much is the introduction of this let interfaces = esp_wifi::wifi::take().unwrap(); Also, given that you say: // get the controller - we can switch modes at will
let controller = esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap(); ... why don't we just have this instead: // get the controller and the interfaces - we can switch controller modes at will
// NOTE: `interfaces` will be `'static` as long as `&esp_wifi_ctrl` is `'static`, (right??) which is quite possible to do with `mk_static`
let (controller, interfaces) = esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap(); ... and then using the new "type-state"-less |
Thanks for taking time to look into this and for the feedback! Seems like this goes into a similar direction as Daniel's feedback and I agree I think I like the idea of getting the controller and the interfaces as a tuple |
Currently if I try disable WiFi at runtime (using |
True - we currently (and did so before) actively disallow |
I suppose this can be closed now? |
Thanks for the reminder |
I would like to initialize the Wifi interface in ApSta mode and later disable the access point (and switch to Sta mode). This is so that the device can be accessed via the access point to configure it. Afterwards, the access point should disappear and be inaccessible (this is especially relevant because the "obvious hack" of making the AP hidden with a password does not work in esp-wifi, as it does not support password protected APs right now).
As far as I can tell, this is possible in esp-idf through
esp_wifi_set_mode
. I propose to changeWifiController::set_confguration
so that it just infers the mode from the configuration that was passed in, i.e. something like thisI think this approach also somewhat simplifies the amount of validation (see here) that has to be done in
set_configuration
.I did try out this change locally and it seems to work and do what it should (though I am not deeply familiar with esp-wifi or esp-idf, so this might be subtly broken).
The text was updated successfully, but these errors were encountered: