I am trying to use python3 dbus package to control wireless on an embedded Linux target (mips MT7628, if it matters).
System is most likely set up correctly because I have iwd + dhclient up-and-running on this embedded target.
I can connect through both eth0 and wlan0.
I can also control iwd through iwctl. So far so good.
I now need to control iwd from python3; specifically I need to be able to send scan results through serial line (real target, as opposed to my development board, will be headless).
I am at a loss with dbus interface. I need some examples to start with.
I tried something along the lines:
# 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
>>>
This while WiFi is working:
# 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]#
... but I'm obviously missing something very basic.
Can someone point me in the right direction, please?
Answering my own question to help whoever will stumble here:
It turns out both iwd and connman repositories come with complete python3 examples in subdirectory "test".
Adapting those to my specific needs proved trivial.
Relevant directories can be found here (iwd) and here (connman).
The solution to my specific question is in the following scripts: scan-for-networks and list-known-networks.
scan-for-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))