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
1 change: 1 addition & 0 deletions board/common/qemu/qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,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

3 changes: 2 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,2 @@
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", NAME="wifi%n"
# Only rename physical interfaces, skip virtual ones created by hostapd
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", TEST=="/sys/class/net/$name/device", KERNEL!="*_*", NAME="wifi%n"
95 changes: 95 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,95 @@
#!/usr/bin/env python3

import sys
import subprocess
import json
import re
import os

def check_interface_exists(interface):
"""Check if the network interface exists"""
try:
result = subprocess.run(['ip', 'link', 'show', interface],
capture_output=True, check=True)
return True
except subprocess.CalledProcessError:
return False

def parse_iw_station_dump(interface):
"""Parse iw station dump output and return JSON"""
try:
result = subprocess.run(['sudo', 'iw', 'dev', interface, 'station', 'dump'],
capture_output=True, text=True, check=True)
output = result.stdout
except subprocess.CalledProcessError as e:
print(f"Error running iw command: {e}", file=sys.stderr)
return []
except FileNotFoundError:
print("Error: 'iw' command not found", file=sys.stderr)
return []

stations = []
current_station = {}

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

if line.startswith('Station'):
if current_station:
stations.append(current_station)

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

elif 'tx bitrate:' in line:
bitrate_match = re.search(r'tx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
if bitrate_match:
speed = bitrate_match.group(1)
unit = bitrate_match.group(2)
current_station['tx-speed'] = f"{speed} {unit.replace('Bit/s', 'bps')}"

elif 'rx bitrate:' in line:
bitrate_match = re.search(r'rx bitrate:\s*(\d+\.?\d*)\s*(MBit/s|Gbit/s)', line)
if bitrate_match:
speed = bitrate_match.group(1)
unit = bitrate_match.group(2)
current_station['rx-speed'] = f"{speed} {unit.replace('Bit/s', 'bps')}"

elif 'signal:' in line and 'avg' not in line:
signal_match = re.search(r'signal:\s*(-?\d+)', line)
if signal_match:
current_station['rssi'] = int(f"{signal_match.group(1)}")

elif 'connected time:' in line:
time_match = re.search(r'connected time:\s*(\d+\s+\w+)', line)
if time_match:
current_station['connected-time'] = time_match.group(1)

if current_station:
stations.append(current_station)

return stations

def main():
if len(sys.argv) != 2:
print("Usage: python3 wifi_station_parser.py <interface>")
print("Example: python3 wifi_station_parser.py wifi0_ap2")
sys.exit(1)

interface = sys.argv[1]

if not check_interface_exists(interface):
print(f"Error: Interface '{interface}' not found", file=sys.stderr)
sys.exit(1)

stations = parse_iw_station_dump(interface)
print(json.dumps(stations, indent=2))

if __name__ == "__main__":
main()
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
},
{
"name": "wifi0",
"type": "infix-if-type:wifi"
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {}
}
]
},
Expand Down
39 changes: 27 additions & 12 deletions src/confd/src/ietf-interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net,
return vxlan_gen(NULL, cif, ip);
case IFT_WIFI:
return wifi_gen(NULL, cif, net);
case IFT_WIFI_AP:
return wifi_ap_add_iface(cif, net) || wifi_gen(NULL, wifi_ap_get_radio(cif), net);
case IFT_ETH:
return netdag_gen_ethtool(net, cif, dif);
case IFT_LO:
Expand Down Expand Up @@ -455,6 +457,11 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net,
return netdag_gen_ethtool(net, cif, dif);
case IFT_WIFI:
return wifi_gen(dif, cif, net);
case IFT_WIFI_AP: {
struct lyd_node *radio_if = wifi_ap_get_radio(cif);
return wifi_gen(NULL, radio_if, net);
return 0;
}
case IFT_DUMMY:
case IFT_GRE:
case IFT_GRETAP:
Expand Down Expand Up @@ -483,6 +490,8 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
case IFT_WIFI:
case IFT_ETH:
return lydx_get_child(dif, "custom-phys-address");
case IFT_WIFI_AP:
return lydx_get_child(dif, "custom-phys-address");

case IFT_GRE:
case IFT_GRETAP:
Expand Down Expand Up @@ -572,9 +581,13 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif,
eth_gen_del(dif, ip);
wifi_gen_del(dif, net);
break;
case IFT_WIFI_AP:
wifi_ap_del_iface(dif, net);
break;
case IFT_VETH:
veth_gen_del(dif, ip);
break;

case IFT_BRIDGE:
case IFT_DUMMY:
case IFT_GRE:
Expand Down Expand Up @@ -615,7 +628,6 @@ static sr_error_t netdag_gen_iface(sr_session_ctx_t *session, struct dagger *net
int err = 0;
FILE *ip;


err = netdag_gen_iface_timeout(net, ifname, iftype);
if (err)
goto err;
Expand Down Expand Up @@ -744,6 +756,7 @@ static int netdag_init_iface(struct lyd_node *cif)
case IFT_DUMMY:
case IFT_ETH:
case IFT_WIFI:
case IFT_WIFI_AP:
case IFT_GRE:
case IFT_GRETAP:
case IFT_LO:
Expand Down Expand Up @@ -897,18 +910,20 @@ static int keystorecb(sr_session_ctx_t *session, uint32_t sub_id, const char *mo

LYX_LIST_FOR_EACH(interfaces, interface, "interface") {
const char *name;

if (iftype_from_iface(interface) != IFT_WIFI)
continue;

wifi = lydx_get_child(interface, "wifi");
if (!wifi)
continue;

name = lydx_get_cattr(wifi, "secret");
if (!name || strcmp(name, secret_name))
enum iftype itype = iftype_from_iface(interface);

if (itype == IFT_WIFI) {
wifi = lydx_get_child(interface, "wifi");
if (!wifi)
continue;

name = lydx_get_cattr(wifi, "secret");
if (!name || strcmp(name, secret_name))
continue;
wifi_station_gen(interface, &confd->netdag);
} else {
continue;
wifi_gen(NULL, interface, &confd->netdag);
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/confd/src/ietf-interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
_map(IFT_DUMMY, "infix-if-type:dummy") \
_map(IFT_ETH, "infix-if-type:ethernet") \
_map(IFT_WIFI, "infix-if-type:wifi") \
_map(IFT_WIFI_AP, "infix-if-type:wifi-ap") \
_map(IFT_GRE, "infix-if-type:gre") \
_map(IFT_GRETAP, "infix-if-type:gretap") \
_map(IFT_LAG, "infix-if-type:lag") \
Expand Down Expand Up @@ -122,7 +123,14 @@ int bridge_port_gen(struct lyd_node *dif, struct lyd_node *cif, FILE *ip);

/* infix-if-wifi.c */
int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net);
int wifi_gen_del(struct lyd_node *dif, struct dagger *net);
int wifi_station_gen(struct lyd_node *cif, struct dagger *net);
int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net);
int wifi_ap_del_iface(struct lyd_node *cif,struct dagger *net);
int wifi_ap_gen(struct lyd_node *cif, struct dagger *net);
int wifi_gen_del(struct lyd_node *iface, struct dagger *net);
int wifi_is_accesspoint(struct lyd_node *cif);
bool wifi_ap_must_delete(struct lyd_node *dif);
struct lyd_node *wifi_ap_get_radio(struct lyd_node *cif);

/* infix-if-gre.c */
int gre_gen(struct lyd_node *dif, struct lyd_node *cif, FILE *ip);
Expand Down
Loading