Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
},
{
"name": "wifi0",
"type": "infix-if-type:wifi"
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {}
}
]
},
Expand Down
1 change: 1 addition & 0 deletions board/common/qemu/qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ run_qemu()
$(serial_args) \
$(rw_args) \
$(usb_args) \
-device usb-host,vendorid=0x0bda,productid=0xc820 \
$(host_args) \
$(net_args) \
$(wdt_args) \
Expand Down
4 changes: 4 additions & 0 deletions board/common/rootfs/etc/finit.d/available/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
service <!> name:hostapd :%i \
[2345] hostapd -P/var/run/hostapd-%i.pid /etc/hostapd-%i.conf \
-- Hostapd (Wi-Fi AccessPoint, 802.1X) @%i

4 changes: 3 additions & 1 deletion board/common/rootfs/etc/udev/rules.d/70-rename-wifi.rules
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", NAME="wifi%n"
# Only rename physical interfaces, skip virtual ones created by hostapd/iw
# Virtual interfaces created by iw have name_assign_type=3 (userspace assigned)
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", ATTR{name_assign_type}!="3", NAME="wifi%n"
61 changes: 61 additions & 0 deletions board/common/rootfs/usr/libexec/infix/wifi-ap-stations
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3

import sys
import subprocess
import json
import re

def get_stations(interface):
"""Get connected stations for an AP interface"""
try:
result = subprocess.run(['iw', 'dev', interface, 'station', 'dump'],
capture_output=True, text=True, check=True)
except (subprocess.CalledProcessError, FileNotFoundError):
return []

stations = []
station = None

for line in result.stdout.split('\n'):
line = line.strip()

if line.startswith('Station'):
if station:
stations.append(station)
mac = re.search(r'([a-fA-F0-9:]{17})', line)
station = {
'mac-address': mac.group(1) if mac else 'unknown',
'rssi': 0,
'tx-speed': 'unknown',
'rx-speed': 'unknown',
'connected-time': 'unknown'
}

elif station:
if 'signal:' in line and 'avg' not in line:
sig = re.search(r'signal:\s*(-?\d+)', line)
if sig:
station['rssi'] = int(sig.group(1))
elif 'tx bitrate:' in line:
bitrate = re.search(r'tx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
if bitrate:
station['tx-speed'] = f"{bitrate.group(1)} {bitrate.group(2).replace('Bit/s', 'bps')}"
elif 'rx bitrate:' in line:
bitrate = re.search(r'rx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
if bitrate:
station['rx-speed'] = f"{bitrate.group(1)} {bitrate.group(2).replace('Bit/s', 'bps')}"
elif 'connected time:' in line:
time = re.search(r'connected time:\s*(\d+\s+\w+)', line)
if time:
station['connected-time'] = time.group(1)

if station:
stations.append(station)

return stations

if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit(1)

print(json.dumps(get_stations(sys.argv[1]), indent=2))
4 changes: 4 additions & 0 deletions package/feature-wifi/Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ config BR2_PACKAGE_FEATURE_WIFI
select BR2_PACKAGE_WPA_SUPPLICANT_AUTOSCAN
select BR2_PACKAGE_WPA_SUPPLICANT_CLI
select BR2_PACKAGE_WIRELESS_REGDB
select BR2_PACKAGE_HOSTAPD
select BR2_PACKAGE_HOSTAPD_DRIVER_NL80211
select BR2_PACKAGE_HOSTAPD_WPA3
select BR2_PACKAGE_HOSTAPD_WPS
select BR2_PACKAGE_IW
help
Enables WiFi in Infix. Enables all requried applications.
Expand Down
1 change: 0 additions & 1 deletion package/feature-wifi/feature-wifi.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_RFKILL)
$(call KCONFIG_SET_OPT,CONFIG_MAC80211,m)
$(call KCONFIG_SET_OPT,CONFIG_CFG80211,m)

$(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK)),
$(call KCONFIG_ENABLE_OPT,CONFIG_WLAN_VENDOR_REALTEK)
$(call KCONFIG_ENABLE_OPT,CONFIG_RTW88)
Expand Down
26 changes: 26 additions & 0 deletions patches/hostapd/0001-skip-mask-check.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
We create the interfaces on our own, and set their MAC addresses
remove this check (which are for hostapd created ap interfaces)

diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index a57a151fa..43d31d16c 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -940,18 +940,6 @@ skip_mask_ext:
if (!auto_addr)
return 0;

- for (i = 0; i < ETH_ALEN; i++) {
- if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
- wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
- " for start address " MACSTR ".",
- MAC2STR(mask), MAC2STR(hapd->own_addr));
- wpa_printf(MSG_ERROR, "Start address must be the "
- "first address in the block (i.e., addr "
- "AND mask == addr).");
- return -1;
- }
- }
-
return 0;
}

51 changes: 50 additions & 1 deletion src/confd/src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,55 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
}
}

/* Check if any wifi-ap interface changed, add all wifi-ap interfaces and their radios to diff */
struct ly_set *diff_ifaces = lydx_find_xpathf(*diff, "/ietf-interfaces:interfaces/interface[type='infix-if-type:wifi-ap']");
if (diff_ifaces) {
struct ly_set *wifi_ap_ifaces = lydx_find_xpathf(config, "/ietf-interfaces:interfaces/interface[type='infix-if-type:wifi-ap']");
size_t i;

for (i = 0; wifi_ap_ifaces && i < wifi_ap_ifaces->count; i++) {
struct lyd_node *iface = wifi_ap_ifaces->dnodes[i];
struct lyd_node *wifi_node, *radio_node;
const char *ifname, *radio_name;
char xpath[256];

ifname = lydx_get_cattr(iface, "name");
wifi_node = lydx_get_child(iface, "wifi");

if (wifi_node) {
/* Add the radio attribute to the diff */
radio_node = lydx_get_child(wifi_node, "radio");
radio_name = lyd_get_value(radio_node);
/* Add radio attribute to wifi-ap interface in diff */
snprintf(xpath, sizeof(xpath),
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/radio",
ifname);
result = add_dependencies(diff, xpath, radio_name);
if (result == CONFD_DEP_ERROR) {
ERROR("Failed to add radio attribute to wifi-ap %s in diff", ifname);
ly_set_free(wifi_ap_ifaces, NULL);
goto err;
}

/* Add the referenced radio interface (type wifi) to diff */
snprintf(xpath, sizeof(xpath),
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi",
radio_name);
result = add_dependencies(diff, xpath, "");
if (result == CONFD_DEP_ERROR) {
ERROR("Failed to add radio interface %s to diff", radio_name);
ly_set_free(wifi_ap_ifaces, NULL);
goto err;
}
}
}

if (wifi_ap_ifaces)
ly_set_free(wifi_ap_ifaces, NULL);
}
err:
ly_set_free(diff_ifaces, NULL);

return result;
}

Expand Down Expand Up @@ -180,7 +229,7 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
}
max_dep--;
}
#if 0
#if 1
/* Debug: print diff to file */
FILE *f = fopen("/tmp/confd-diff.json", "w");
if (f) {
Expand Down
Loading