当前位置: 首页 > news >正文

ubuntu linux 控制wifi功能 dbus控制

dbus 控制wifi功能
原理:ubuntu系统自带的NetworkManager 守护进程专门接管了系统网络的功能,避免了用户手动写代码调用系统函数驱动来间接操作硬件。
所以有这个NetworkManager来管理这个这部分网络功能,并且提供dbus通信,让各个应用来共享该功能,避免了各个不同的应用都控制该功能导致冲突。

⚠️ 重要前提:

  • 你的系统使用 NetworkManager(检查:systemctl is-active NetworkManager 应为 active)
  • 你有无线网卡,设备名如 wlan0(可通过 ip linknmcli device 查看,但后者是工具,我们尽量不用)
  • 所有命令需在终端以普通用户或 root 执行(部分需 root,我会标注)

🎯 1. 开启 WiFi(启用无线射频)

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.DBus.Properties.Set \string:"org.freedesktop.NetworkManager" \string:"WirelessEnabled" \variant:boolean:true

🎯 2. 关闭 WiFi(禁用无线射频)

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.DBus.Properties.Set \string:"org.freedesktop.NetworkManager" \string:"WirelessEnabled" \variant:boolean:false

🎯 3. 连接指定的 WiFi(SSID + 密码)

这需要 3 步

Step 1️⃣:扫描 WiFi(可选,确保目标 AP 可见)

该命令行相当于查看当前的网络设备有哪些

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.NetworkManager.GetDevices

从返回结果中找到你的无线设备路径,比如:/org/freedesktop/NetworkManager/Devices/3

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/7 \org.freedesktop.DBus.Properties.Get \string:"org.freedesktop.NetworkManager.Device" \string:"Interface"

它会告诉你 /Devices/7 对应的名字(比如 docker0 或 virbr0)。

方法 2:用 dbus-send 查类型


dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.DBus.Properties.Get \string:"org.freedesktop.NetworkManager.Device" \string:"DeviceType"# 返回值是一个数字:
| 数字 | 类型                                                  |
| -- | --------------------------------------------------- |
| 0  | Unknown                                             |
| 1  | Ethernet                                            |
| 2  | Wi-Fi (802.11 wireless LAN)                         |
| 3  | Unused (保持兼容)                                       |
| 5  | Bridge                                              |
| 6  | VLAN                                                |
| 7  | Modem (GSM/UMTS/LTE, CDMA, etc.) ← 📡 就是 4G/USB 上网卡 |
| 8  | Infiniband                                          |
| 9  | Bond                                                |
| 10 | Veth                                                |
| 11 | Macvlan                                             |
| 12 | VXLAN                                               |
| 13 | VethPair                                            |
| 14 | Tun/Tap                                             |
|| 其他虚拟设备类型                                            |# 等等

然后请求扫描:
RequestScan 只是触发扫描,不返回结果(dbus会扫到wifi会增加对应的AccessPoint的路径对象,每个都表示一个wifi)

 # 无问题busctl call \org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.NetworkManager.Device.Wireless \RequestScan \a{sv} 0

Step 2️⃣:获取目标 AP 的对象路径

等待几秒(5s)让扫描完成。(会触发信号当扫描到wifi的时候)

# 监听信号
dbus-monitor --system "interface='org.freedesktop.NetworkManager.Device.Wireless'"

获取对应的AccessPoint 与SSId的输出

for ap in $(dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.NetworkManager.Device.Wireless.GetAllAccessPoints \| grep object | awk '{print $3}' | tr -d '"'); dossid=$(dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \$ap \org.freedesktop.DBus.Properties.Get \string:"org.freedesktop.NetworkManager.AccessPoint" \string:"Ssid" \
)if [ -n "$ssid" ]; thenecho "$ap"echo "$ssid"echo ""fidone
# 获取可连接的wifi 上面扫描完成之后 会增加AccessPoint的对象这里,列出来所有的可连接的wifidbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.NetworkManager.Device.Wireless.GetAccessPoints
# 包括不可访问的wifi
dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.NetworkManager.Device.Wireless.GetAllAccessPoints

在返回列表中找到你要连接的 SSID 对应的路径,如:/org/freedesktop/NetworkManager/AccessPoint/123


Step 3️⃣:创建并激活连接

先创建一个临时连接配置(一次性,不保存):
用命令行很难做出来,这里给出python调用dbus功能连接指定的wifi
wifi名字叫gt 密码是12345678
python 连接指定的wifi

#!/usr/bin/env python3
import dbus
import uuid
import sysSSID = "gt"
PASSWORD = "12345678"bus = dbus.SystemBus()
NM_BUS_NAME = "org.freedesktop.NetworkManager"
NM_OBJECT_PATH = "/org/freedesktop/NetworkManager"nm_proxy = bus.get_object(NM_BUS_NAME, NM_OBJECT_PATH)
nm_iface = dbus.Interface(nm_proxy, NM_BUS_NAME)# 1️⃣ 找到无线设备
devices = nm_iface.GetDevices()
wifi_device = None
interface_name = Nonefor dev_path in devices:dev_proxy = bus.get_object(NM_BUS_NAME, dev_path)dev_props = dbus.Interface(dev_proxy, "org.freedesktop.DBus.Properties")dev_type = dev_props.Get("org.freedesktop.NetworkManager.Device", "DeviceType")if dev_type == 2:  # wirelesswifi_device = dev_pathinterface_name = dev_props.Get("org.freedesktop.NetworkManager.Device", "Interface")print("wireless path:", wifi_device, "| type:", type(wifi_device))print("interface_name:", interface_name, "| type:", type(interface_name))breakif wifi_device is None:print("没有找到无线设备")sys.exit(1)# 2️⃣ 构造连接字典
connection = {'connection': dbus.Dictionary({'id': dbus.String(SSID),'type': dbus.String('802-11-wireless'),'uuid': dbus.String(str(uuid.uuid4())),'interface-name': dbus.String(interface_name)}, signature='sv'),'802-11-wireless': dbus.Dictionary({'ssid': dbus.ByteArray(SSID.encode())}, signature='sv'),'802-11-wireless-security': dbus.Dictionary({'key-mgmt': dbus.String('wpa-psk'),'psk': dbus.String(PASSWORD)}, signature='sv')
}# 3️⃣ 调用 AddAndActivateConnection
conn_path, active_path = nm_iface.AddAndActivateConnection(connection,dbus.ObjectPath(wifi_device),dbus.ObjectPath("/")  # 不指定 AP, 自动选择
)print("连接成功!")
print("Connection path:", conn_path)
print("Active path:", active_path)

✅ 此时 WiFi 应该已连接。


🎯 4. 断开当前 WiFi 连接

获取当前激活的连接:

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.NetworkManager.GetActiveConnections

找到返回中类型为 802-11-wireless 的连接路径,如:/org/freedesktop/NetworkManager/ActiveConnection/5

然后停用它:

busctl call org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.NetworkManager DeactivateConnection \o /org/freedesktop/NetworkManager/ActiveConnection/5

🎯 5. 创建并打开 WiFi 热点(AP 模式)

Step 1:创建热点连接配置

Step 2:激活热点

#!/usr/bin/env python3
import dbus# -------------------------------
# 配置热点信息
SSID = b"MyHotspot"      # 热点名称(Byte)
PASSWORD = "12345678"    # 热点密码
# -------------------------------# 连接到系统总线
bus = dbus.SystemBus()# 获取 NetworkManager 对象
nm_proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
nm_iface = dbus.Interface(nm_proxy, 'org.freedesktop.NetworkManager')# 获取 NetworkManager 设置接口
settings_proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager/Settings')
settings_iface = dbus.Interface(settings_proxy, 'org.freedesktop.NetworkManager.Settings')# 获取所有设备,找到第一个无线设备
device_paths = nm_iface.GetDevices()
wifi_device_path = None
wifi_iface_name = None
for path in device_paths:dev_proxy = bus.get_object('org.freedesktop.NetworkManager', path)dev_props = dbus.Interface(dev_proxy, 'org.freedesktop.DBus.Properties')dev_type = dev_props.Get('org.freedesktop.NetworkManager.Device', 'DeviceType')# DeviceType 2 = Wi-Fiif dev_type == 2:wifi_device_path = pathwifi_iface_name = dev_props.Get('org.freedesktop.NetworkManager.Device', 'Interface')breakif not wifi_device_path:raise RuntimeError("未找到无线设备,请检查你的网络接口。")print(f"使用无线接口: {wifi_iface_name}")# 构造热点连接配置
connection = {'connection': {'id': 'MyHotspot','type': '802-11-wireless','interface-name': wifi_iface_name,'autoconnect': False,},'802-11-wireless': {'ssid': dbus.ByteArray(SSID),'mode': 'ap',},'802-11-wireless-security': {'key-mgmt': 'wpa-psk','psk': PASSWORD,},
}# 调用 AddConnection 添加热点
connection_path = settings_iface.AddConnection(connection)
print("连接已添加,路径:", connection_path)# 激活热点(使用 ActivateConnection)
active_path = nm_iface.ActivateConnection(connection_path, wifi_device_path, '/')
print("热点已激活,Active path:", active_path)
print(f"SSID: {SSID.decode()}, Password: {PASSWORD}")

✅ 热点已启动!


🎯 6. 关闭热点

和“断开 WiFi”一样:

如之前使用了打开热点的的时候输出的内容:

使用无线接口: wlp7s0 连接已添加,路径: /org/freedesktop/NetworkManager/Settings/15 热点已激活,Active path: /org/freedesktop/NetworkManager/ActiveConnection/12 SSID: MyHotspot, Password: 12345678

或着找到类型为 802-11-wireless 且模式是 ap 的连接路径,如:/org/freedesktop/NetworkManager/ActiveConnection/6 关键要想办法得到这个ActiveConnection

然后:

busctl call org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.NetworkManager DeactivateConnection \o /org/freedesktop/NetworkManager/ActiveConnection/12

📌 附录:如何获取设备路径(不用 nmcli)

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager \org.freedesktop.NetworkManager.GetDevices

遍历返回的设备路径,对每个设备查询设备类型:

dbus-send --system --print-reply \--dest=org.freedesktop.NetworkManager \/org/freedesktop/NetworkManager/Devices/3 \org.freedesktop.DBus.Properties.Get \string:"org.freedesktop.NetworkManager.Device" \string:"DeviceType"

返回值 2 表示无线设备(NM_DEVICE_TYPE_WIFI)。


✅ 总结命令表(纯 dbus-send)

功能命令摘要
开启 WiFiSet WirelessEnabled true
关闭 WiFiSet WirelessEnabled false
连接 WiFiAddConnection + ActivateConnection(需 SSID 字节数组)
断开 WiFiDeactivateConnection(需 ActiveConnection 路径)
打开热点AddConnection(mode=ap) + ActivateConnection
关闭热点DeactivateConnection(找 AP 类型的 ActiveConnection)

💡 温馨提示:

  • 使用 dbus-send busctl操作 NetworkManager 极其繁琐,参数结构复杂,错误难调试。
  • 生产环境或脚本中强烈建议使用 nmcli
  • 如果想要更详细的控制就调用dbus的功能通信,nmcli 也是这么做的
  • 如果你是为了学习 D-Bus 或嵌入式定制系统,这些命令非常有价值。
    (可以用命令先跑通,然后再转换具体的代码)

http://www.dtcms.com/a/393536.html

相关文章:

  • `TensorBoard`、`PyTorchViz` 和 `HiddenLayer` 深度学习中三个重要的可视化工具
  • 本地设备ipv6默认网关和路由器ipv6默认网关的区别
  • 云原生docker在线yum安装
  • LeetCode 384 打乱数组 Swift 题解:从洗牌算法到实际应用
  • 计算机网络-因特网
  • HDFS和MapReduce——Hadoop的两大核心技
  • 【华为OD】石头剪刀布游戏
  • LinuxC++项目开发日志——基于正倒排索引的boost搜索引擎(1——项目框架)
  • Photoshop - Photoshop 非破坏性编辑
  • C++入门小馆:C++11第三弹(可变参数模板)
  • 常用设计模式中的工厂模式,责任链模式,策略模式和单例模式的简单说明
  • aave v3 合约解析1 存款
  • autosar中自旋锁和互斥锁的应用
  • 建筑可视化告别“假”渲染:用Photoshop+Twinmotion打造照片级场景
  • 一键生成linux服务器健康巡检html报告
  • 数据结构(C语言篇):(十八)交换排序
  • Ubuntu20.04下跑通ORB-SLAM2
  • C++二进制转十进制
  • WordPress用户系统 + JWT认证:打造统一的应用登录解决方案
  • PortSwigger靶场之将反射型 XSS 注入到带有尖括号和双引号的 JavaScript 字符串中,并使用 HTML 编码和单引号进行转义通关秘籍
  • win11电脑按键失灵,提供几个可能恢复的方法
  • Android 中获取稳定时间的方法
  • mac编译ffmpeg
  • Deepsoil V7.1.10+Shake2000,最新版程序、教学视频、PDF使用手册
  • Apollo相机数据RTMP推流与播放指南
  • 使用Python扩展Unity编辑器
  • 【Android】自定义控件
  • 探索 Event 框架 6:高级特性与性能优化
  • JavaSE基础——第九章 枚举类注解
  • 云计算在金融领域中的应用