从 python 访问 iwd dbus 接口
Accessing iwd dbus interface from python
我正在尝试使用 python3 dbus 包来控制嵌入式 Linux 目标(mips MT7628,如果重要的话)上的无线。
系统很可能设置正确,因为我在这个嵌入式目标上安装了 iwd + dhclient 运行。
我可以通过 eth0 和 wlan0 连接。
我也可以通过iwctl来控制iwd。到目前为止一切顺利。
我现在需要从 python3 控制 iwd;具体来说,我需要能够通过串行线发送扫描结果(真正的目标,而不是我的开发板,将是无头的)。
我对dbus接口一头雾水。我需要一些例子来开始。
我尝试了一些方法:
# python
Python 3.8.1 (default, Feb 21 2020, 11:13:38)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dbus
>>> bus = dbus.SystemBus()
>>> wlan0 = bus.get_object('net.connman.iwd', '/net/connman/iwd/phy1/1')
>>> p = wlan0.Properties(dbus_interface='net.connman.iwd.Station')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 72, in __call__
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 141, in __call__
File "/usr/lib/python3.8/site-packages/dbus/connection.py", line 652, in call_blocking
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotFound: No matching method found
>>> p = wlan0.Scan(dbus_interface='net.connman.iwd.Station')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 141, in __call__
File "/usr/lib/python3.8/site-packages/dbus/connection.py", line 652, in call_blocking
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotFound: No matching method found
>>>
此时 WiFi 正在工作:
# iwctl
[iwd]# adapter list
Adapters *
--------------------------------------------------------------------------------
Name Powered Vendor Model
--------------------------------------------------------------------------------
phy1 on --
[iwd]# device list
Devices *
--------------------------------------------------------------------------------
Name Address Powered Adapter Mode
--------------------------------------------------------------------------------
wlan1 42:c1:f8:85:67:ba on phy1 station
[iwd]# station list
Devices in Station Mode *
--------------------------------------------------------------------------------
Name State Scanning
--------------------------------------------------------------------------------
wlan1 connected
[iwd]#
...但我显然遗漏了一些非常基本的东西。
有人能给我指出正确的方向吗?
回答我自己的问题以帮助任何在这里绊倒的人:
事实证明,iwd 和 connman 存储库都在子目录 "test".
中提供了完整的 python3 示例
事实证明,根据我的具体需要调整这些是微不足道的。
可以找到相关目录here (iwd) and here (connman).
我的具体问题的解决方案在以下脚本中:scan-for-networks and list-known-networks。
扫描网络:
#!/usr/bin/python3
import sys
import dbus
if (len(sys.argv) != 2):
print("Usage: %s <device>" % (sys.argv[0]))
sys.exit(1)
bus = dbus.SystemBus()
device = dbus.Interface(bus.get_object("net.connman.iwd", sys.argv[1]),
"net.connman.iwd.Station")
device.Scan()
list_known_networks:
#!/usr/bin/python3
import sys
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('net.connman.iwd', '/'),
'org.freedesktop.DBus.ObjectManager')
forget = None
if len(sys.argv) >= 4 and sys.argv[1] == 'forget':
forget = (sys.argv[2], sys.argv[3])
print('Known Networks:')
for path, interfaces in manager.GetManagedObjects().items():
if 'net.connman.iwd.KnownNetwork' not in interfaces:
continue
network = interfaces['net.connman.iwd.KnownNetwork']
if (network['Name'], network['Type']) == forget:
obj = dbus.Interface(bus.get_object('net.connman.iwd', path),
'net.connman.iwd.KnownNetwork')
obj.Forget()
continue
print("[ %s ]" % network['Name'])
for key in network:
val = network[key]
if type(val) == dbus.Boolean:
val = 'True' if val else 'False'
print(" %s = %s" % (key, val))
我正在尝试使用 python3 dbus 包来控制嵌入式 Linux 目标(mips MT7628,如果重要的话)上的无线。
系统很可能设置正确,因为我在这个嵌入式目标上安装了 iwd + dhclient 运行。
我可以通过 eth0 和 wlan0 连接。
我也可以通过iwctl来控制iwd。到目前为止一切顺利。
我现在需要从 python3 控制 iwd;具体来说,我需要能够通过串行线发送扫描结果(真正的目标,而不是我的开发板,将是无头的)。
我对dbus接口一头雾水。我需要一些例子来开始。
我尝试了一些方法:
# python
Python 3.8.1 (default, Feb 21 2020, 11:13:38)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dbus
>>> bus = dbus.SystemBus()
>>> wlan0 = bus.get_object('net.connman.iwd', '/net/connman/iwd/phy1/1')
>>> p = wlan0.Properties(dbus_interface='net.connman.iwd.Station')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 72, in __call__
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 141, in __call__
File "/usr/lib/python3.8/site-packages/dbus/connection.py", line 652, in call_blocking
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotFound: No matching method found
>>> p = wlan0.Scan(dbus_interface='net.connman.iwd.Station')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/dbus/proxies.py", line 141, in __call__
File "/usr/lib/python3.8/site-packages/dbus/connection.py", line 652, in call_blocking
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotFound: No matching method found
>>>
此时 WiFi 正在工作:
# iwctl
[iwd]# adapter list
Adapters *
--------------------------------------------------------------------------------
Name Powered Vendor Model
--------------------------------------------------------------------------------
phy1 on --
[iwd]# device list
Devices *
--------------------------------------------------------------------------------
Name Address Powered Adapter Mode
--------------------------------------------------------------------------------
wlan1 42:c1:f8:85:67:ba on phy1 station
[iwd]# station list
Devices in Station Mode *
--------------------------------------------------------------------------------
Name State Scanning
--------------------------------------------------------------------------------
wlan1 connected
[iwd]#
...但我显然遗漏了一些非常基本的东西。
有人能给我指出正确的方向吗?
回答我自己的问题以帮助任何在这里绊倒的人:
事实证明,iwd 和 connman 存储库都在子目录 "test".
中提供了完整的 python3 示例事实证明,根据我的具体需要调整这些是微不足道的。
可以找到相关目录here (iwd) and here (connman).
我的具体问题的解决方案在以下脚本中:scan-for-networks and list-known-networks。
扫描网络:
#!/usr/bin/python3
import sys
import dbus
if (len(sys.argv) != 2):
print("Usage: %s <device>" % (sys.argv[0]))
sys.exit(1)
bus = dbus.SystemBus()
device = dbus.Interface(bus.get_object("net.connman.iwd", sys.argv[1]),
"net.connman.iwd.Station")
device.Scan()
list_known_networks:
#!/usr/bin/python3
import sys
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('net.connman.iwd', '/'),
'org.freedesktop.DBus.ObjectManager')
forget = None
if len(sys.argv) >= 4 and sys.argv[1] == 'forget':
forget = (sys.argv[2], sys.argv[3])
print('Known Networks:')
for path, interfaces in manager.GetManagedObjects().items():
if 'net.connman.iwd.KnownNetwork' not in interfaces:
continue
network = interfaces['net.connman.iwd.KnownNetwork']
if (network['Name'], network['Type']) == forget:
obj = dbus.Interface(bus.get_object('net.connman.iwd', path),
'net.connman.iwd.KnownNetwork')
obj.Forget()
continue
print("[ %s ]" % network['Name'])
for key in network:
val = network[key]
if type(val) == dbus.Boolean:
val = 'True' if val else 'False'
print(" %s = %s" % (key, val))