From ecccbb46cbef0cb52b0f487b92e2925cba6e9db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 13 Sep 2018 15:13:23 +0200 Subject: [PATCH] wifi_drv: add hidden network support Fixes #2988. --- repos/dde_linux/include/wifi/ctrl.h | 2 +- repos/dde_linux/patches/wpa_supplicant.patch | 13 + repos/dde_linux/ports/dde_linux.hash | 2 +- repos/dde_linux/run/nic_router_uplinks.run | 4 +- repos/dde_linux/run/wifi.run | 35 +- repos/dde_linux/src/drivers/wifi/frontend.h | 460 ++++++++++++------ repos/dde_linux/src/lib/wifi/lxcc_emul.cc | 1 - .../lib/wpa_supplicant/ctrl_iface_genode.c | 29 +- repos/ports/run/netperf.inc | 4 +- 9 files changed, 366 insertions(+), 184 deletions(-) diff --git a/repos/dde_linux/include/wifi/ctrl.h b/repos/dde_linux/include/wifi/ctrl.h index 106764256a..2b53492acf 100644 --- a/repos/dde_linux/include/wifi/ctrl.h +++ b/repos/dde_linux/include/wifi/ctrl.h @@ -22,7 +22,7 @@ extern "C" { struct Msg_buffer { - unsigned char recv[4096]; + unsigned char recv[4096*8]; unsigned char send[1024]; unsigned recv_id; unsigned send_id; diff --git a/repos/dde_linux/patches/wpa_supplicant.patch b/repos/dde_linux/patches/wpa_supplicant.patch index 31ae9411e7..f7f752a0bb 100644 --- a/repos/dde_linux/patches/wpa_supplicant.patch +++ b/repos/dde_linux/patches/wpa_supplicant.patch @@ -93,3 +93,16 @@ index 436bc8c99..f5ff4facb 100644 #endif /* CONFIG_ELOOP_POLL */ #ifdef CONFIG_ELOOP_EPOLL +diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c +index fe39c25b7..3a682785e 100644 +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -9778,7 +9778,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, + char *buf, size_t *resp_len) + { + char *reply; +- const int reply_size = 4096; ++ const int reply_size = 4096*8; + int reply_len; + + if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || diff --git a/repos/dde_linux/ports/dde_linux.hash b/repos/dde_linux/ports/dde_linux.hash index 91085d0b13..a44c9c01a9 100644 --- a/repos/dde_linux/ports/dde_linux.hash +++ b/repos/dde_linux/ports/dde_linux.hash @@ -1 +1 @@ -5ee7d9befaff281fec480e2257f302c76fe85126 +85b33124266df46e53981153e5014fd372d0680d diff --git a/repos/dde_linux/run/nic_router_uplinks.run b/repos/dde_linux/run/nic_router_uplinks.run index d4fee7d1e7..270a731243 100644 --- a/repos/dde_linux/run/nic_router_uplinks.run +++ b/repos/dde_linux/run/nic_router_uplinks.run @@ -113,8 +113,8 @@ append config { - - + + diff --git a/repos/dde_linux/run/wifi.run b/repos/dde_linux/run/wifi.run index 84f1fd6a92..7eea74e55c 100644 --- a/repos/dde_linux/run/wifi.run +++ b/repos/dde_linux/run/wifi.run @@ -79,7 +79,15 @@ append config { - + + + + + + + + + @@ -91,30 +99,28 @@ append config { + + + + - - + + - - + + - - + + - - - - - - @@ -133,7 +139,8 @@ append config { - + + diff --git a/repos/dde_linux/src/drivers/wifi/frontend.h b/repos/dde_linux/src/drivers/wifi/frontend.h index 4aafd73d1f..ccc6658a51 100644 --- a/repos/dde_linux/src/drivers/wifi/frontend.h +++ b/repos/dde_linux/src/drivers/wifi/frontend.h @@ -71,12 +71,13 @@ static struct Recv_msg_table { char const *string; size_t len; } recv_table[] = { - { "OK", 2 }, - { "FAIL", 4 }, - { "CTRL-EVENT-SCAN-RESULTS", 23 }, - { "CTRL-EVENT-CONNECTED", 20 }, - { "CTRL-EVENT-DISCONNECTED", 23 }, - { "SME: Trying to authenticate", 27 }, + { "OK", 2 }, + { "FAIL", 4 }, + { "CTRL-EVENT-SCAN-RESULTS", 23 }, + { "CTRL-EVENT-CONNECTED", 20 }, + { "CTRL-EVENT-DISCONNECTED", 23 }, + { "SME: Trying to authenticate", 27 }, + { "CTRL-EVENT-NETWORK-NOT-FOUND", 28 }, }; enum Rmi { @@ -86,6 +87,7 @@ enum Rmi { CONNECTED, DISCONNECTED, SME_AUTH, + NOT_FOUND, }; @@ -110,6 +112,10 @@ static bool connecting_to_network(char const *msg) { return check_recv_msg(msg, recv_table[SME_AUTH]); } +static bool network_not_found(char const *msg) { + return check_recv_msg(msg, recv_table[NOT_FOUND]); } + + static bool scan_results(char const *msg) { return Genode::strcmp("bssid", msg, 5) == 0; } @@ -151,12 +157,13 @@ struct Accesspoint int id { -1 }; bool enabled { false }; - /* + /* * Internal configuration fields */ - bool auto_connect { false }; - bool update { false }; - bool stale { false }; + bool auto_connect { false }; + bool update { false }; + bool stale { false }; + bool explicit_scan { false }; /** * Default constructor @@ -171,11 +178,12 @@ struct Accesspoint : bssid(bssid), freq(freq), prot(prot), ssid(ssid), signal(signal) { } - void invalidate() { ssid = Ssid(); } + void invalidate() { ssid = Ssid(); bssid = Bssid(); } - bool valid() const { return ssid.length() > 1; } - bool wpa() const { return prot != "NONE"; } - bool stored() const { return id != -1; } + bool valid() const { return ssid.length() > 1; } + bool bssid_valid() const { return bssid.length() > 1; } + bool wpa() const { return prot != "NONE"; } + bool stored() const { return id != -1; } }; @@ -343,7 +351,7 @@ struct Wifi::Frontend } if (_rfkilled && _state != State::IDLE) { - Genode::warning(__func__, ": rfkilled with ", state_strings(_state)); + Genode::warning("rfkilled in state ", state_strings(_state)); } } @@ -357,12 +365,12 @@ struct Wifi::Frontend bool _use_11n { true }; bool _deferred_config_update { false }; - bool _fake_connecting { false }; + bool _single_autoconnect { false }; unsigned _connected_scan_interval { 15 }; unsigned _scan_interval { 5 }; - void _handle_config_update() + void _config_update(bool signal) { _config_rom.update(); @@ -400,7 +408,18 @@ struct Wifi::Frontend * by the singal handler but is not expected to be any different * as the rfkill call is not supposed to fail. */ - if (blocked) { _rfkilled = true; } + if (blocked && !_rfkilled) { + _rfkilled = true; + + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("state", "disconnected"); + xml.attribute("rfkilled", _rfkilled); + }); + }); + + _connected_ap.invalidate(); + } } /* @@ -413,90 +432,92 @@ struct Wifi::Frontend return; } - bool fake_connecting = false; + bool single_autoconnect = false; /* update AP list */ - try { - config.for_each_sub_node("accesspoint", [&] ( Genode::Xml_node node) { + auto parse = [&] ( Genode::Xml_node node) { - Accesspoint ap; - ap.ssid = node.attribute_value("ssid", Accesspoint::Ssid("")); - ap.bssid = node.attribute_value("bssid", Accesspoint::Bssid("")); + Accesspoint ap; + ap.ssid = node.attribute_value("ssid", Accesspoint::Ssid()); + ap.bssid = node.attribute_value("bssid", Accesspoint::Bssid()); - size_t const ssid_len = ap.ssid.length() - 1; - if (ssid_len == 0 || ssid_len > 32) { - Genode::warning("ignoring accesspoint with invalid ssid"); + size_t const ssid_len = ap.ssid.length() - 1; + if (ssid_len == 0 || ssid_len > 32) { + Genode::warning("ignoring accesspoint with invalid ssid"); + return; + } + + Accesspoint *p = _lookup_ap_by_ssid(ap.ssid); + if (p) { + if (_verbose) { Genode::log("Update: '", p->ssid, "'"); } + /* mark for updating */ + p->update = true; + } else { + p = _ap_slot(); + if (!p) { + Genode::warning("could not add accesspoint, no slots left"); return; } + } - Accesspoint *p = _lookup_ap_by_ssid(ap.ssid); - if (p) { - if (_verbose) { Genode::log("Update: '", p->ssid, "'"); } - /* mark for updating */ - p->update = true; - } else { - p = _ap_slot(); - if (!p) { - Genode::warning("could not add accesspoint, no slots left"); - return; - } - } - - ap.pass = node.attribute_value("passphrase", Accesspoint::Pass("")); - ap.prot = node.attribute_value("protection", Accesspoint::Prot("NONE")); - ap.auto_connect = node.attribute_value("auto_connect", true); - - if (ap.wpa()) { - size_t const psk_len = ap.pass.length() - 1; - if (psk_len < 8 || psk_len > 63) { - Genode::warning("ignoring accesspoint '", ap.ssid, - "' with invalid pass"); - return; - } + ap.pass = node.attribute_value("passphrase", Accesspoint::Pass("")); + ap.prot = node.attribute_value("protection", Accesspoint::Prot("NONE")); + ap.auto_connect = node.attribute_value("auto_connect", true); + ap.explicit_scan = node.attribute_value("explicit_scan", false); + + if (ap.wpa()) { + size_t const psk_len = ap.pass.length() - 1; + if (psk_len < 8 || psk_len > 63) { + Genode::warning("ignoring accesspoint '", ap.ssid, + "' with invalid pass"); + return; } + } - /* check if updating is really necessary */ - if (p->update) { - p->update = (ap.bssid != p->bssid - || ap.pass != p->pass - || ap.prot != p->prot - || ap.auto_connect != p->auto_connect); - } + /* check if updating is really necessary */ + if (p->update) { + p->update = ((ap.bssid.length() > 1 && ap.bssid != p->bssid) + || ap.pass != p->pass + || ap.prot != p->prot + || ap.auto_connect != p->auto_connect); + } - /* TODO add better way to check validity */ - if (ap.bssid.length() == 17 + 1) { p->bssid = ap.bssid; } + /* TODO add better way to check validity */ + if (ap.bssid.length() == 17 + 1) { p->bssid = ap.bssid; } - p->ssid = ap.ssid; - p->prot = ap.prot; - p->pass = ap.pass; - p->auto_connect = ap.auto_connect; + p->ssid = ap.ssid; + p->prot = ap.prot; + p->pass = ap.pass; + p->auto_connect = ap.auto_connect; + p->explicit_scan = ap.explicit_scan; - fake_connecting |= (p->update || p->auto_connect) && !_connected_ap.valid(); - }); - } catch (...) { Genode::warning("accesspoint list empty"); } + single_autoconnect |= (p->update || p->auto_connect) && !_connected_ap.valid(); + }; + config.for_each_sub_node("network", parse); /* * To accomodate a management component that only deals * with on network, e.g. the sculpt_manager, generate a - * fake connected event. + * fake connecting event. Either a connected or disconnected + * event will bring us to square one. */ - if (_count_to_be_enabled() == 1 && fake_connecting) { + if (signal && _count_to_be_enabled() == 1 && single_autoconnect && !_rfkilled) { auto lookup = [&] (Accesspoint const &ap) { if (!ap.auto_connect) { return; } - if (_verbose) { Genode::log("Fake connected event for '", ap.ssid, "'"); } + if (_verbose) { Genode::log("Single autoconnect event for '", ap.ssid, "'"); } try { Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { xml.node("accesspoint", [&] () { xml.attribute("ssid", ap.ssid); - xml.attribute("state", "connected"); + xml.attribute("state", "connecting"); }); }); - _fake_connecting = true; + _single_autoconnect = true; } catch (...) { } }; @@ -510,6 +531,8 @@ struct Wifi::Frontend _mark_stale_aps(config); } + void _handle_config_update() { _config_update(true); } + /* state */ Accesspoint *_processed_ap { nullptr }; @@ -611,14 +634,43 @@ struct Wifi::Frontend return; } - _arm_scan_timer(_connected_ap.valid()); + _arm_scan_timer(_connected_ap.bssid_valid()); /* skip as we will be scheduled some time soon(tm) anyway */ if (_state != State::IDLE) { return; } - /* TODO scan request/pending results timeout */ + /* left one attempt out */ + if (_scan_busy) { + _scan_busy = false; + return; + } + + enum { SSID_ARG_LEN = 64 + 5, /* "ssid " + "a5a5a5a5..." */ }; + /* count * (SSID_ARG_LEN + " ") + NUL */ + char ssid_buffer[MAX_ACCESSPOINTS * (SSID_ARG_LEN + 1) + 1] = { }; + size_t buffer_pos = 0; + + auto valid_ssid = [&] (Accesspoint const &ap) { + + if (!ap.explicit_scan) { return; } + + char ssid_hex[64+1] = { }; + char const *ssid = ap.ssid.string(); + + for (size_t i = 0; i < ap.ssid.length() - 1; i++) { + Util::byte2hex((ssid_hex + i * 2), ssid[i]); + } + + Genode::String tmp(" ssid ", (char const*)ssid_hex); + size_t const tmp_len = tmp.length() - 1; + + Genode::memcpy((ssid_buffer + buffer_pos), tmp.string(), tmp_len); + buffer_pos += tmp_len; + }; + _for_each_ap(valid_ssid); + _state_transition(_state, State::INITIATE_SCAN); - _submit_cmd(Cmd_str("SCAN")); + _submit_cmd(Cmd_str("SCAN ", (char const*)ssid_buffer)); } void _arm_scan_timer(bool connected) @@ -644,6 +696,9 @@ struct Wifi::Frontend if (!count_lines) { return; } try { + + bool connecting_attempt = false; + Genode::Reporter::Xml_generator xml(*_ap_reporter, [&]() { for_each_result_line(msg, [&] (Accesspoint const &ap) { @@ -658,8 +713,22 @@ struct Wifi::Frontend xml.attribute("quality", ap.signal); if (ap.wpa()) { xml.attribute("protection", ap.prot); } }); + + auto check_existence = [&] (Accesspoint &lap) { + connecting_attempt |= (lap.ssid == ap.ssid) && ap.auto_connect; + }; + _for_each_ap(check_existence); }); }); + + if (!_connected_ap.bssid_valid() && connecting_attempt) { + + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("state", "connecting"); + }); + }); + } } catch (...) { /* silently omit report */ } } @@ -670,7 +739,7 @@ struct Wifi::Frontend auto mark_stale = [&] (Accesspoint &ap) { ap.stale = true; - config.for_each_sub_node("accesspoint", [&] ( Genode::Xml_node node) { + config.for_each_sub_node("network", [&] ( Genode::Xml_node node) { Accesspoint::Ssid ssid = node.attribute_value("ssid", Accesspoint::Ssid("")); if (ap.ssid == ssid) { ap.stale = false; } @@ -735,8 +804,6 @@ struct Wifi::Frontend Genode::log("Update network: '", _processed_ap->ssid, "'"); } - // _processed_ap->update = false; - /* re-use state to change PSK */ _state_transition(_state, State::FILL_NETWORK_PSK); _network_set_psk(); @@ -873,12 +940,17 @@ struct Wifi::Frontend /* result handling */ + bool _scan_busy { false }; + void _handle_scan_results(State state, char const *msg) { switch (state) { case State::INITIATE_SCAN: if (!cmd_successful(msg)) { - Genode::warning("could not initiate scan: ", msg); + _scan_busy = Genode::strcmp(msg, "FAIL-BUSY"); + if (!_scan_busy) { + Genode::warning("could not initiate scan: ", msg); + } } _state_transition(_state, State::IDLE); break; @@ -1054,16 +1126,17 @@ struct Wifi::Frontend * If some step failed we have to generate a fake * disconnect event. */ - if (_fake_connecting && !successfully) { + if (_single_autoconnect && !successfully) { try { Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { xml.node("accesspoint", [&] () { xml.attribute("state", "disconnected"); + xml.attribute("rfkilled", _rfkilled); xml.attribute("config_error", true); }); }); - _fake_connecting = false; + _single_autoconnect = false; } catch (...) { } } } @@ -1072,15 +1145,11 @@ struct Wifi::Frontend { _state_transition(_state, State::IDLE); - _state_transition(_state, State::LIST_NETWORKS); - _submit_cmd(Cmd_str("LIST_NETWORKS")); - } - - void _handle_info_result(State state, char const *msg) - { - _state_transition(_state, State::IDLE); - - if (!_connected_event && !_disconnected_event) { return; } + /* + * Querying the status might have failed but we already sent + * out a rudimentary report, just stop here. + */ + if (0 == msg[0]) { return; } Accesspoint ap { }; @@ -1099,16 +1168,66 @@ struct Wifi::Frontend }; for_each_line(msg, fill_ap); - /* + if (!ap.ssid.valid()) { + Genode::error("Cannot query SSID :-("); + return; + } + + Accesspoint *p = _lookup_ap_by_ssid(ap.ssid); + if (p) { + p->bssid = ap.bssid; + p->freq = ap.freq; + } + + _connected_ap.ssid = ap.ssid; + + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("ssid", ap.ssid); + xml.attribute("bssid", ap.bssid); + xml.attribute("freq", ap.freq); + xml.attribute("state", "connected"); + }); + }); + } + + void _handle_info_result(State state, char const *msg) + { + _state_transition(_state, State::IDLE); + + if (!_connected_event && !_disconnected_event) { return; } + + /* + * It might happen that the supplicant already flushed + * its internal BSS information and cannot help us out. + * Since we already sent out a rudimentary report, just + * stop here. + */ + if (0 == msg[0]) { return; } + + Accesspoint ap { }; + + auto fill_ap = [&] (char const *line) { + if (Genode::strcmp(line, "ssid=", 5) == 0) { + ap.ssid = Accesspoint::Ssid(line+5); + } else + + if (Genode::strcmp(line, "bssid=", 6) == 0) { + ap.bssid = Accesspoint::Bssid(line+6); + } else + + if (Genode::strcmp(line, "freq=", 5) == 0) { + ap.freq = Accesspoint::Freq(line+5); + } + }; + for_each_line(msg, fill_ap); + + /* * When the config is changed while we are still connecting and * for some reasons the accesspoint does not get disabled * a connected event could arrive and we will get a nullptr... */ Accesspoint *p = _lookup_ap_by_ssid(ap.ssid); - if (!p) { - Genode::warning("received connection event for unknown " - "network '", ap.ssid, "'"); - } /* * ... but we still generate a report and let the management @@ -1129,8 +1248,13 @@ struct Wifi::Frontend }); if (_disconnected_fail) { - - if (!p || _processed_ap || _state != State::IDLE) { + /* + * Being able to remove a failed network from the internal + * state of the supplicant relies on a sucessful BSS request. + * In case that failes the supplicant will try to join the + * network again and again... + */ + if (!p || _processed_ap) { Genode::error("cannot disabled failed network"); } else { _processed_ap = p; @@ -1140,20 +1264,21 @@ struct Wifi::Frontend } else if (_connected_event) { + /* + * In case the BSS cmd did not return a valid SSID, which + * was observed only with hidden networks so far, check the + * current status. + */ if (!p) { - Genode::error("cannot lookup connected network"); - return; + _state_transition(_state, State::STATUS); + _submit_cmd(Cmd_str("STATUS")); + + } else { + p->bssid = ap.bssid; + p->freq = ap.freq; } - p->bssid = ap.bssid; - p->freq = ap.freq; - _connected_ap = ap; - } else - - /* just your normal disconnect event */ - { - _connected_ap.invalidate(); } } @@ -1200,60 +1325,71 @@ struct Wifi::Frontend bool _disconnected_event { false }; bool _disconnected_fail { false }; + enum { MAX_ATTEMPTS = 3, }; + unsigned _scan_attempts { 0 }; + Accesspoint::Bssid _pending_bssid { }; - bool _handle_connection_events(char const *msg) + void _handle_connection_events(char const *msg) { bool const connected = check_recv_msg(msg, recv_table[Rmi::CONNECTED]); bool const disconnected = check_recv_msg(msg, recv_table[Rmi::DISCONNECTED]); + bool const auth_failed = disconnected && _auth_failure(msg); State state = connected ? State::CONNECTED : State::DISCONNECTED; - Accesspoint::Bssid const &bssid = _extract_bssid(msg, state); + /* + * Always reset the "global" connection state first + */ + _connected_ap.invalidate(); + if (connected) { _connected_ap.bssid = bssid; } + if (connected || disconnected) { _connecting = Accesspoint::Bssid(); } + + /* + * Save local connection state here for later re-use when + * the BSS information are handled. + */ _connected_event = connected; _disconnected_event = disconnected; - _disconnected_fail = disconnected && _auth_failure(msg); + _disconnected_fail = auth_failed; - if (connected) { + if (!_rfkilled) { + + /* + * As we only received the BSSID, try to gather more information + * so we may generate a more thorough follow-up state report. + */ if (_state != State::IDLE) { _pending_bssid = bssid; } else { _state_transition(_state, State::INFO); _submit_cmd(Cmd_str("BSS ", bssid)); } - } else { - /* - * In case of disconnected event use stored information if we - * already were connected. - */ - Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { - - xml.node("accesspoint", [&] () { - if (_connected_ap.valid()) { - xml.attribute("ssid", _connected_ap.ssid); - xml.attribute("bssid", _connected_ap.bssid); - xml.attribute("freq", _connected_ap.freq); - } else { - xml.attribute("bssid", bssid); - } - xml.attribute("state", "disconnected"); - xml.attribute("rfkilled", _rfkilled); - xml.attribute("auth_failure", _disconnected_fail); - }); - }); - - _connected_ap.invalidate(); - - /* arm scan timer implicitly */ - _handle_scan_timer(); + _arm_scan_timer(connected); } - /* reset */ - _fake_connecting = false; + /* + * Generate the first rudimentary report whose missing information + * are (potentially) filled in later (see above). + */ + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("bssid", bssid); + xml.attribute("state", connected ? "connected" + : "disconnected"); + if (disconnected) { + xml.attribute("rfkilled", _rfkilled); + if (auth_failed) { + xml.attribute("auth_failure", auth_failed); + } + } + }); + }); - return connected || disconnected; + /* reset */ + _single_autoconnect = false; } Genode::Signal_handler _events_handler; @@ -1271,10 +1407,6 @@ struct Wifi::Frontend return; } - if (_rfkilled) { - Genode::warning(__func__, ": rfkilled with ", state_strings(_state)); - } - if (results_available(msg)) { /* @@ -1291,7 +1423,7 @@ struct Wifi::Frontend } else if (connecting_to_network(msg)) { - if (!_fake_connecting) { + if (!_single_autoconnect) { Accesspoint::Bssid const &bssid = _extract_bssid(msg, State::CONNECTING); _connecting = bssid; @@ -1304,6 +1436,29 @@ struct Wifi::Frontend } } else + if (network_not_found(msg)) { + + /* always try to update the accesspoint list */ + if (_state == State::IDLE) { + _state_transition(_state, State::PENDING_RESULTS); + _submit_cmd(Cmd_str("SCAN_RESULTS")); + } + + if (_single_autoconnect && ++_scan_attempts >= MAX_ATTEMPTS) { + _scan_attempts = 0; + _single_autoconnect = false; + + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("state", "disconnected"); + xml.attribute("rfkilled", _rfkilled); + xml.attribute("not_found", true); + }); + }); + } + + } else + { _handle_connection_events(msg); } @@ -1326,10 +1481,6 @@ struct Wifi::Frontend return; } - if (_rfkilled) { - Genode::warning(__func__, ": rfkilled with ", state_strings(_state)); - } - _last_recv_id = recv_id; switch (_state & 0xf) { @@ -1353,7 +1504,7 @@ struct Wifi::Frontend if (_verbose_state) { Genode::log("State:", - " connected: ", _connected_ap.valid(), + " connected: ", _connected_ap.bssid_valid(), " connecting: ", _connecting.length() > 1, " enabled: ", _count_enabled(), " stored: ", _count_stored(), @@ -1392,6 +1543,8 @@ struct Wifi::Frontend try { _ap_reporter.construct(env, "accesspoints"); _ap_reporter->enabled(true); + + Genode::Reporter::Xml_generator xml(*_ap_reporter, [&] () { }); } catch (...) { Genode::warning("no Report session available, scan results will " "not be reported"); @@ -1400,13 +1553,20 @@ struct Wifi::Frontend try { _state_reporter.construct(env, "state"); _state_reporter->enabled(true); + + Genode::Reporter::Xml_generator xml(*_state_reporter, [&] () { + xml.node("accesspoint", [&] () { + xml.attribute("state", "disconnected"); + xml.attribute("rfkilled", _rfkilled); + }); + }); } catch (...) { Genode::warning("no Report session available, connectivity will " "not be reported"); } /* read in list of APs */ - _handle_config_update(); + _config_update(false); /* kick-off initial scanning */ _handle_scan_timer(); diff --git a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc index 516e9976dc..d43f20062f 100644 --- a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc @@ -1418,7 +1418,6 @@ bool flush_work(struct work_struct *work) */ bool const queued = work_queued(work->wq, work); if (queued) { - Genode::error(__func__, " work: ", work, " (", work->func, ") queued"); struct workqueue_struct *wq = work->wq; diff --git a/repos/dde_linux/src/lib/wpa_supplicant/ctrl_iface_genode.c b/repos/dde_linux/src/lib/wpa_supplicant/ctrl_iface_genode.c index 5d9e2b725e..d66d9b6301 100644 --- a/repos/dde_linux/src/lib/wpa_supplicant/ctrl_iface_genode.c +++ b/repos/dde_linux/src/lib/wpa_supplicant/ctrl_iface_genode.c @@ -63,6 +63,7 @@ struct ctrl_iface_global_priv { }; +extern void lx_printf(char const *, ...) __attribute__((format(printf, 1, 2))); extern void nl_set_wpa_ctrl_fd(void); @@ -72,19 +73,19 @@ void wpa_ctrl_set_fd() } -static int send_reply(struct ctrl_iface_priv *priv, char const *txt, size_t len) +static void send_reply(struct ctrl_iface_priv *priv, char const *txt, size_t len) { char *msg = priv->send_buffer; size_t mlen = priv->send_buffer_size; - if (!msg || !len || (len > mlen)) { return -1; } + if (len >= mlen) { + lx_printf("Warning: cmd reply will be truncated\n"); + len = mlen - 1; + } - memset(msg, 0, mlen); memcpy(msg, txt, len); - + msg[len] = 0; (*priv->send_id)++; - - return 0; } @@ -112,7 +113,6 @@ static void wpa_supplicant_ctrl_iface_receive(int fd, void *eloop_ctx, reply = wpa_supplicant_ctrl_iface_process(wpa_s, msg, &reply_len); - // lx_printf("%s:%d %p %zu\n", __func__, __LINE__, reply, reply_len); if (reply) { wifi_notify_cmd_result(); @@ -121,10 +121,12 @@ static void wpa_supplicant_ctrl_iface_receive(int fd, void *eloop_ctx, } else if (reply_len == 1) { + wifi_notify_cmd_result(); send_reply(priv, "FAIL", 4); } else if (reply_len == 2) { + wifi_notify_cmd_result(); send_reply(priv, "OK", 2); } } @@ -139,19 +141,19 @@ static void print_txt(char const *txt, size_t len) } -static int send_event(struct ctrl_iface_priv *priv, char const *txt, size_t len) +static void send_event(struct ctrl_iface_priv *priv, char const *txt, size_t len) { char *msg = priv->event_buffer; size_t mlen = priv->event_buffer_size; - if (!msg || !len || (len > mlen)) { return -1; } + if (len >= mlen) { + lx_printf("Warning: event will be truncated\n"); + len = mlen - 1; + } - memset(msg, 0, mlen); memcpy(msg, txt, len); - + msg[len] = 0; (*priv->event_id)++; - - return 0; } @@ -191,6 +193,7 @@ static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, strncmp(txt, "CTRL-EVENT-SCAN-RESULTS", 23) == 0 || strncmp(txt, "CTRL-EVENT-CONNECTED", 20) == 0 || strncmp(txt, "CTRL-EVENT-DISCONNECTED", 23) == 0 + || strncmp(txt, "CTRL-EVENT-NETWORK-NOT-FOUND", 28) == 0 /* needed to detect connecting state */ || strncmp(txt, "SME: Trying to authenticate", 27) == 0 ; diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc index 53ffc35281..33847c94a7 100644 --- a/repos/ports/run/netperf.inc +++ b/repos/ports/run/netperf.inc @@ -246,9 +246,9 @@ append_if $use_wifi_driver config { -} +} append_if $use_wifi_driver config " - " + " append_if $use_wifi_driver config {