44from time import monotonic , sleep
55
66import gi
7- gi .require_version ('NM' , '1.0' )
7+
8+ gi .require_version ("NM" , "1.0" )
89from gi .repository import GLib , NM
910
1011# ensure all wrapper objects for Settings types are created
1112for _name in dir (NM ):
12- if _name .startswith (' Setting' ):
13+ if _name .startswith (" Setting" ):
1314 getattr (NM , _name )
1415
16+
1517class Future :
1618 def __init__ (self ):
1719 self ._event = threading .Event ()
@@ -38,6 +40,7 @@ def run(self):
3840 GLib .MainLoop (None ).run ()
3941 except Exception :
4042 import traceback
43+
4144 traceback .print_exc (file = sys .stderr )
4245 sys .exit (1 )
4346
@@ -53,13 +56,11 @@ def cb(data):
5356 done .wait ()
5457 return result [0 ]
5558
59+
5660def address_from_str (s ):
57- assert '/' in s , "IP address must be in the form address/prefix"
58- (addr , prefix ) = s .split ('/' , 1 )
59- return NM .IPAddress .new (
60- socket .AF_INET6 if ':' in addr else socket .AF_INET ,
61- addr ,
62- int (prefix ))
61+ assert "/" in s , "IP address must be in the form address/prefix"
62+ (addr , prefix ) = s .split ("/" , 1 )
63+ return NM .IPAddress .new (socket .AF_INET6 if ":" in addr else socket .AF_INET , addr , int (prefix ))
6364
6465
6566def connection_from_dict (data ):
@@ -71,13 +72,13 @@ def connection_from_dict(data):
7172 if not v :
7273 continue
7374
74- if k == ' mac-address' :
75- v = ':' .join (f"{ x :02X} " for x in v )
76- elif k == ' ssid' :
75+ if k == " mac-address" :
76+ v = ":" .join (f"{ x :02X} " for x in v )
77+ elif k == " ssid" :
7778 if isinstance (v , str ):
7879 v = v .encode ()
7980 v = GLib .Bytes (v )
80- elif k == ' addresses' :
81+ elif k == " addresses" :
8182 # setting addresses via the property doesn't seem to work
8283 for x in v :
8384 setting .add_address (address_from_str (x ))
@@ -92,13 +93,15 @@ def connection_from_dict(data):
9293 con .add_setting (setting )
9394 return con
9495
96+
9597class NMDev :
9698 def __init__ (self , interface ):
9799 self ._interface = interface
98- self ._nm_dev = nm .get_device_by_iface (interface ) # pylint: disable=possibly-used-before-assignment
100+ self ._nm_dev = nm .get_device_by_iface (interface ) # pylint: disable=possibly-used-before-assignment
99101
100102 def _delete_connection (self , con ):
101103 future = Future ()
104+
102105 def cb (con , res , error ):
103106 assert error is None
104107 try :
@@ -114,7 +117,7 @@ def cb(con, res, error):
114117 )
115118
116119 def get_settings (self ):
117- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
120+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
118121 if lg_con :
119122 return dict (lg_con .to_dbus (NM .ConnectionSerializationFlags .ALL ))
120123
@@ -125,26 +128,29 @@ def get_active_settings(self):
125128 return dict (con .to_dbus (NM .ConnectionSerializationFlags .ALL ))
126129
127130 def configure (self , data ):
128- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
131+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
129132 if lg_con :
130133 self ._delete_connection (lg_con )
131- data ['connection' ].update ({
132- 'id' : f"labgrid-{ self ._interface } " ,
133- 'autoconnect' : False ,
134- 'interface-name' : self ._interface ,
135- })
134+ data ["connection" ].update (
135+ {
136+ "id" : f"labgrid-{ self ._interface } " ,
137+ "autoconnect" : False ,
138+ "interface-name" : self ._interface ,
139+ }
140+ )
136141 con = connection_from_dict (data )
137142
138143 future = Future ()
144+
139145 def cb (dev , res , error ):
140146 assert error is None
141147 try :
142- res = nm .add_and_activate_connection_finish (res ) # pylint: disable=possibly-used-before-assignment
148+ res = nm .add_and_activate_connection_finish (res ) # pylint: disable=possibly-used-before-assignment
143149 future .set (res )
144150 except Exception as e :
145151 future .set (e )
146152
147- nm .add_and_activate_connection_async ( # pylint: disable=possibly-used-before-assignment
153+ nm .add_and_activate_connection_async ( # pylint: disable=possibly-used-before-assignment
148154 con ,
149155 self ._nm_dev ,
150156 None , # specific_object
@@ -172,7 +178,7 @@ def wait_state(self, expected, timeout):
172178 )
173179
174180 def disable (self ):
175- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
181+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
176182 if lg_con :
177183 self ._delete_connection (lg_con )
178184
@@ -182,58 +188,60 @@ def _flags_to_str(self, flags):
182188 def _accesspoint_to_dict (self , ap ):
183189 res = {}
184190
185- res ['flags' ] = self ._flags_to_str (ap .get_flags ())
186- res ['wpa-flags' ] = self ._flags_to_str (ap .get_wpa_flags ())
187- res ['rsn-flags' ] = self ._flags_to_str (ap .get_rsn_flags ())
188- res ['bssid' ] = ap .get_bssid ()
189- res ['ssid' ] = ap .get_ssid ().get_data ().decode (errors = 'surrogateescape' )
190- res ['frequency' ] = ap .get_frequency ()
191- res ['mode' ] = self ._flags_to_str (ap .get_mode ())
192- res ['max-bitrate' ] = ap .get_max_bitrate ()
193- res ['strength' ] = ap .get_strength ()
191+ res ["flags" ] = self ._flags_to_str (ap .get_flags ())
192+ res ["wpa-flags" ] = self ._flags_to_str (ap .get_wpa_flags ())
193+ res ["rsn-flags" ] = self ._flags_to_str (ap .get_rsn_flags ())
194+ res ["bssid" ] = ap .get_bssid ()
195+ if ap .get_ssid ():
196+ res ["ssid" ] = ap .get_ssid ().get_data ().decode (errors = "surrogateescape" )
197+ res ["frequency" ] = ap .get_frequency ()
198+ res ["mode" ] = self ._flags_to_str (ap .get_mode ())
199+ res ["max-bitrate" ] = ap .get_max_bitrate ()
200+ res ["strength" ] = ap .get_strength ()
194201
195202 return res
196203
197204 def get_state (self ):
198205 state = {}
199206
200207 device = {}
201- device [' capabilities' ] = self ._flags_to_str (self ._nm_dev .get_capabilities ())
202- device [' device-type' ] = self ._flags_to_str (self ._nm_dev .get_device_type ())
203- device [' state' ] = self ._flags_to_str (self ._nm_dev .get_state ())
204- device [' state-reason' ] = self ._flags_to_str (self ._nm_dev .get_state_reason ())
205- device [' hw-address' ] = self ._nm_dev .get_hw_address ()
206- device [' driver' ] = self ._nm_dev .get_driver ()
207- device [' udi' ] = self ._nm_dev .get_udi ()
208- device [' mtu' ] = self ._nm_dev .get_mtu ()
209- device [' vendor' ] = self ._nm_dev .get_vendor ()
210- device [' product' ] = self ._nm_dev .get_product ()
211- state [' device' ] = device
208+ device [" capabilities" ] = self ._flags_to_str (self ._nm_dev .get_capabilities ())
209+ device [" device-type" ] = self ._flags_to_str (self ._nm_dev .get_device_type ())
210+ device [" state" ] = self ._flags_to_str (self ._nm_dev .get_state ())
211+ device [" state-reason" ] = self ._flags_to_str (self ._nm_dev .get_state_reason ())
212+ device [" hw-address" ] = self ._nm_dev .get_hw_address ()
213+ device [" driver" ] = self ._nm_dev .get_driver ()
214+ device [" udi" ] = self ._nm_dev .get_udi ()
215+ device [" mtu" ] = self ._nm_dev .get_mtu ()
216+ device [" vendor" ] = self ._nm_dev .get_vendor ()
217+ device [" product" ] = self ._nm_dev .get_product ()
218+ state [" device" ] = device
212219
213220 for name , ip_cfg in (
214- ( ' ip4-config' , self ._nm_dev .get_ip4_config ()),
215- ( ' ip6-config' , self ._nm_dev .get_ip6_config ()),
216- ):
221+ ( " ip4-config" , self ._nm_dev .get_ip4_config ()),
222+ ( " ip6-config" , self ._nm_dev .get_ip6_config ()),
223+ ):
217224 if ip_cfg is None :
218225 continue
219226 cfg = {}
220- cfg [' addresses' ] = []
227+ cfg [" addresses" ] = []
221228 for address in ip_cfg .get_addresses ():
222- cfg [' addresses' ].append (f"{ address .get_address ()} /{ address .get_prefix ()} " )
223- cfg [' gateway' ] = ip_cfg .get_gateway ()
229+ cfg [" addresses" ].append (f"{ address .get_address ()} /{ address .get_prefix ()} " )
230+ cfg [" gateway" ] = ip_cfg .get_gateway ()
224231 state [name ] = cfg
225232
226233 try :
227234 ap = self ._nm_dev .get_active_access_point ()
228235 except AttributeError :
229236 ap = None
230237 if ap :
231- state [' active-access-point' ] = self ._accesspoint_to_dict (ap )
238+ state [" active-access-point" ] = self ._accesspoint_to_dict (ap )
232239
233240 return state
234241
235242 def request_scan (self ):
236243 future = Future ()
244+
237245 def cb (dev , res , error ):
238246 assert error is None
239247 try :
@@ -251,7 +259,7 @@ def cb(dev, res, error):
251259 future .wait () # we must wait, but don't need to return it here
252260
253261 def get_access_points (self , scan ):
254- if scan is None : # automatically scan if needed
262+ if scan is None : # automatically scan if needed
255263 age = NM .utils_get_timestamp_msec () - self ._nm_dev .get_last_scan ()
256264 scan = bool (age > 30_000 )
257265
@@ -275,80 +283,93 @@ def get_dhcpd_leases(self):
275283 with open (f"/var/lib/NetworkManager/dnsmasq-{ self ._interface } .leases" ) as f :
276284 for line in f :
277285 line = line .strip ().split ()
278- if line [3 ] == '*' :
286+ if line [3 ] == "*" :
279287 line [3 ] = None
280- if line [4 ] == '*' :
288+ if line [4 ] == "*" :
281289 line [4 ] = None
282- leases .append ({
283- 'expire' : int (line [0 ]),
284- 'mac' : line [1 ],
285- 'ip' : line [2 ],
286- 'hostname' : line [3 ],
287- 'id' : line [4 ],
288- })
290+ leases .append (
291+ {
292+ "expire" : int (line [0 ]),
293+ "mac" : line [1 ],
294+ "ip" : line [2 ],
295+ "hostname" : line [3 ],
296+ "id" : line [4 ],
297+ }
298+ )
289299 return leases
290300
291- if getattr (NM .Client , '__gtype__' , None ):
301+
302+ if getattr (NM .Client , "__gtype__" , None ):
292303 # hide this from sphinx autodoc
293304 bl = BackgroundLoop ()
294305 bl .start ()
295306 nm = bl .block_on (NM .Client .new , None )
296307
297308_nmdevs = {}
298309
310+
299311def _get_nmdev (interface ):
300312 if interface not in _nmdevs :
301313 _nmdevs [interface ] = NMDev (interface )
302314 return _nmdevs [interface ]
303315
316+
304317def handle_configure (interface , settings ):
305318 nmdev = _get_nmdev (interface )
306319 return nmdev .configure (settings )
307320
321+
308322def handle_wait_state (interface , expected , timeout = 60 ):
309323 nmdev = _get_nmdev (interface )
310324 return nmdev .wait_state (expected , timeout )
311325
326+
312327def handle_disable (interface ):
313328 nmdev = _get_nmdev (interface )
314329 return nmdev .disable ()
315330
331+
316332def handle_get_active_settings (interface ):
317333 nmdev = _get_nmdev (interface )
318334 return nmdev .get_active_settings ()
319335
336+
320337def handle_get_settings (interface ):
321338 nmdev = _get_nmdev (interface )
322339 return nmdev .get_settings ()
323340
341+
324342def handle_get_state (interface ):
325343 nmdev = _get_nmdev (interface )
326344 return nmdev .get_state ()
327345
346+
328347def handle_get_dhcpd_leases (interface ):
329348 nmdev = _get_nmdev (interface )
330349 return nmdev .get_dhcpd_leases ()
331350
351+
332352def handle_request_scan (interface ):
333353 nmdev = _get_nmdev (interface )
334354 return nmdev .request_scan ()
335355
356+
336357def handle_get_access_points (interface , scan = None ):
337358 nmdev = _get_nmdev (interface )
338359 return nmdev .get_access_points (scan )
339360
340361
341362methods = {
342363 # basic
343- ' configure' : handle_configure ,
344- ' wait_state' : handle_wait_state ,
345- ' disable' : handle_disable ,
346- ' get_active_settings' : handle_get_active_settings ,
347- ' get_settings' : handle_get_settings ,
348- ' get_state' : handle_get_state ,
364+ " configure" : handle_configure ,
365+ " wait_state" : handle_wait_state ,
366+ " disable" : handle_disable ,
367+ " get_active_settings" : handle_get_active_settings ,
368+ " get_settings" : handle_get_settings ,
369+ " get_state" : handle_get_state ,
349370 # dhcpd
350- ' get_dhcpd_leases' : handle_get_dhcpd_leases ,
371+ " get_dhcpd_leases" : handle_get_dhcpd_leases ,
351372 # wireless
352- ' request_scan' : handle_request_scan ,
353- ' get_access_points' : handle_get_access_points ,
373+ " request_scan" : handle_request_scan ,
374+ " get_access_points" : handle_get_access_points ,
354375}
0 commit comments