mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-01 16:58:29 +00:00
wifi_drv: enable soft RFKILL and new front end
* TODO
This commit is contained in:
parent
4a47b7cb41
commit
ec9e8ecfaa
45
repos/dde_linux/include/wifi/ctrl.h
Normal file
45
repos/dde_linux/include/wifi/ctrl.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* \brief Wpa_supplicant CTRL interface
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-31
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WIFI__CTRL_H_
|
||||
#define _WIFI__CTRL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define WPA_CTRL_FD 51
|
||||
|
||||
struct Msg_buffer
|
||||
{
|
||||
unsigned char recv[4096];
|
||||
unsigned char send[1024];
|
||||
unsigned recv_id;
|
||||
unsigned send_id;
|
||||
unsigned char event[1024];
|
||||
unsigned event_id;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
void wpa_ctrl_set_fd(void);
|
||||
|
||||
void *wifi_get_buffer(void);
|
||||
void wifi_notify_cmd_result(void);
|
||||
void wifi_notify_event(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _WIFI__CTRL_H_ */
|
26
repos/dde_linux/include/wifi/rfkill.h
Normal file
26
repos/dde_linux/include/wifi/rfkill.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief RFKILL interface
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WIFI__RFKILL_H_
|
||||
#define _WIFI__RFKILL_H_
|
||||
|
||||
|
||||
namespace Wifi {
|
||||
|
||||
enum { RFKILL_FD = 42, };
|
||||
}
|
||||
|
||||
bool wifi_get_rfkill(void);
|
||||
void wifi_set_rfkill(bool);
|
||||
|
||||
#endif /* _WIFI__RFKILL_H_ */
|
@ -8,6 +8,7 @@ SHARED_LIB = yes
|
||||
LD_OPT += --version-script=$(LIB_DIR)/symbol.map
|
||||
|
||||
SRC_CC += dummies.cc ioctl.cc
|
||||
SRC_CC += rfkill_genode.cc
|
||||
|
||||
WS_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/app/wpa_supplicant
|
||||
|
||||
@ -22,8 +23,8 @@ SRC_C_drivers = drivers.c \
|
||||
driver_nl80211_event.c \
|
||||
driver_nl80211_monitor.c \
|
||||
driver_nl80211_scan.c \
|
||||
netlink.c \
|
||||
rfkill.c
|
||||
netlink.c
|
||||
|
||||
SRC_C += $(addprefix src/drivers/, $(SRC_C_drivers))
|
||||
INC_DIR += $(WS_CONTRIB_DIR)/src/drivers \
|
||||
$(WS_CONTRIB_DIR)/src/utils \
|
||||
|
@ -11,10 +11,13 @@ CC_OPT += -Wno-unused-function
|
||||
CC_CXX_OPT += -fpermissive
|
||||
|
||||
SRC_C += main.c ctrl_iface_genode.c
|
||||
SRC_CC += reporter.cc
|
||||
INC_DIR += $(REP_DIR)/include
|
||||
|
||||
|
||||
# wpa_supplicant
|
||||
SRC_C_wpa_supplicant = blacklist.c \
|
||||
bgscan.c \
|
||||
bgscan_simple.c \
|
||||
bss.c \
|
||||
config.c \
|
||||
config_file.c \
|
||||
@ -32,7 +35,8 @@ SRC_C_wpa_supplicant = blacklist.c \
|
||||
SRC_C += $(addprefix wpa_supplicant/, $(SRC_C_wpa_supplicant))
|
||||
INC_DIR += $(WS_CONTRIB_DIR)/wpa_supplicant
|
||||
CC_OPT += -DCONFIG_BACKEND_FILE -DCONFIG_NO_CONFIG_WRITE \
|
||||
-DCONFIG_SME -DCONFIG_CTRL_IFACE
|
||||
-DCONFIG_SME -DCONFIG_CTRL_IFACE \
|
||||
-DCONFIG_BGSCAN -DCONFIG_BGSCAN_SIMPLE
|
||||
|
||||
CC_OPT += -DTLS_DEFAULT_CIPHERS=\"DEFAULT:!EXP:!LOW\"
|
||||
|
||||
|
@ -53,7 +53,7 @@ CC_OPT += -DCONFIG_MAC80211_MESH
|
||||
CC_OPT += -DCONFIG_PM -DCONFIG_PM_SLEEP
|
||||
|
||||
# rfkill
|
||||
CC_OPT += -DCONFIG_RFKILL
|
||||
CC_OPT += -DCONFIG_RFKILL -DCONFIG_RFKILL_INPUT
|
||||
# choose default pid algorithm
|
||||
CC_OPT += -DCONFIG_MAC80211_RC_PID -DCONFIG_MAC80211_RC_DEFAULT=\"pid\"
|
||||
|
||||
|
@ -80,6 +80,19 @@ index 7152fdc..5d133e5 100644
|
||||
.configure_filter = iwl_mvm_configure_filter,
|
||||
.config_iface_filter = iwl_mvm_config_iface_filter,
|
||||
.bss_info_changed = iwl_mvm_bss_info_changed,
|
||||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
||||
index 5d133e5..ec770d4 100644
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
|
||||
@@ -1573,7 +1573,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
- if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
|
||||
+ if (!mvm->mcast_filter_cmd)
|
||||
return;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
||||
index f25ce3a..85007fc 100644
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
|
||||
@ -106,27 +119,28 @@ index 99df171..4632cdf 100644
|
||||
}
|
||||
|
||||
delta = remcsum_adjust(ptr, skb->csum, start, offset);
|
||||
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
|
||||
index 1fdcde9..5f221bd 100644
|
||||
--- a/include/linux/rtnetlink.h
|
||||
+++ b/include/linux/rtnetlink.h
|
||||
@@ -97,9 +97,13 @@ void rtnetlink_init(void);
|
||||
void __rtnl_unlock(void);
|
||||
void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
|
||||
|
||||
+#if 1
|
||||
+#define ASSERT_RTNL()
|
||||
+# else
|
||||
#define ASSERT_RTNL() \
|
||||
WARN_ONCE(!rtnl_is_locked(), \
|
||||
"RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__)
|
||||
+#endif
|
||||
|
||||
extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
||||
index e0f3f4a..a309257 100644
|
||||
--- a/net/packet/af_packet.c
|
||||
+++ b/net/packet/af_packet.c
|
||||
@@ -3977,6 +3977,8 @@ static int packet_notifier(struct notifier_block *this,
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct net *net = dev_net(dev);
|
||||
|
||||
+// XXX check if still needed
|
||||
+#if 0
|
||||
rcu_read_lock();
|
||||
sk_for_each_rcu(sk, &net->packet.sklist) {
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
@@ -4017,6 +4019,7 @@ static int packet_notifier(struct notifier_block *this,
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
+#endif
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@@ -4544,8 +4547,10 @@ static int __net_init packet_net_init(struct net *net)
|
||||
mutex_init(&net->packet.sklist_lock);
|
||||
INIT_HLIST_HEAD(&net->packet.sklist);
|
||||
|
22
repos/dde_linux/patches/wifi_rfkill.patch
Normal file
22
repos/dde_linux/patches/wifi_rfkill.patch
Normal file
@ -0,0 +1,22 @@
|
||||
--- a/net/rfkill/core.c
|
||||
+++ b/net/rfkill/core.c
|
||||
@@ -911,6 +911,19 @@ bool rfkill_blocked(struct rfkill *rfkill)
|
||||
}
|
||||
EXPORT_SYMBOL(rfkill_blocked);
|
||||
|
||||
+bool rfkill_get_any(enum rfkill_type type)
|
||||
+{
|
||||
+ bool blocked = false;
|
||||
+
|
||||
+ struct rfkill *rfkill;
|
||||
+ list_for_each_entry(rfkill, &rfkill_list, node) {
|
||||
+ if (rfkill->type != type && type != RFKILL_TYPE_ALL)
|
||||
+ continue;
|
||||
+
|
||||
+ blocked |= rfkill_blocked(rfkill);
|
||||
+ }
|
||||
+ return blocked;
|
||||
+}
|
||||
|
||||
struct rfkill * __must_check rfkill_alloc(const char *name,
|
||||
struct device *parent,
|
@ -1,7 +1,41 @@
|
||||
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
||||
index 5cff47fab..5cba03efe 100644
|
||||
index 5cff47fab..af08177b2 100644
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -1682,13 +1682,13 @@ static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
|
||||
{
|
||||
struct wpa_driver_nl80211_data *drv = ctx;
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
|
||||
+ wpa_printf(MSG_INFO, "nl80211: RFKILL blocked");
|
||||
|
||||
/*
|
||||
* rtnetlink ifdown handler will report interfaces other than the P2P
|
||||
* Device interface as disabled.
|
||||
*/
|
||||
- if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
|
||||
+ // if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
|
||||
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
|
||||
}
|
||||
|
||||
@@ -1696,7 +1696,7 @@ static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
|
||||
static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
|
||||
{
|
||||
struct wpa_driver_nl80211_data *drv = ctx;
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
|
||||
+ wpa_printf(MSG_INFO, "nl80211: RFKILL unblocked");
|
||||
if (i802_set_iface_flags(drv->first_bss, 1)) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
|
||||
"after rfkill unblock");
|
||||
@@ -1710,7 +1710,7 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
|
||||
* rtnetlink ifup handler will report interfaces other than the P2P
|
||||
* Device interface as enabled.
|
||||
*/
|
||||
- if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
|
||||
+ // if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
|
||||
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
|
||||
}
|
||||
|
||||
@@ -7645,7 +7645,7 @@ static void * nl80211_global_init(void *ctx)
|
||||
if (wpa_driver_nl80211_init_nl_global(global) < 0)
|
||||
goto err;
|
||||
@ -24,8 +58,30 @@ index 0e960f48c..38fb26c18 100644
|
||||
|
||||
struct netlink_data {
|
||||
struct netlink_config *cfg;
|
||||
diff --git a/src/utils/common.c b/src/utils/common.c
|
||||
index 1eb33705b..e4447306a 100644
|
||||
--- a/src/utils/common.c
|
||||
+++ b/src/utils/common.c
|
||||
@@ -498,12 +498,12 @@ void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
|
||||
*txt++ = 't';
|
||||
break;
|
||||
default:
|
||||
- if (data[i] >= 32 && data[i] <= 126) {
|
||||
+ // if (data[i] >= 32 && data[i] <= 126) {
|
||||
*txt++ = data[i];
|
||||
- } else {
|
||||
- txt += os_snprintf(txt, end - txt, "\\x%02x",
|
||||
- data[i]);
|
||||
- }
|
||||
+ // } else {
|
||||
+ // txt += os_snprintf(txt, end - txt, "\\x%02x",
|
||||
+ // data[i]);
|
||||
+ // }
|
||||
break;
|
||||
}
|
||||
}
|
||||
diff --git a/src/utils/eloop.c b/src/utils/eloop.c
|
||||
index 436bc8c99..fd72eaef3 100644
|
||||
index 436bc8c99..f5ff4facb 100644
|
||||
--- a/src/utils/eloop.c
|
||||
+++ b/src/utils/eloop.c
|
||||
@@ -28,7 +28,7 @@
|
||||
@ -37,75 +93,3 @@ index 436bc8c99..fd72eaef3 100644
|
||||
#endif /* CONFIG_ELOOP_POLL */
|
||||
|
||||
#ifdef CONFIG_ELOOP_EPOLL
|
||||
@@ -961,7 +961,7 @@ static void eloop_handle_alarm(int sig)
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
|
||||
-static void eloop_handle_signal(int sig)
|
||||
+void eloop_handle_signal(int sig)
|
||||
{
|
||||
int i;
|
||||
|
||||
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
|
||||
index fb77f1dbd..9142f3f1b 100644
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -1754,6 +1754,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
|
||||
}
|
||||
|
||||
|
||||
+extern void wpa_report_scan_results(struct wpa_supplicant *);
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Return a negative value if no scan results could be fetched or if scan
|
||||
* results should not be shared with other virtual interfaces.
|
||||
@@ -1799,6 +1802,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
|
||||
goto scan_work_done;
|
||||
}
|
||||
|
||||
+ wpa_report_scan_results(wpa_s);
|
||||
+
|
||||
#ifndef CONFIG_NO_RANDOM_POOL
|
||||
num = scan_res->num;
|
||||
if (num > 10)
|
||||
@@ -2813,6 +2818,9 @@ static int disconnect_reason_recoverable(u16 reason_code)
|
||||
}
|
||||
|
||||
|
||||
+void wpa_report_disconnect_event(struct wpa_supplicant *);
|
||||
+
|
||||
+
|
||||
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
|
||||
u16 reason_code,
|
||||
int locally_generated)
|
||||
@@ -2834,6 +2842,7 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
|
||||
|
||||
if (!is_zero_ether_addr(bssid) ||
|
||||
wpa_s->wpa_state >= WPA_AUTHENTICATING) {
|
||||
+ wpa_report_disconnect_event(wpa_s);
|
||||
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
|
||||
" reason=%d%s",
|
||||
MAC2STR(bssid), reason_code,
|
||||
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
|
||||
index 185a8d50f..4baedabb3 100644
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -822,6 +822,9 @@ void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
|
||||
}
|
||||
|
||||
|
||||
+void wpa_report_connect_event(struct wpa_supplicant *);
|
||||
+
|
||||
+
|
||||
/**
|
||||
* wpa_supplicant_set_state - Set current connection state
|
||||
* @wpa_s: Pointer to wpa_supplicant data
|
||||
@@ -879,6 +882,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
|
||||
|
||||
if (state == WPA_COMPLETED && wpa_s->new_connection) {
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
+ wpa_report_connect_event(wpa_s);
|
||||
int fils_hlp_sent = 0;
|
||||
|
||||
#ifdef CONFIG_SME
|
||||
|
@ -1 +1 @@
|
||||
d2628a8fe8df14dd00d5fa8ef6bbea527d319bee
|
||||
f8b3fc722728da35627dcd064209debe9e6aed92
|
||||
|
@ -129,6 +129,7 @@ PATCH_OPT(patches/lxip_skbuff_cast.patch) := $(LXIP_OPT)
|
||||
WIFI_OPT = -p1 -d$(SRC_DIR_WIFI)
|
||||
PATCH_OPT(patches/wifi.patch) := $(WIFI_OPT)
|
||||
PATCH_OPT(patches/wifi_mem.patch) := $(WIFI_OPT)
|
||||
PATCH_OPT(patches/wifi_rfkill.patch) := $(WIFI_OPT)
|
||||
|
||||
# libnl
|
||||
PATCH_OPT(patches/libnl.patch) := -p1 -d ${DIR(libnl)}
|
||||
|
@ -1,17 +1,16 @@
|
||||
<runtime ram="54M" caps="300" binary="wifi_drv">
|
||||
<runtime ram="32M" caps="300" binary="wifi_drv">
|
||||
|
||||
<requires> <rom label="wlan_configuration"/> </requires>
|
||||
<requires> <rom label="wifi_config"/> </requires>
|
||||
<provides> <nic/> </provides>
|
||||
|
||||
<config ld_verbose="yes" verbose="yes" use_11n="no" connected_scan_interval="0">
|
||||
<config ld_verbose="yes" verbose="no">
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <rtc/> <null/>
|
||||
<jitterentropy name="random"/>
|
||||
<jitterentropy name="urandom"/>
|
||||
</dir>
|
||||
<dir name="config"> <ram/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/null" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||
<libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
|
||||
</config>
|
||||
|
||||
<content>
|
||||
|
@ -1,23 +1,36 @@
|
||||
#
|
||||
# Configure wireless lan
|
||||
#
|
||||
|
||||
proc wifi_ssid { } {
|
||||
return $::env(GENODE_WIFI_SSID)
|
||||
}
|
||||
|
||||
proc wifi_psk { } {
|
||||
return $::env(GENODE_WIFI_PSK)
|
||||
}
|
||||
|
||||
#
|
||||
# Restrict platforms
|
||||
#
|
||||
assert_spec x86
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer drivers/wifi
|
||||
drivers/rtc
|
||||
drivers/timer
|
||||
drivers/wifi
|
||||
server/report_rom
|
||||
server/dynamic_rom
|
||||
test/lwip/http_srv
|
||||
lib/vfs/jitterentropy
|
||||
lib/vfs/lwip
|
||||
}
|
||||
|
||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
||||
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
|
||||
return gpio_drv }
|
||||
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
@ -29,7 +42,7 @@ create_boot_directory
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
@ -49,69 +62,85 @@ set config {
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="rtc_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Rtc"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="test-lwip_httpsrv">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<config>
|
||||
<libc stdout="/dev/log" stderr="/dev/log">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
</libc>
|
||||
<libc stdout="/dev/null" stderr="/dev/log" socket="/socket"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <null/> </dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config/>
|
||||
<config verbose="no"/>
|
||||
</start>
|
||||
|
||||
<start name="config_rom">
|
||||
<binary name="dynamic_rom"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="ROM"/></provides>
|
||||
<config verbose="yes">
|
||||
<rom name="wlan_configuration">
|
||||
<inline description="DISCONNECT"> <selected_network/> </inline>
|
||||
<sleep milliseconds="10000"/> <!-- 10 seconds -->
|
||||
<inline description="CONNECT">}
|
||||
append config "<selected_network ssid=\"$::env(GENODE_WIFI_SSID)\" protection=\"WPA-PSK\" psk=\"$::env(GENODE_WIFI_PSK)\"/>"
|
||||
append config {
|
||||
<rom name="wifi_config">
|
||||
<inline description="connect">
|
||||
<wifi_config connected_scan_interval="30" scan_interval="5" rfkill="no" verbose="yes">
|
||||
<accesspoint ssid="} [wifi_ssid] {" protection="WPA2" passphrase="} [wifi_psk] {"/>
|
||||
</wifi_config>
|
||||
</inline>
|
||||
<sleep milliseconds="300000"/> <!-- 5 minutes -->
|
||||
<sleep milliseconds="60000"/>
|
||||
<inline description="rfkill block">
|
||||
<wifi_config connected_scan_interval="30" scan_interval="5" rfkill="yes" verbose="yes">
|
||||
<accesspoint ssid="} [wifi_ssid] {" protection="WPA2" passphrase="} [wifi_psk] {"/>
|
||||
</wifi_config>
|
||||
</inline>
|
||||
<sleep milliseconds="30000"/>
|
||||
<inline description="rfkill unblock">
|
||||
<wifi_config connected_scan_interval="30" scan_interval="5" rfkill="no" verbose="yes">
|
||||
<accesspoint ssid="} [wifi_ssid] {" protection="WPA2" passphrase="} [wifi_psk] {"/>
|
||||
</wifi_config>
|
||||
</inline>
|
||||
<sleep milliseconds="30000"/>
|
||||
<inline description="disconnect">
|
||||
<wifi_config connected_scan_interval="30" scan_interval="5" rfkill="no" verbose="yes">
|
||||
<accesspoint ssid="} [wifi_ssid] {" protection="WPA2" passphrase="} [wifi_psk] {"/>
|
||||
</wifi_config>
|
||||
</inline>
|
||||
<sleep milliseconds="60000"/>
|
||||
</rom>
|
||||
</config>
|
||||
</start>
|
||||
<start name="wifi_drv" caps="220">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
|
||||
<start name="wifi_drv" caps="200">
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
<config ld_verbose="yes" verbose="yes" connected_scan_interval="30">
|
||||
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||
<config ld_verbose="yes">
|
||||
<libc stdout="/dev/null" stderr="/dev/null" rtc="/dev/rtc"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <rtc/>
|
||||
<dir name="dev"> <log/> <null/> <rtc/>
|
||||
<jitterentropy name="random"/>
|
||||
<jitterentropy name="urandom"/>
|
||||
</dir>
|
||||
<dir name="config"> <ram/> </dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Rtc"> <any-child/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="wlan_configuration"> <child name="config_rom"/> </service>
|
||||
<service name="ROM" label="wifi_config"> <child name="config_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append_if [have_spec gpio] config "
|
||||
<start name=\"[gpio_drv]\">
|
||||
<resource name=\"RAM\" quantum=\"4M\"/>
|
||||
<provides><service name=\"Gpio\"/></provides>
|
||||
<config/>
|
||||
</start>"
|
||||
|
||||
append config {
|
||||
</config>
|
||||
}
|
||||
@ -137,19 +166,18 @@ set firmware_modules {
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer rtc_drv report_rom dynamic_rom
|
||||
vfs_jitterentropy.lib.so posix.lib.so
|
||||
libc.lib.so vfs.lib.so libm.lib.so libcrypto.lib.so libssl.lib.so
|
||||
vfs_jitterentropy.lib.so
|
||||
libc.lib.so vfs.lib.so libcrypto.lib.so libssl.lib.so
|
||||
wpa_driver_nl80211.lib.so wpa_supplicant.lib.so
|
||||
wifi.lib.so
|
||||
wifi_drv
|
||||
|
||||
test-lwip_httpsrv lwip_legacy.lib.so
|
||||
test-lwip_httpsrv
|
||||
vfs_lwip.lib.so
|
||||
}
|
||||
|
||||
append boot_modules $firmware_modules
|
||||
|
||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
1467
repos/dde_linux/src/drivers/wifi/frontend.h
Normal file
1467
repos/dde_linux/src/drivers/wifi/frontend.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,247 +13,104 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <libc/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* local includes */
|
||||
#include "wpa.h"
|
||||
|
||||
typedef long long ssize_t;
|
||||
|
||||
extern void wifi_init(Genode::Env&, Genode::Lock&, bool);
|
||||
extern "C" void wpa_conf_reload(void);
|
||||
extern "C" ssize_t wpa_write_conf(char const *, Genode::size_t);
|
||||
|
||||
static Genode::Lock &wpa_startup_lock()
|
||||
{
|
||||
static Genode::Lock _l(Genode::Lock::LOCKED);
|
||||
return _l;
|
||||
}
|
||||
#include <util.h>
|
||||
#include <wpa.h>
|
||||
#include <frontend.h>
|
||||
|
||||
|
||||
namespace {
|
||||
template <Genode::size_t CAPACITY>
|
||||
class Buffer
|
||||
{
|
||||
private:
|
||||
|
||||
char _data[CAPACITY] { 0 };
|
||||
Genode::size_t _length { 0 };
|
||||
|
||||
public:
|
||||
|
||||
void reset() { _data[0] = 0; _length = 0; }
|
||||
char const *data() const { return _data; }
|
||||
Genode::size_t length() const { return _length; }
|
||||
|
||||
void append(char const *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::String_console sc(_data + _length, CAPACITY - _length);
|
||||
sc.vprintf(format, list);
|
||||
va_end(list);
|
||||
|
||||
_length += sc.len();
|
||||
}
|
||||
};
|
||||
} /* anonymous namespace */
|
||||
static Wifi::Frontend *_wifi_frontend = nullptr;
|
||||
|
||||
|
||||
/**
|
||||
* Generate wpa_supplicant.conf file
|
||||
* Notify front end about command processing
|
||||
*
|
||||
* Called by the CTRL interface after wpa_supplicant has processed
|
||||
* the command.
|
||||
*/
|
||||
static int generatewpa_supplicant_conf(char const **p, Genode::size_t *len, char const *ssid,
|
||||
char const *bssid, bool protection = false, char const *psk = 0)
|
||||
void wifi_notify_cmd_result(void)
|
||||
{
|
||||
static char const *start_fmt = "network={\n\tscan_ssid=1\n";
|
||||
static char const *ssid_fmt = "\tssid=\"%s\"\n";
|
||||
static char const *bssid_fmt = "\tbssid=%s\n";
|
||||
static char const *prot_fmt = "\tkey_mgmt=%s\n";
|
||||
static char const *psk_fmt = "\tpsk=\"%s\"\n";
|
||||
static char const *end_fmt = "}\n";
|
||||
if (!_wifi_frontend) {
|
||||
Genode::warning("frontend not available, dropping notification");
|
||||
return;
|
||||
}
|
||||
|
||||
static Buffer<256> buffer;
|
||||
buffer.reset();
|
||||
/*
|
||||
* Next time we block as long as the front end has not finished
|
||||
* handling our previous request
|
||||
*/
|
||||
_wifi_frontend->block_for_processing();
|
||||
|
||||
buffer.append(start_fmt);
|
||||
/* XXX hack to trick poll() into returning faster */
|
||||
wpa_ctrl_set_fd();
|
||||
|
||||
if (ssid)
|
||||
buffer.append(ssid_fmt, ssid);
|
||||
|
||||
if (bssid)
|
||||
buffer.append(bssid_fmt, bssid);
|
||||
|
||||
if (protection)
|
||||
buffer.append(psk_fmt, psk);
|
||||
|
||||
buffer.append(prot_fmt, protection ? "WPA-PSK" : "NONE");
|
||||
|
||||
buffer.append(end_fmt);
|
||||
|
||||
*p = buffer.data();
|
||||
*len = buffer.length();
|
||||
|
||||
return 0;
|
||||
Genode::Signal_transmitter(_wifi_frontend->result_sigh()).submit();
|
||||
}
|
||||
|
||||
|
||||
struct Wlan_configration
|
||||
/**
|
||||
* Notify front end about triggered event
|
||||
*
|
||||
* Called by the CTRL interface whenever wpa_supplicant has triggered
|
||||
* a event.
|
||||
*/
|
||||
void wifi_notify_event(void)
|
||||
{
|
||||
Genode::Attached_rom_dataspace config_rom;
|
||||
Genode::Signal_handler<Wlan_configration> dispatcher;
|
||||
Genode::Lock update_lock;
|
||||
|
||||
char const *buffer;
|
||||
Genode::size_t size;
|
||||
|
||||
/**
|
||||
* Write configuration buffer to conf file to activate the new configuration.
|
||||
*/
|
||||
void _activate_configuration()
|
||||
{
|
||||
if (wpa_write_conf(buffer, size) == 0) {
|
||||
Genode::log("Reload wpa_supplicant configuration");
|
||||
wpa_conf_reload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write dummy configuration buffer to conf file to activate the new
|
||||
* configuration.
|
||||
*/
|
||||
void _active_dummy_configuration()
|
||||
{
|
||||
generatewpa_supplicant_conf(&buffer, &size, "dummyssid", "00:00:00:00:00:00");
|
||||
_activate_configuration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the conf file used by the wpa_supplicant.
|
||||
*/
|
||||
void _update_configuration()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Lock::Guard guard(update_lock);
|
||||
|
||||
config_rom.update();
|
||||
|
||||
/**
|
||||
* We generate a dummy configuration because there is no valid
|
||||
* configuration yet to fool wpa_supplicant to keep it scanning
|
||||
* for the non exisiting network.
|
||||
*/
|
||||
if (!config_rom.valid()) {
|
||||
_active_dummy_configuration();
|
||||
if (!_wifi_frontend) {
|
||||
Genode::warning("frontend not available, dropping notification");
|
||||
return;
|
||||
}
|
||||
|
||||
Xml_node node(config_rom.local_addr<char>(), config_rom.size());
|
||||
Genode::Signal_transmitter(_wifi_frontend->event_sigh()).submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Since <selected_accesspoint/> is empty or missing an ssid attribute
|
||||
* we also generate a dummy configuration.
|
||||
|
||||
/**
|
||||
* Return shared-memory message buffer
|
||||
*
|
||||
* It is used by the wpa_supplicant CTRL interface.
|
||||
*/
|
||||
if (!node.has_attribute("ssid")) {
|
||||
_active_dummy_configuration();
|
||||
return;
|
||||
}
|
||||
void *wifi_get_buffer(void)
|
||||
{
|
||||
return _wifi_frontend ? &_wifi_frontend->msg_buffer() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to generate a valid configuration.
|
||||
*/
|
||||
enum { MAX_SSID_LENGTH = 32 + 1,
|
||||
BSSID_LENGTH = 12 + 5 + 1,
|
||||
PROT_LENGTH = 7 + 1,
|
||||
MIN_PSK_LENGTH = 8 + 1,
|
||||
MAX_PSK_LENGTH = 63 + 1};
|
||||
|
||||
String<MAX_SSID_LENGTH> ssid;
|
||||
node.attribute("ssid").value(&ssid);
|
||||
|
||||
bool use_bssid = node.has_attribute("bssid");
|
||||
String<BSSID_LENGTH> bssid;
|
||||
if (use_bssid)
|
||||
node.attribute("bssid").value(&bssid);
|
||||
|
||||
bool use_protection = false;
|
||||
if (node.has_attribute("protection")) {
|
||||
String<PROT_LENGTH> prot;
|
||||
node.attribute("protection").value(&prot);
|
||||
use_protection = (prot == "WPA-PSK");
|
||||
}
|
||||
|
||||
String<MAX_PSK_LENGTH> psk;
|
||||
if (use_protection && node.has_attribute("psk"))
|
||||
node.attribute("psk").value(&psk);
|
||||
|
||||
/* psk must be between 8 and 63 characters long */
|
||||
if (use_protection && (psk.length() < MIN_PSK_LENGTH)) {
|
||||
Genode::error("given pre-shared key is too short");
|
||||
_active_dummy_configuration();
|
||||
return;
|
||||
}
|
||||
|
||||
if (generatewpa_supplicant_conf(&buffer, &size, ssid.string(),
|
||||
use_bssid ? bssid.string() : 0,
|
||||
use_protection, psk.string()) == 0)
|
||||
_activate_configuration();
|
||||
}
|
||||
|
||||
void _handle_update()
|
||||
{
|
||||
Libc::with_libc([&] () { _update_configuration(); });
|
||||
}
|
||||
|
||||
Wlan_configration(Genode::Env &env)
|
||||
:
|
||||
config_rom(env, "wlan_configuration"),
|
||||
dispatcher(env.ep(), *this, &Wlan_configration::_handle_update)
|
||||
{
|
||||
config_rom.sigh(dispatcher);
|
||||
_update_configuration();
|
||||
}
|
||||
};
|
||||
/* exported by wifi.lib.so */
|
||||
extern void wifi_init(Genode::Env&, Genode::Lock&, bool, Genode::Signal_context_capability);
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
|
||||
Genode::Attached_rom_dataspace config_rom { env, "config" };
|
||||
Genode::Constructible<Wpa_thread> _wpa;
|
||||
Genode::Constructible<Wifi::Frontend> _frontend;
|
||||
|
||||
Wpa_thread *wpa;
|
||||
Wlan_configration *wlan_config;
|
||||
Genode::Lock _wpa_startup_lock { Genode::Lock::LOCKED };
|
||||
|
||||
Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
bool const verbose = config_rom.xml().attribute_value("verbose", false);
|
||||
long const interval = config_rom.xml().attribute_value("connected_scan_interval", 0L);
|
||||
_frontend.construct(env);
|
||||
_wifi_frontend = &*_frontend;
|
||||
|
||||
_wpa.construct(env, _wpa_startup_lock);
|
||||
_wpa->start();
|
||||
|
||||
/*
|
||||
* Forcefully disable 11n but for convenience the attribute is used the
|
||||
* other way araound.
|
||||
*/
|
||||
bool const disable_11n = !config_rom.xml().attribute_value("use_11n", true);
|
||||
|
||||
wpa = new (&heap) Wpa_thread(env, wpa_startup_lock(), verbose, interval);
|
||||
|
||||
wpa->start();
|
||||
|
||||
try {
|
||||
wlan_config = new (&heap) Wlan_configration(env);
|
||||
} catch (...) {
|
||||
Genode::warning("could not create Wlan_configration handler");
|
||||
}
|
||||
|
||||
wifi_init(env, wpa_startup_lock(), disable_11n);
|
||||
bool const disable_11n = !_frontend->use_11n();
|
||||
wifi_init(env, _wpa_startup_lock, disable_11n,
|
||||
_frontend->rfkill_sigh());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7,5 +7,6 @@ LIBS += wpa_supplicant
|
||||
|
||||
# needed for firmware.h
|
||||
INC_DIR += $(REP_DIR)/src/lib/wifi/include
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
90
repos/dde_linux/src/drivers/wifi/util.h
Normal file
90
repos/dde_linux/src/drivers/wifi/util.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* \brief Wifi front end utilities
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _WIFI__UTIL_H_
|
||||
#define _WIFI__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
|
||||
typedef unsigned long size_t;
|
||||
typedef long long ssize_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
|
||||
namespace Util {
|
||||
|
||||
using size_t = Genode::size_t;
|
||||
using uint8_t = Genode::uint8_t;
|
||||
|
||||
size_t next_char(char const *s, size_t start, char const c)
|
||||
{
|
||||
size_t v = start;
|
||||
while (s[v]) {
|
||||
if (s[v] == c) { break; }
|
||||
v++;
|
||||
}
|
||||
return v - start;
|
||||
}
|
||||
|
||||
bool string_contains(char const *str, char const *pattern)
|
||||
{
|
||||
char const *p = pattern;
|
||||
while (*str && *p) {
|
||||
p = *str == *p ? p + 1 : pattern;
|
||||
str++;
|
||||
}
|
||||
return !*p;
|
||||
}
|
||||
|
||||
void byte2hex(char *dest, uint8_t b)
|
||||
{
|
||||
int i = 1;
|
||||
if (b < 16) { dest[i--] = '0'; }
|
||||
|
||||
for (; b > 0; b /= 16) {
|
||||
uint8_t const v = b % 16;
|
||||
uint8_t const c = (v > 9) ? v + 'a' - 10 : v + '0';
|
||||
dest[i--] = (char)c;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************
|
||||
** Front end specific utilities **
|
||||
**********************************/
|
||||
|
||||
inline unsigned approximate_quality(char const *str)
|
||||
{
|
||||
long level = 0;
|
||||
Genode::ascii_to(str, level);
|
||||
|
||||
/*
|
||||
* We provide an quality value by transforming the actual
|
||||
* signal level [-50,-100] (dBm) to [100,0] (%).
|
||||
*/
|
||||
if (level <= -100) { return 0; }
|
||||
else if (level >= -50) { return 100; }
|
||||
|
||||
return 2 * (level + 100);
|
||||
}
|
||||
|
||||
inline unsigned check_time(unsigned value, unsigned min, unsigned max)
|
||||
{
|
||||
if (value < min) { return min; }
|
||||
else if (value > max) { return max; }
|
||||
return value;
|
||||
}
|
||||
|
||||
} /* namespace Util */
|
||||
|
||||
#endif /* _WIFI__UTIL_H_ */
|
@ -18,9 +18,7 @@
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* entry function */
|
||||
extern "C" int wpa_main(int debug_msg, int connected_scan_interval);
|
||||
extern "C" void wpa_reporter_init(void *env);
|
||||
extern "C" void wpa_conf_reload(void);
|
||||
extern "C" int wpa_main(void);
|
||||
|
||||
class Wpa_thread : public Genode::Thread
|
||||
{
|
||||
@ -28,26 +26,20 @@ class Wpa_thread : public Genode::Thread
|
||||
|
||||
Genode::Lock &_lock;
|
||||
int _exit;
|
||||
bool _debug_msg;
|
||||
int _connected_scan_interval;
|
||||
|
||||
public:
|
||||
|
||||
Wpa_thread(Genode::Env &env, Genode::Lock &lock,
|
||||
bool debug_msg, int connected_scan_interval)
|
||||
Wpa_thread(Genode::Env &env, Genode::Lock &lock)
|
||||
:
|
||||
Thread(env, "wpa_supplicant", 8*1024*sizeof(long)),
|
||||
_lock(lock), _exit(-1),
|
||||
_debug_msg(debug_msg), _connected_scan_interval(connected_scan_interval)
|
||||
{
|
||||
wpa_reporter_init(&env);
|
||||
}
|
||||
_lock(lock), _exit(-1)
|
||||
{ }
|
||||
|
||||
void entry()
|
||||
{
|
||||
/* wait until the wifi driver is up and running */
|
||||
_lock.lock();
|
||||
_exit = wpa_main(_debug_msg, _connected_scan_interval);
|
||||
_exit = wpa_main();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
};
|
||||
|
@ -72,9 +72,9 @@ class Socket_registry
|
||||
{
|
||||
private :
|
||||
|
||||
/* abritary value (it goes to eleven!) */
|
||||
enum {
|
||||
SOCKETS_INITIAL_VALUE = 11,
|
||||
/* lower FDs might be special */
|
||||
SOCKETS_OFFSET_VALUE = 100,
|
||||
MAX_SOCKETS = 7,
|
||||
};
|
||||
|
||||
@ -99,7 +99,7 @@ class Socket_registry
|
||||
if (sfd.s != nullptr) { return false; }
|
||||
|
||||
sfd.s = s;
|
||||
sfd.fd = ++_sockets;
|
||||
sfd.fd = (++_sockets & 0xff) + SOCKETS_OFFSET_VALUE;
|
||||
|
||||
/* return fd */
|
||||
fd = sfd.fd;
|
||||
@ -144,7 +144,7 @@ class Socket_registry
|
||||
};
|
||||
|
||||
Socket_fd Socket_registry::_socket_fd[MAX_SOCKETS] = {};
|
||||
unsigned Socket_registry::_sockets = Socket_registry::SOCKETS_INITIAL_VALUE;
|
||||
unsigned Socket_registry::_sockets = 0;
|
||||
|
||||
|
||||
extern "C" {
|
||||
@ -480,10 +480,36 @@ int fcntl(int fd, int cmd, ... /* arg */ )
|
||||
** sys/poll.h **
|
||||
****************/
|
||||
|
||||
static bool _ctrl_fd_set = false;
|
||||
|
||||
|
||||
extern "C" void nl_set_wpa_ctrl_fd()
|
||||
{
|
||||
_ctrl_fd_set = true;
|
||||
}
|
||||
|
||||
static bool special_fd(int fd)
|
||||
{
|
||||
/*
|
||||
* This range is used by the CTRL and RFKILL fds.
|
||||
*/
|
||||
return (fd > 40 && fd < 60);
|
||||
}
|
||||
|
||||
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
Poll_socket_fd sockets[Wifi::MAX_POLL_SOCKETS];
|
||||
unsigned num = 0;
|
||||
int nready = 0;
|
||||
|
||||
/* handle special FDs first */
|
||||
for (nfds_t i = 0; i < nfds; i++) {
|
||||
if (!special_fd(fds[i].fd)) { continue; }
|
||||
|
||||
fds[i].revents = 0;
|
||||
fds[i].revents |= POLLIN;
|
||||
nready++;
|
||||
}
|
||||
|
||||
for (nfds_t i = 0; i < nfds; i++) {
|
||||
Socket *s = Socket_registry::find(fds[i].fd);
|
||||
@ -504,11 +530,16 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
num++;
|
||||
}
|
||||
|
||||
int nready = socket_call.poll_all(sockets, num, timeout);
|
||||
if (!nready)
|
||||
return 0;
|
||||
if (nready < 0)
|
||||
return -1;
|
||||
/* make sure we do not block in poll_all */
|
||||
if (_ctrl_fd_set) {
|
||||
_ctrl_fd_set = false;
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
int sready = socket_call.poll_all(sockets, num, timeout);
|
||||
if (sready < 0 || sready == 0) { return nready; }
|
||||
|
||||
nready += sready;
|
||||
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
int revents = sockets[i].revents;
|
||||
|
@ -132,18 +132,18 @@ DUMMY_SKIP(0, in_irq) /* XXX */
|
||||
|
||||
DUMMY_SKIP(0, local_bh_disable)
|
||||
DUMMY_SKIP(0, local_bh_enable)
|
||||
DUMMY_SKIP(0, dma_unmap_page)
|
||||
|
||||
DUMMY_SKIP(0, dma_set_coherent_mask) /* we set the mask always to ~0UL */
|
||||
DUMMY_SKIP(0, dma_set_mask) /* in the PCI driver */
|
||||
DUMMY(-1, dma_sync_single_for_cpu)
|
||||
DUMMY(-1, dma_sync_single_for_device)
|
||||
|
||||
|
||||
/* XXX DUMMY_SKIP safe? */
|
||||
DUMMY_SKIP(0, dma_sync_single_for_cpu)
|
||||
DUMMY_SKIP(0, dma_sync_single_for_device)
|
||||
/*
|
||||
* There is no actual mapping going on as the memory is always
|
||||
* allocated from the DMA backend. It is safe to _not_ implement
|
||||
* the unmap functions.
|
||||
*/
|
||||
DUMMY_SKIP(0, dma_unmap_page)
|
||||
DUMMY_SKIP(0, dma_unmap_single)
|
||||
DUMMY_SKIP(0, kunmap)
|
||||
DUMMY_SKIP(0, kunmap_atomic)
|
||||
|
||||
DUMMY_SKIP(-1, dump_stack)
|
||||
DUMMY_SKIP(-1, gfp_pfmemalloc_allowed)
|
||||
@ -189,9 +189,6 @@ DUMMY(0, device_rename)
|
||||
DUMMY(0, device_unregister)
|
||||
DUMMY(0, do_posix_clock_monotonic_gettime)
|
||||
DUMMY(0, do_softirq)
|
||||
DUMMY(0, flush_delayed_work)
|
||||
DUMMY(0, flush_work)
|
||||
DUMMY(0, flush_workqueue)
|
||||
DUMMY(0, genl_dump_check_consistent)
|
||||
DUMMY(0, genl_info_net)
|
||||
DUMMY(0, genlmsg_cancel)
|
||||
@ -370,9 +367,8 @@ DUMMY(0, __hw_addr_sync)
|
||||
DUMMY(0, __hw_addr_unsync)
|
||||
DUMMY_SKIP(0, dev_alloc_name)
|
||||
DUMMY(0, dev_change_net_namespace)
|
||||
DUMMY(0, dev_close)
|
||||
DUMMY(0, dev_kfree_skb_any)
|
||||
DUMMY_SKIP(0, dev_net_set)
|
||||
DUMMY(0, dev_net_set)
|
||||
DUMMY(0, dev_open)
|
||||
DUMMY_SKIP(0, dev_hold)
|
||||
DUMMY_SKIP(0, dev_put)
|
||||
@ -406,7 +402,6 @@ DUMMY(0, request_firmware)
|
||||
DUMMY(0, tcp_v4_check)
|
||||
DUMMY(0, sk_attach_filter)
|
||||
|
||||
DUMMY(0, __class_create)
|
||||
DUMMY(0, __module_get)
|
||||
DUMMY(0, __sock_recv_timestamp)
|
||||
DUMMY(0, __sock_recv_wifi_status)
|
||||
@ -449,12 +444,6 @@ DUMMY(0, regulator_enable)
|
||||
DUMMY(0, regulator_get_exclusive)
|
||||
DUMMY(0, regulator_is_enabled)
|
||||
DUMMY(0, regulator_put)
|
||||
DUMMY(0, rfkill_epo)
|
||||
DUMMY(0, rfkill_get_global_sw_state)
|
||||
DUMMY(0, rfkill_is_epo_lock_active)
|
||||
DUMMY(0, rfkill_remove_epo_lock)
|
||||
DUMMY(0, rfkill_restore_states)
|
||||
DUMMY(0, rfkill_switch_all)
|
||||
DUMMY(0, send_sigurg)
|
||||
DUMMY(0, simple_strtoul)
|
||||
DUMMY(0, skb_gro_len)
|
||||
@ -533,7 +522,6 @@ DUMMY(0, release_pages)
|
||||
DUMMY(0, sk_busy_loop)
|
||||
DUMMY(0, sk_can_busy_loop)
|
||||
|
||||
// DUMMY_SKIP(0, complete_all)
|
||||
DUMMY_SKIP(0, simple_strtol)
|
||||
DUMMY_SKIP(0, alg_test)
|
||||
|
||||
@ -550,7 +538,6 @@ DUMMY(0, config_enabled)
|
||||
DUMMY(0, dev_change_proto_down)
|
||||
DUMMY(0, dev_get_iflink)
|
||||
DUMMY(0, dev_get_phys_port_name)
|
||||
DUMMY(-1, device_create_with_groups)
|
||||
DUMMY(0, device_enable_async_suspend)
|
||||
DUMMY(0, fatal_signal_pending)
|
||||
DUMMY_RET(1, file_ns_capable)
|
||||
@ -586,7 +573,7 @@ DUMMY(0, netif_xmit_frozen_or_drv_stopped)
|
||||
DUMMY(0, netif_xmit_frozen_or_stopped)
|
||||
DUMMY_STOP(0, netif_rx_ni)
|
||||
DUMMY_STOP(0, netif_tx_start_all_queues)
|
||||
DUMMY_STOP(0, netif_tx_stop_all_queues)
|
||||
DUMMY(0, netif_tx_stop_all_queues)
|
||||
|
||||
DUMMY(0, peernet_has_id)
|
||||
DUMMY(0, peernet2id_alloc)
|
||||
|
@ -14,7 +14,7 @@
|
||||
/* local includes */
|
||||
#include <lx_emul.h>
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
#define TRACE \
|
||||
do { \
|
||||
lx_printf("%s not implemented from: %p\n", __func__, \
|
||||
@ -141,12 +141,6 @@ unsigned int memalloc_noreclaim_save(void)
|
||||
}
|
||||
|
||||
|
||||
u64 ktime_get_ns(void)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fq_flow *fq_flow_classify(struct fq *fq, struct fq_tin *tin,
|
||||
struct sk_buff *skb,
|
||||
fq_flow_get_default_t get_default_func)
|
||||
@ -510,6 +504,13 @@ void wireless_nlevent_flush(void)
|
||||
|
||||
bool wq_has_sleeper(struct wait_queue_head *wq_head)
|
||||
{
|
||||
TRACE;
|
||||
TRACE_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool sysfs_streq(const char *s1, const char *s2)
|
||||
{
|
||||
TRACE;
|
||||
return false;
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ static inline int no_printk(const char *fmt, ...) { return 0; }
|
||||
#define pr_warn(fmt, ...) printk(KERN_WARN fmt, ##__VA_ARGS__)
|
||||
#define pr_warn_once pr_warn
|
||||
#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__)
|
||||
#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__)
|
||||
#define pr_info(fmt, ...) no_printk(KERN_INFO fmt, ##__VA_ARGS__)
|
||||
#define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__)
|
||||
/* pr_devel() should produce zero code unless DEBUG is defined */
|
||||
#ifdef DEBUG
|
||||
@ -2923,7 +2923,7 @@ unsigned int dev_get_flags(const struct net_device *);
|
||||
struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, struct rtnl_link_stats64 *storage);
|
||||
int dev_change_net_namespace(struct net_device *, struct net *, const char *);
|
||||
int dev_alloc_name(struct net_device *dev, const char *name);
|
||||
int dev_close(struct net_device *dev);
|
||||
void dev_close(struct net_device *dev);
|
||||
int dev_set_mac_address(struct net_device *, struct sockaddr *);
|
||||
int dev_set_mtu(struct net_device *, int);
|
||||
int dev_set_promiscuity(struct net_device *dev, int inc);
|
||||
@ -3245,6 +3245,7 @@ struct file_operations {
|
||||
int (*release) (struct inode *, struct file *);
|
||||
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
|
||||
int (*fasync) (int, struct file *, int);
|
||||
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
||||
};
|
||||
|
||||
static inline loff_t no_llseek(struct file *file, loff_t offset, int origin) {
|
||||
@ -3287,13 +3288,6 @@ struct platform_device {
|
||||
|
||||
};
|
||||
|
||||
/* needed by net/rfkill/rfkill-gpio.c */
|
||||
struct platform_driver {
|
||||
int (*probe)(struct platform_device *);
|
||||
int (*remove)(struct platform_device *);
|
||||
struct device_driver driver;
|
||||
};
|
||||
|
||||
void *platform_get_drvdata(const struct platform_device *pdev);
|
||||
void platform_set_drvdata(struct platform_device *pdev, void *data);
|
||||
struct platform_device *platform_device_register_simple( const char *name, int id, const struct resource *res, unsigned int num);
|
||||
@ -5634,4 +5628,12 @@ int device_property_read_string(struct device *dev, const char *propname, const
|
||||
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
|
||||
/******************************
|
||||
** uapi/asm-generic/ioctl.h **
|
||||
******************************/
|
||||
|
||||
#define _IOC_NR(nr) (nr)
|
||||
#define _IOC_TYPE(nr) (nr)
|
||||
|
||||
#endif /* _LX_EMUL_H_ */
|
||||
|
@ -29,6 +29,62 @@
|
||||
#include <lx_kit/pci.h>
|
||||
|
||||
|
||||
/*********************
|
||||
** RFKILL handling **
|
||||
*********************/
|
||||
|
||||
#include <linux/rfkill.h>
|
||||
|
||||
extern "C" void rfkill_switch_all(enum rfkill_type type, bool blocked);
|
||||
extern "C" bool rfkill_get_any(enum rfkill_type type);
|
||||
|
||||
#include <wifi/rfkill.h>
|
||||
|
||||
bool wifi_get_rfkill(void)
|
||||
{
|
||||
return rfkill_get_any(RFKILL_TYPE_WLAN);
|
||||
}
|
||||
|
||||
|
||||
static Lx::Task *_lx_task = nullptr;
|
||||
static bool _lx_init_done = false;
|
||||
static bool _switch_rfkill = false;
|
||||
static bool _new_blocked = false;
|
||||
static Genode::Signal_context_capability _rfkill_sig_ctx;
|
||||
|
||||
|
||||
void wifi_set_rfkill(bool blocked)
|
||||
{
|
||||
bool const cur = wifi_get_rfkill();
|
||||
|
||||
_switch_rfkill = blocked != cur;
|
||||
if (_lx_init_done && _switch_rfkill) {
|
||||
_new_blocked = blocked;
|
||||
|
||||
_lx_task->unblock();
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** socketcall poll hack **
|
||||
**************************/
|
||||
|
||||
void wifi_kick_socketcall()
|
||||
{
|
||||
/*
|
||||
* Kicking is going to unblock the socketcall task that
|
||||
* probably is waiting in poll_all().
|
||||
*/
|
||||
Lx::socket_kick();
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Initialization handling **
|
||||
*****************************/
|
||||
|
||||
extern "C" void core_netlink_proto_init(void);
|
||||
extern "C" void core_sock_init(void);
|
||||
extern "C" void module_packet_init(void);
|
||||
@ -44,6 +100,7 @@ extern "C" void module_aes_init(void);
|
||||
extern "C" void module_arc4_init(void);
|
||||
// extern "C" void module_chainiv_module_init(void);
|
||||
extern "C" void module_krng_mod_init(void);
|
||||
extern "C" void subsys_leds_init(void);
|
||||
|
||||
extern "C" unsigned int *module_param_11n_disable;
|
||||
|
||||
@ -69,6 +126,7 @@ static void run_linux(void *args)
|
||||
module_packet_init();
|
||||
subsys_genl_init();
|
||||
subsys_rfkill_init();
|
||||
subsys_leds_init();
|
||||
fs_cfg80211_init();
|
||||
subsys_ieee80211_init();
|
||||
|
||||
@ -77,7 +135,6 @@ static void run_linux(void *args)
|
||||
module_crypto_ctr_module_init();
|
||||
module_aes_init();
|
||||
module_arc4_init();
|
||||
// module_chainiv_module_init();
|
||||
|
||||
try {
|
||||
int const err = module_iwl_drv_init();
|
||||
@ -91,15 +148,40 @@ static void run_linux(void *args)
|
||||
|
||||
_wpa_lock->unlock();
|
||||
|
||||
_lx_init_done = true;
|
||||
|
||||
while (1) {
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
|
||||
if (!_switch_rfkill) { continue; }
|
||||
|
||||
Genode::log("RFKILL: ", _new_blocked ? "BLOCKED" : "UNBLOCKED");
|
||||
rfkill_switch_all(RFKILL_TYPE_WLAN, _new_blocked);
|
||||
|
||||
if (!_new_blocked) {
|
||||
try {
|
||||
bool const ok = Lx::open_device();
|
||||
if (!ok) { throw -1; }
|
||||
|
||||
} catch (...) {
|
||||
Genode::Env &env = *(Genode::Env*)args;
|
||||
|
||||
env.parent().exit(1);
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
}
|
||||
|
||||
/* notify front end */
|
||||
Genode::Signal_transmitter(_rfkill_sig_ctx).submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
|
||||
void wifi_init(Genode::Env &env, Genode::Lock &lock, bool disable_11n)
|
||||
void wifi_init(Genode::Env &env, Genode::Lock &lock, bool disable_11n,
|
||||
Genode::Signal_context_capability rfkill)
|
||||
{
|
||||
Lx_kit::construct_env(env);
|
||||
|
||||
@ -128,10 +210,14 @@ void wifi_init(Genode::Env &env, Genode::Lock &lock, bool disable_11n)
|
||||
*module_param_11n_disable = 1;
|
||||
}
|
||||
|
||||
_rfkill_sig_ctx = rfkill;
|
||||
|
||||
/* Linux task (handles the initialization only currently) */
|
||||
static Lx::Task linux(run_linux, &env, "linux",
|
||||
Lx::Task::PRIORITY_0, Lx::scheduler());
|
||||
|
||||
_lx_task = &linux;
|
||||
|
||||
/* give all task a first kick before returning */
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ namespace Lx
|
||||
void emul_init(Genode::Env&, Genode::Allocator&);
|
||||
|
||||
void socket_init(Genode::Entrypoint&, Genode::Allocator&);
|
||||
void socket_kick();
|
||||
|
||||
void nic_init(Genode::Env&, Genode::Allocator&);
|
||||
|
||||
@ -35,6 +36,8 @@ namespace Lx
|
||||
void backend_free(Genode::Ram_dataspace_capability);
|
||||
|
||||
void get_mac_address(unsigned char *);
|
||||
|
||||
bool open_device();
|
||||
}
|
||||
|
||||
#endif /* _LX_H_ */
|
||||
|
@ -443,7 +443,7 @@ core_initcall(sock_init);
|
||||
|
||||
codel_time_t codel_get_time(void)
|
||||
{
|
||||
u64 ns = ktime_get_ns();
|
||||
u64 ns = ktime_get();
|
||||
return ns >> CODEL_SHIFT;
|
||||
}
|
||||
|
||||
@ -479,3 +479,41 @@ u64 ktime_get_boot_ns(void)
|
||||
{
|
||||
return (u64)ktime_get();
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/device.h **
|
||||
********************/
|
||||
|
||||
struct device *device_create_with_groups(struct class *class,
|
||||
struct device *parent, dev_t devt,
|
||||
void *drvdata,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
long ret = -ENODEV;
|
||||
if (class == NULL || IS_ERR(class)) { goto err; }
|
||||
|
||||
struct device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return dev;
|
||||
|
||||
err:
|
||||
return (void*)ret;
|
||||
}
|
||||
|
||||
|
||||
struct class *__class_create(struct module *owner,
|
||||
const char *name,
|
||||
struct lock_class_key *key)
|
||||
{
|
||||
struct class *cls = kzalloc(sizeof(*cls), GFP_KERNEL);
|
||||
if (!cls) { return (void*)-ENOMEM; }
|
||||
|
||||
cls->name = name;
|
||||
return cls;
|
||||
}
|
||||
|
@ -303,8 +303,9 @@ size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
|
||||
|
||||
bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
|
||||
{
|
||||
/* XXX at some point check if i->count > bytes could be a problem */
|
||||
if (bytes > i->count)
|
||||
return false;
|
||||
bytes = i->count;
|
||||
|
||||
if (bytes == 0)
|
||||
return true;
|
||||
@ -730,28 +731,6 @@ time64_t ktime_get_seconds(void)
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workqueue.h **
|
||||
***********************/
|
||||
|
||||
struct workqueue_struct *create_singlethread_workqueue(char const *)
|
||||
{
|
||||
workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
|
||||
return wq;
|
||||
}
|
||||
|
||||
struct workqueue_struct *alloc_ordered_workqueue(char const *name , unsigned int flags, ...)
|
||||
{
|
||||
return create_singlethread_workqueue(name);
|
||||
}
|
||||
|
||||
struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags,
|
||||
int max_active, ...)
|
||||
{
|
||||
return create_singlethread_workqueue(nullptr);
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/dma-mapping.h **
|
||||
*************************/
|
||||
@ -1375,11 +1354,11 @@ void pci_dev_put(struct pci_dev *pci_dev)
|
||||
Genode::destroy(Lx_kit::env().heap(), pci_dev);
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workquque.h **
|
||||
** linux/workqueue.h **
|
||||
***********************/
|
||||
|
||||
/* Linux emul includes */
|
||||
#include <lx_emul/impl/work.h>
|
||||
|
||||
|
||||
@ -1391,6 +1370,88 @@ bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
|
||||
}
|
||||
|
||||
|
||||
struct workqueue_struct *alloc_ordered_workqueue(char const *fmt , unsigned int flags, ...)
|
||||
{
|
||||
return alloc_workqueue(fmt, flags, 1);
|
||||
}
|
||||
|
||||
|
||||
struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags,
|
||||
int max_active, ...)
|
||||
{
|
||||
workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
|
||||
Lx::Work *work = Lx::Work::alloc_work_queue(&Lx::Malloc::mem(), fmt);
|
||||
wq->task = (void *)work;
|
||||
|
||||
return wq;
|
||||
}
|
||||
|
||||
|
||||
void flush_workqueue(struct workqueue_struct *wq)
|
||||
{
|
||||
Lx::Task *current = Lx::scheduler().current();
|
||||
if (!current) {
|
||||
Genode::error("BUG: flush_workqueue executed without task");
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
Lx::Work *lx_work = (wq && wq->task) ? (Lx::Work*) wq->task
|
||||
: &Lx::Work::work_queue();
|
||||
|
||||
lx_work->flush(*current);
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
}
|
||||
|
||||
|
||||
static inline bool work_queued(struct workqueue_struct *wq, void *work)
|
||||
{
|
||||
Lx::Work *lx_work = (wq && wq->task) ? (Lx::Work*) wq->task
|
||||
: &Lx::Work::work_queue();
|
||||
return lx_work->work_queued(work);
|
||||
}
|
||||
|
||||
|
||||
bool flush_work(struct work_struct *work)
|
||||
{
|
||||
/* XXX AFAIU if the work was not queued it is already 'idle' and
|
||||
* we just return false
|
||||
*/
|
||||
bool const queued = work_queued(work->wq, work);
|
||||
if (queued) {
|
||||
Genode::error(__func__, " work: ", work, " (", work->func, ") queued");
|
||||
|
||||
struct workqueue_struct *wq = work->wq;
|
||||
|
||||
Lx::Work *lx_work = (wq && wq->task) ? (Lx::Work*) wq->task
|
||||
: &Lx::Work::work_queue();
|
||||
|
||||
Lx::Task *current = Lx::scheduler().current();
|
||||
lx_work->wakeup_for(work, *current);
|
||||
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool flush_delayed_work(struct delayed_work *dwork)
|
||||
{
|
||||
/* XXX AFAIU if the work was not queued it is already 'idle' and
|
||||
* we just return false
|
||||
*/
|
||||
bool const queued = work_queued(dwork->wq, dwork);
|
||||
if (queued) {
|
||||
Genode::error(__func__, " dwork: ", dwork, " (", dwork->work.func, ") queued");
|
||||
Genode::sleep_forever();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
@ -1512,7 +1573,7 @@ struct Idr
|
||||
if (index == INVALID_ENTRY) { return INVALID_ENTRY; }
|
||||
|
||||
_barray.set(index, 1);
|
||||
_ptr[index] = ptr;
|
||||
_ptr[index] = (addr_t) ptr;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -598,6 +598,57 @@ extern "C" size_t LL_RESERVED_SPACE(struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
extern "C" void dev_close(struct net_device *ndev)
|
||||
{
|
||||
/*
|
||||
* First instruct cfg80211 to leave the associated network
|
||||
* and then shutdown the interface.
|
||||
*/
|
||||
net_notifier().call_all_blocks(NETDEV_GOING_DOWN, ndev);
|
||||
net_notifier().call_all_blocks(NETDEV_DOWN, ndev);
|
||||
|
||||
ndev->state &= ~(1UL << __LINK_STATE_START);
|
||||
netif_carrier_off(ndev);
|
||||
|
||||
const struct net_device_ops *ops = ndev->netdev_ops;
|
||||
if (ops->ndo_stop) { ops->ndo_stop(ndev); }
|
||||
|
||||
ndev->flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
|
||||
bool Lx::open_device()
|
||||
{
|
||||
if (!Root::instance->device) {
|
||||
Genode::error("no net_device available");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct net_device * const ndev = Root::instance->device;
|
||||
|
||||
int err = ndev->netdev_ops->ndo_open(ndev);
|
||||
if (err) {
|
||||
Genode::error("Open device failed");
|
||||
throw -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Important, otherwise netif_running checks fail and AF_PACKET
|
||||
* will not bind and EAPOL will cease to work.
|
||||
*/
|
||||
ndev->flags |= IFF_UP;
|
||||
ndev->state |= (1UL << __LINK_STATE_START);
|
||||
|
||||
if (ndev->netdev_ops->ndo_set_rx_mode)
|
||||
ndev->netdev_ops->ndo_set_rx_mode(ndev);
|
||||
|
||||
net_notifier().call_all_blocks(NETDEV_UP, ndev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int register_netdevice(struct net_device *ndev)
|
||||
{
|
||||
static bool already_registered = false;
|
||||
|
@ -358,8 +358,9 @@ class Lx::Socket
|
||||
case Call::NON_BLOCK: _do_non_block(); break;
|
||||
|
||||
default:
|
||||
_call.err = -EINVAL;
|
||||
Genode::warning("unknown opcode: ", (int)_call.opcode);
|
||||
case Call::NONE: /* ignore silently */
|
||||
_call.err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -372,6 +373,11 @@ class Lx::Socket
|
||||
_sender.submit();
|
||||
_block.down();
|
||||
}
|
||||
|
||||
void unblock_task()
|
||||
{
|
||||
_task.unblock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -387,6 +393,15 @@ void Lx::socket_init(Genode::Entrypoint &ep, Genode::Allocator &alloc)
|
||||
}
|
||||
|
||||
|
||||
void Lx::socket_kick()
|
||||
{
|
||||
/* ignore silently, the function might be called to before init */
|
||||
if (!_socket) { return; }
|
||||
|
||||
_socket->unblock_task();
|
||||
}
|
||||
|
||||
|
||||
static void run_socketcall(void *)
|
||||
{
|
||||
while (1) {
|
||||
|
@ -10,10 +10,15 @@
|
||||
*Socket_call*;
|
||||
/* Wifi::Socket_call instance */
|
||||
socket_call;
|
||||
/* rfkill interface */
|
||||
_*wifi_*_rfkill*;
|
||||
_*wifi_kick_*;
|
||||
|
||||
/* used by libnl's time() */
|
||||
jiffies;
|
||||
|
||||
lx_printf*;
|
||||
|
||||
local:
|
||||
|
||||
*;
|
||||
|
89
repos/dde_linux/src/lib/wpa_driver_nl80211/rfkill_genode.cc
Normal file
89
repos/dde_linux/src/lib/wpa_driver_nl80211/rfkill_genode.cc
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* \brief RFKILL backend
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on:
|
||||
*
|
||||
* Linux rfkill helper functions for driver wrappers
|
||||
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
/* rep includes */
|
||||
#include <wifi/rfkill.h>
|
||||
|
||||
extern "C" {
|
||||
#include "includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
|
||||
#include <drivers/rfkill.h>
|
||||
} /* extern "C" */
|
||||
|
||||
|
||||
struct rfkill_data {
|
||||
struct rfkill_config *cfg;
|
||||
int fd;
|
||||
bool blocked;
|
||||
};
|
||||
|
||||
|
||||
static void rfkill_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
struct rfkill_data * const rfkill = (rfkill_data*)eloop_ctx;
|
||||
bool const new_blocked = wifi_get_rfkill();
|
||||
|
||||
if (new_blocked != rfkill->blocked) {
|
||||
rfkill->blocked = new_blocked;
|
||||
|
||||
if (new_blocked) {
|
||||
rfkill->cfg->blocked_cb(rfkill->cfg->ctx);
|
||||
} else {
|
||||
rfkill->cfg->unblocked_cb(rfkill->cfg->ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct rfkill_data * rfkill_init(struct rfkill_config *cfg)
|
||||
{
|
||||
struct rfkill_data *rfkill = (rfkill_data*) os_zalloc(sizeof(*rfkill));
|
||||
if (!rfkill) { return NULL; }
|
||||
|
||||
rfkill->cfg = cfg;
|
||||
rfkill->fd = Wifi::RFKILL_FD;
|
||||
|
||||
eloop_register_read_sock(rfkill->fd, rfkill_receive, rfkill, NULL);
|
||||
|
||||
return rfkill;
|
||||
}
|
||||
|
||||
|
||||
void rfkill_deinit(struct rfkill_data *rfkill)
|
||||
{
|
||||
if (!rfkill) { return; }
|
||||
|
||||
eloop_unregister_read_sock(rfkill->fd);
|
||||
|
||||
os_free(rfkill->cfg);
|
||||
os_free(rfkill);
|
||||
}
|
||||
|
||||
|
||||
int rfkill_is_blocked(struct rfkill_data *rfkill)
|
||||
{
|
||||
return rfkill ? rfkill->blocked : 0;
|
||||
}
|
@ -12,6 +12,9 @@
|
||||
|
||||
poll;
|
||||
|
||||
/* needed by wpa_supplicant lib for wifi_drv */
|
||||
nl_set_wpa_ctrl_fd;
|
||||
|
||||
local:
|
||||
|
||||
*;
|
||||
|
@ -1,4 +1,19 @@
|
||||
/*
|
||||
* \brief WPA Supplicant frontend
|
||||
* \author Josef Soentgen
|
||||
* \date 2018-07-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on:
|
||||
*
|
||||
* WPA Supplicant / UNIX domain socket -based control interface
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
@ -6,8 +21,8 @@
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
/* wpa_supplicant includes */
|
||||
#include "includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "utils/list.h"
|
||||
@ -17,8 +32,29 @@
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "ctrl_iface.h"
|
||||
|
||||
/* rep includes */
|
||||
#include <wifi/ctrl.h>
|
||||
|
||||
|
||||
struct ctrl_iface_priv {
|
||||
struct wpa_supplicant *wpa_s;
|
||||
int fd;
|
||||
int level;
|
||||
|
||||
/* TODO replace w/ Msg_buffer */
|
||||
char *send_buffer;
|
||||
size_t send_buffer_size;
|
||||
unsigned *send_id;
|
||||
|
||||
char *recv_buffer;
|
||||
size_t recv_buffer_size;
|
||||
unsigned *recv_id;
|
||||
|
||||
unsigned last_recv_id;
|
||||
|
||||
char *event_buffer;
|
||||
size_t event_buffer_size;
|
||||
unsigned *event_id;
|
||||
};
|
||||
|
||||
|
||||
@ -26,71 +62,201 @@ struct ctrl_iface_global_priv {
|
||||
struct wpa_global *global;
|
||||
};
|
||||
|
||||
struct ctrl_iface_msg {
|
||||
struct wpa_supplicant *wpa_s;
|
||||
};
|
||||
|
||||
extern void nl_set_wpa_ctrl_fd(void);
|
||||
|
||||
|
||||
void wpa_ctrl_set_fd()
|
||||
{
|
||||
nl_set_wpa_ctrl_fd();
|
||||
}
|
||||
|
||||
|
||||
static int 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; }
|
||||
|
||||
memset(msg, 0, mlen);
|
||||
memcpy(msg, txt, len);
|
||||
|
||||
(*priv->send_id)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is called by wpa_supplicant whenever it receives a
|
||||
* command via the CTRL interface, i.e. the front end has sent a new
|
||||
* message.
|
||||
*/
|
||||
static void wpa_supplicant_ctrl_iface_receive(int fd, void *eloop_ctx,
|
||||
void *sock_ctx)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||
struct ctrl_iface_priv *priv = sock_ctx;
|
||||
|
||||
char *msg = priv->recv_buffer;
|
||||
|
||||
unsigned const recv_id = *priv->recv_id;
|
||||
|
||||
char *reply = NULL;
|
||||
size_t reply_len = 0;
|
||||
|
||||
if (msg[0] == 0 || recv_id == priv->last_recv_id) { return; }
|
||||
|
||||
priv->last_recv_id = recv_id;
|
||||
|
||||
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();
|
||||
send_reply(priv, reply, reply_len);
|
||||
os_free(reply);
|
||||
} else
|
||||
|
||||
if (reply_len == 1) {
|
||||
send_reply(priv, "FAIL", 4);
|
||||
} else
|
||||
|
||||
if (reply_len == 2) {
|
||||
send_reply(priv, "OK", 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_txt(char const *txt, size_t len)
|
||||
{
|
||||
char buffer[256];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memcpy(buffer, txt, len < sizeof(buffer) - 1 ? len : sizeof(buffer) - 1);
|
||||
lx_printf(" %s\n", buffer);
|
||||
}
|
||||
|
||||
|
||||
static int 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; }
|
||||
|
||||
memset(msg, 0, mlen);
|
||||
memcpy(msg, txt, len);
|
||||
|
||||
(*priv->event_id)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is called by wpa_supplicant whenever it wants to
|
||||
* forward some message. We filter these messages and forward only
|
||||
* those, which are of interest to the front end.
|
||||
*/
|
||||
static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
|
||||
enum wpa_msg_type type,
|
||||
const char *txt, size_t len)
|
||||
{
|
||||
#if 0
|
||||
int const dont_print =
|
||||
strncmp(txt, "BSS:", 4) == 0
|
||||
|| strncmp(txt, "BSS:", 4) == 0
|
||||
|| strncmp(txt, "CTRL-EVENT-BSS", 14) == 0
|
||||
|| strncmp(txt, " skip", 7) == 0
|
||||
;
|
||||
if (!dont_print) { print_txt(txt, len); }
|
||||
#endif
|
||||
|
||||
/* there is not global support */
|
||||
if (type == WPA_MSG_ONLY_GLOBAL) { return; }
|
||||
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
if (wpa_s == NULL) { return; }
|
||||
|
||||
struct ctrl_iface_priv *priv = wpa_s->ctrl_iface;
|
||||
if (!priv || level < priv->level) { return; }
|
||||
|
||||
/*
|
||||
* Filter messages and only forward events the front end cares
|
||||
* about or rather knows how to handle.
|
||||
*/
|
||||
int const forward =
|
||||
strncmp(txt, "CTRL-EVENT-SCAN-RESULTS", 23) == 0
|
||||
|| strncmp(txt, "CTRL-EVENT-CONNECTED", 20) == 0
|
||||
|| strncmp(txt, "CTRL-EVENT-DISCONNECTED", 23) == 0
|
||||
/* needed to detect connecting state */
|
||||
|| strncmp(txt, "SME: Trying to authenticate", 27) == 0
|
||||
;
|
||||
if (!forward) { return; }
|
||||
|
||||
wifi_notify_event();
|
||||
send_event(priv, txt, len);
|
||||
}
|
||||
|
||||
|
||||
struct ctrl_iface_priv *
|
||||
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
printf("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
struct ctrl_iface_priv *priv;
|
||||
|
||||
priv = os_zalloc(sizeof(*priv));
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
if (priv == NULL) { return NULL; }
|
||||
|
||||
if (wpa_s->conf->ctrl_interface == NULL)
|
||||
if (wpa_s->conf->ctrl_interface == NULL) {
|
||||
return priv;
|
||||
}
|
||||
|
||||
struct Msg_buffer *msg_buffer = (struct Msg_buffer*)wifi_get_buffer();
|
||||
priv->recv_buffer = (char *)msg_buffer->send;
|
||||
priv->recv_buffer_size = sizeof(msg_buffer->send);
|
||||
priv->send_buffer = (char *)msg_buffer->recv;
|
||||
priv->send_buffer_size = sizeof(msg_buffer->recv);
|
||||
priv->send_id = &msg_buffer->recv_id;
|
||||
priv->recv_id = &msg_buffer->send_id;
|
||||
|
||||
priv->event_buffer = (char *)msg_buffer->event;
|
||||
priv->event_buffer_size = sizeof(msg_buffer->event);
|
||||
priv->event_id = &msg_buffer->event_id;
|
||||
|
||||
priv->level = MSG_INFO;
|
||||
priv->fd = WPA_CTRL_FD;
|
||||
|
||||
eloop_register_read_sock(priv->fd,
|
||||
wpa_supplicant_ctrl_iface_receive,
|
||||
wpa_s, priv);
|
||||
|
||||
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
|
||||
return priv;
|
||||
}
|
||||
|
||||
|
||||
void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
|
||||
{
|
||||
printf("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
struct wpa_ctrl_dst *dst, *prev;
|
||||
struct ctrl_iface_msg *msg, *prev_msg;
|
||||
struct ctrl_iface_global_priv *gpriv;
|
||||
|
||||
os_free(priv);
|
||||
}
|
||||
|
||||
|
||||
void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
|
||||
{
|
||||
printf("%s:%d\n", __func__, __LINE__);
|
||||
}
|
||||
void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) { }
|
||||
|
||||
|
||||
struct ctrl_iface_global_priv *
|
||||
wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||
{
|
||||
printf("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
struct ctrl_iface_global_priv *priv;
|
||||
|
||||
priv = os_zalloc(sizeof(*priv));
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
if (global->params.ctrl_interface == NULL)
|
||||
return priv;
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
|
||||
void wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
|
||||
void wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *p)
|
||||
{
|
||||
printf("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
struct wpa_ctrl_dst *dst, *prev;
|
||||
struct ctrl_iface_msg *msg, *prev_msg;
|
||||
|
||||
os_free(priv);
|
||||
os_free(p);
|
||||
}
|
||||
|
@ -36,25 +36,8 @@
|
||||
#include "scan.h"
|
||||
|
||||
|
||||
static char const *conf_file = "/config/wpa_supplicant.conf";
|
||||
|
||||
static int connected_scan_interval;
|
||||
|
||||
static void connected_scan_handler(void *eloop_ctx, void *user_ctx)
|
||||
int wpa_main(void)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)eloop_ctx;
|
||||
|
||||
if (wpa_s->wpa_state >= WPA_ASSOCIATED)
|
||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||
|
||||
eloop_register_timeout(connected_scan_interval, 0, connected_scan_handler, wpa_s, 0);
|
||||
}
|
||||
|
||||
|
||||
int wpa_main(int debug_msg, int interval)
|
||||
{
|
||||
connected_scan_interval = interval;
|
||||
|
||||
struct wpa_interface iface;
|
||||
int exitcode = 0;
|
||||
struct wpa_params params;
|
||||
@ -62,7 +45,8 @@ int wpa_main(int debug_msg, int interval)
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
params.wpa_debug_level = debug_msg ? MSG_DEBUG : MSG_INFO;
|
||||
// TODO use CTRL interface for setting debug level
|
||||
params.wpa_debug_level = 1 ? MSG_DEBUG : MSG_INFO;
|
||||
params.ctrl_interface = "GENODE";
|
||||
|
||||
global = wpa_supplicant_init(¶ms);
|
||||
@ -72,15 +56,12 @@ int wpa_main(int debug_msg, int interval)
|
||||
memset(&iface, 0, sizeof(iface));
|
||||
|
||||
iface.ifname = "wlan0";
|
||||
iface.confname = conf_file;
|
||||
iface.confname = 0;
|
||||
iface.ctrl_interface = "GENODE";
|
||||
|
||||
if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL)
|
||||
exitcode = -1;
|
||||
|
||||
if (connected_scan_interval > 0)
|
||||
eloop_register_timeout(connected_scan_interval, 0,
|
||||
connected_scan_handler, global->ifaces, 0);
|
||||
|
||||
if (exitcode == 0)
|
||||
exitcode = wpa_supplicant_run(global);
|
||||
|
||||
@ -88,24 +69,3 @@ int wpa_main(int debug_msg, int interval)
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
|
||||
void eloop_handle_signal(int);
|
||||
void wpa_conf_reload(void)
|
||||
{
|
||||
/* (ab)use POSIX signal to trigger reloading the conf file */
|
||||
eloop_handle_signal(SIGHUP);
|
||||
}
|
||||
|
||||
|
||||
int wpa_write_conf(char const *buffer, size_t len)
|
||||
{
|
||||
int fd = open(conf_file, O_CREAT|O_TRUNC|O_WRONLY);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
ssize_t n = write(fd, buffer, len);
|
||||
close(fd);
|
||||
|
||||
return n > 0 ? 0 : -1;
|
||||
}
|
||||
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* \brief WPA Supplicant frontend
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-12-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/reporter.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* WPA Supplicant includes */
|
||||
extern "C" {
|
||||
#include "includes.h"
|
||||
#include "common.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "bss.h"
|
||||
#include "scan.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
}
|
||||
|
||||
|
||||
static Genode::Constructible<Genode::Reporter> accesspoints_reporter;
|
||||
static Genode::Constructible<Genode::Reporter> state_reporter;
|
||||
|
||||
|
||||
extern "C" void wpa_reporter_init(void *env)
|
||||
{
|
||||
accesspoints_reporter.construct(*static_cast<Genode::Env*>(env), "wlan_accesspoints");
|
||||
accesspoints_reporter->enabled(true);
|
||||
|
||||
state_reporter.construct(*static_cast<Genode::Env*>(env), "wlan_state");
|
||||
state_reporter->enabled(true);
|
||||
}
|
||||
|
||||
|
||||
enum { SSID_STRING_MAX_LEN = 32 + 1, MAC_STR_LEN = 6*2 + 5 + 1};
|
||||
|
||||
|
||||
static inline void mac2str(char *buf, u8 const *mac)
|
||||
{
|
||||
Genode::snprintf(buf, MAC_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wpa_report_connect_event(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
try {
|
||||
Genode::Reporter::Xml_generator xml(*state_reporter, [&]() {
|
||||
struct wpa_ssid *wpa_ssid = wpa_s->current_ssid;
|
||||
|
||||
/* FIXME ssid may contain any characters, even NUL */
|
||||
Genode::String<SSID_STRING_MAX_LEN>
|
||||
ssid(Genode::Cstring((char *)wpa_ssid->ssid, wpa_ssid->ssid_len));
|
||||
|
||||
char bssid_buf[MAC_STR_LEN];
|
||||
mac2str(bssid_buf, wpa_s->bssid);
|
||||
|
||||
xml.node("accesspoint", [&]() {
|
||||
xml.attribute("ssid", ssid.string());
|
||||
xml.attribute("bssid", bssid_buf);
|
||||
xml.attribute("state", "connected");
|
||||
});
|
||||
});
|
||||
} catch (...) { Genode::warning("could not report connected state"); }
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wpa_report_disconnect_event(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
try {
|
||||
Genode::Reporter::Xml_generator xml(*state_reporter, [&]() {
|
||||
struct wpa_ssid *wpa_ssid = wpa_s->current_ssid;
|
||||
|
||||
/* FIXME ssid may contain any characters, even NUL */
|
||||
Genode::String<SSID_MAX_LEN>
|
||||
ssid(Genode::Cstring((char *)wpa_ssid->ssid, wpa_ssid->ssid_len));
|
||||
|
||||
char bssid_buf[MAC_STR_LEN];
|
||||
mac2str(bssid_buf, wpa_ssid->bssid);
|
||||
|
||||
unsigned auth_failures = wpa_ssid->auth_failures;
|
||||
|
||||
xml.node("accesspoint", [&]() {
|
||||
xml.attribute("ssid", ssid.string());
|
||||
xml.attribute("bssid", bssid_buf);
|
||||
xml.attribute("state", "disconnected");
|
||||
xml.attribute("auth_failures", auth_failures);
|
||||
});
|
||||
|
||||
});
|
||||
} catch (...) { Genode::warning("could not report disconnected state"); }
|
||||
}
|
||||
|
||||
|
||||
static inline int approximate_quality(struct wpa_bss *bss)
|
||||
{
|
||||
/*
|
||||
* We provide an quality value by transforming the actual
|
||||
* signal level [-50,-100] (dBm) to [100,0] (%).
|
||||
*/
|
||||
int level = bss->level;
|
||||
|
||||
if (level <= -100)
|
||||
return 0;
|
||||
else if (level >= -50)
|
||||
return 100;
|
||||
|
||||
return 2 * (level + 100);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wpa_report_scan_results(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
try {
|
||||
Genode::Reporter::Xml_generator xml(*accesspoints_reporter, [&]() {
|
||||
for (unsigned i = 0; i < wpa_s->last_scan_res_used; i++) {
|
||||
struct wpa_bss *bss = wpa_s->last_scan_res[i];
|
||||
|
||||
bool wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) != NULL;
|
||||
bool wpa2 = wpa_bss_get_ie(bss, WLAN_EID_RSN) != NULL;
|
||||
|
||||
char bssid_buf[MAC_STR_LEN];
|
||||
mac2str(bssid_buf, bss->bssid);
|
||||
|
||||
Genode::String<SSID_MAX_LEN>
|
||||
ssid(Genode::Cstring((char *)bss->ssid, bss->ssid_len));
|
||||
|
||||
int quality = approximate_quality(bss);
|
||||
|
||||
xml.node("accesspoint", [&]() {
|
||||
xml.attribute("ssid", ssid.string());
|
||||
xml.attribute("bssid", bssid_buf);
|
||||
xml.attribute("quality", quality);
|
||||
|
||||
/* XXX we forcefully only support WPA/WPA2 psk for now */
|
||||
if (wpa || wpa2)
|
||||
xml.attribute("protection", "WPA-PSK");
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (...) { Genode::warning("could not report scan results"); }
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
/* needed by wifi_drv */
|
||||
wpa_main;
|
||||
wpa_reporter_init;
|
||||
wpa_ctrl_set_fd;
|
||||
|
||||
/* needed by wpa_driver_nl80211 */
|
||||
__hide_aliasing_typecast;
|
||||
|
@ -359,7 +359,6 @@ linux-x.x.x/net/packet/af_packet.c
|
||||
linux-x.x.x/net/packet/internal.h
|
||||
linux-x.x.x/net/rfkill/core.c
|
||||
linux-x.x.x/net/rfkill/input.c
|
||||
linux-x.x.x/net/rfkill/rfkill-gpio.c
|
||||
linux-x.x.x/net/rfkill/rfkill.h
|
||||
linux-x.x.x/net/wireless/ap.c
|
||||
linux-x.x.x/net/wireless/chan.c
|
||||
|
Loading…
x
Reference in New Issue
Block a user