0.6: first steps to make it work on OLPC
[cnetworkmanager.git] / cnetworkmanager
blob3a34eeb75b9c226ea48d94d81fa5b7c403247f65
1 #! /usr/bin/python
2 # cnetworkmanager: Command Line Interface for NetworkManager
3 # by: http://en.opensuse.org/User:Mvidner
4 # license: http://www.gnu.org/licenses/gpl-2.0.html or later
6 VERSION = "0.6"
7 print "cnetworkmanager %s - Command Line Interface for NetworkManager" % VERSION
9 norpm = False
10 import sys
11 import os
12 import ConfigParser # knm config
13 from optparse import OptionParser
14 try:
15 import dbus
16 import dbus.service
17 import _dbus_bindings
18 except:
19 print "Install python-1-dbus.rpm or or python-dbus.rpm or python-dbus.deb"
20 norpm = True
21 import xml.dom.minidom
22 try:
23 import gobject
24 except:
25 # todo - only if loop wanted
26 print "Install python-gobject2.rpm or pygobject2.rpm or python-gobject.deb"
27 norpm = True
28 # python-gnome.rpm has gconf for nm-applet...
29 if norpm:
30 sys.exit(1)
32 from dbus.mainloop.glib import DBusGMainLoop
33 DBusGMainLoop(set_as_default=True)
35 LOOP = False
37 bus = dbus.SystemBus()
39 # FOOC = connection (service) string
40 # FOOI = interface string
41 # fooo = object
42 # fooi = interface
43 # foopi = property interface
44 NMC = 'org.freedesktop.NetworkManager'
45 NMI = NMC
46 PI = 'org.freedesktop.DBus.Properties'
47 SSC = "org.freedesktop.NetworkManagerSystemSettings"
48 USC = "org.freedesktop.NetworkManagerUserSettings"
50 def introspect(obj):
51 ii = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
52 print ii.Introspect()
54 class cNM:
55 # TODO: pull them from introspection.xml
56 NM_STATE = ["UNKNOWN", "ASLEEP", "CONNECTING", "CONNECTED", "DISCONNECTED",]
58 def __init__(self, opath):
59 self.opath = opath
60 self.nmo = bus.get_object(NMC, self.opath)
61 self.nmi = dbus.Interface(self.nmo, NMI)
62 self.nmpi = dbus.Interface(self.nmo, PI)
64 def Dump0(self):
65 "Dumps its own info (not owned objects)."
66 pass
68 def Dump(self):
69 self.Dump0()
70 if options.dev:
71 for device in self.Devices():
72 device.Dump()
74 if options.actcon:
75 print "Active Connections"
76 aconns = self.ActiveConnections()
77 for aconn in aconns:
78 aconn.Dump()
80 def ListNets(self):
81 print "Wifi Networks:"
82 for dev in self.Devices():
83 dev.ListNets()
85 def reply_handler(self, opath):
86 print "Connected:", opath
88 def err_handler(self, *args):
89 print "ERR:", args
91 def silent_handler(self, *args):
92 pass
93 print "BOO!:", args
95 def quitter_handler(self, *args):
96 # exit the loop that runs only because of us
97 print "padla"
98 sys.exit(0)
100 def ActivateConnection(self, conn, device, ap):
101 # passing *_handler makes the call asynchronous
102 self.nmi.ActivateConnection(USC,
103 conn.__dbus_object_path__,
104 device.opath,
105 ap.opath,
106 reply_handler=self.reply_handler,
107 error_handler=self.err_handler,
110 def make_nm(opath):
111 "Detects NM version and chooses appropriate class"
113 nmo = bus.get_object(NMC, opath)
114 nmi = dbus.Interface(nmo, NMI)
115 try:
116 dummy = nmi.getDevices()
117 return cNM_06(opath)
118 except dbus.exceptions.DBusException:
119 return cNM_07(opath)
121 class cNM_06(cNM):
122 def SetWifiEnabled(self, v):
123 # TODO: async call, catch the state signal and exit
124 # weird: synchronous call works, but times out
125 # asynchronous call does not work
126 self.nmi.setWirelessEnabled(v,
127 reply_handler=self.quitter_handler,
128 error_handler=self.quitter_handler)
129 global LOOP
130 LOOP = True
132 def SetOnline(self, v):
133 self.nmi.sleep(not v,
134 reply_handler=self.quitter_handler,
135 error_handler=self.quitter_handler)
136 global LOOP
137 LOOP = True
139 def Dump0(self):
140 print "State:", self.NM_STATE[self.nmi.state()]
141 we = self.nmi.getWirelessEnabled()
142 if isinstance(we, tuple):
143 print "Wifi enabled:", bool(we[0])
144 print "Wifi HW enabled:", bool(we[1])
145 else:
146 print "Wifi enabled:", bool(we)
148 try:
149 dup = self.nmi.getDialup()
150 print "Dialup:", dup
151 except dbus.exceptions.DBusException, e:
152 #if e.get_dbus_name() == "org.freedesktop.NetworkManager.NoDialup":
153 # pass
154 #else:
155 print e
157 def Devices(self):
158 opaths = self.nmi.getDevices()
159 return map(cDevice_06, opaths)
161 def ActiveConnections(self):
162 return [] # at most one active connection, FIXME find it
165 class cNM_07(cNM):
166 def SetWifiEnabled(self, v):
167 self.nmpi.Set(NMI, "WirelessEnabled", v)
169 def SetOnline(self, v):
170 self.nmi.Sleep(not v)
172 def Dump0(self):
173 print "State:", self.NM_STATE[self.nmpi.Get(NMI, "State")]
174 print "Wifi enabled:", self.nmpi.Get(NMI, "WirelessEnabled")
175 print "Wifi HW enabled:", self.nmpi.Get(NMI, "WirelessHardwareEnabled")
177 def Devices(self):
178 opaths = self.nmi.GetDevices()
179 return map(cDevice_07, opaths)
181 def ActiveConnections(self):
182 aconns = self.nmpi.Get(NMI, "ActiveConnections")
183 return map(cActiveConnection, aconns)
187 class cActiveConnection:
188 def __init__(self, opath):
189 self.opath = opath
191 def Dump(self):
192 print self.opath
193 co = bus.get_object(NMC, self.opath)
194 copi = dbus.Interface(co, PI)
195 for P in ["ServiceName", "Connection", "SharedServiceName", "SharedConnection", "SpecificObject",]:
196 print " %s: %s" % (P, copi.Get(NMI, P))
197 devs = copi.Get(NMI, "Devices")
198 print " Devices:"
199 for dev in devs:
200 print " ", dev
202 def bitmask_str(map, value):
203 ret = []
204 for mask in sorted(map.keys()):
205 if value & mask: ret.append(map[mask])
206 return ",".join(ret)
209 class cDevice:
210 def __init__(self, opath):
211 self.opath = opath
212 self.devo = bus.get_object(NMC, self.opath)
213 self.devi = dbus.Interface(self.devo, NMI + ".Device")
214 self.devpi = dbus.Interface(self.devo, PI)
215 self.dt = None
216 self.DeviceType0()
218 DEVICE_TYPE = ["UNKNOWN", "802_3_ETHERNET", "802_11_WIRELESS",
219 "GSM", "CDMA",] #OLPC: 3 is MESH
221 def DeviceType(self):
222 return self.DEVICE_TYPE[self.DeviceType0()]
224 def ip_str(self, i32):
225 ret = []
226 ret.append("%d" % (i32 % 256))
227 i32 /= 256
228 ret.append("%d" % (i32 % 256))
229 i32 /= 256
230 ret.append("%d" % (i32 % 256))
231 i32 /= 256
232 ret.append("%d" % (i32 % 256))
233 i32 /= 256
234 return ".".join(ret)
236 def DumpIp4Config(self, opath):
237 print " Ip4Config:", opath
238 o = bus.get_object(NMC, opath)
239 pi = dbus.Interface(o, PI)
240 try:
241 for P in ["Address", "Netmask", "Broadcast", "Gateway",]: # beta2?
242 print " %s: %s" % (P, self.ip_str(pi.Get(NMI, P)))
243 except:
244 print " Addresses:"
245 addrs = pi.Get(NMI, "Addresses")
246 for addr in addrs:
247 print " %s/%s via %s" % tuple(map(self.ip_str, addr))
248 hn = pi.Get(NMI, "Hostname")
249 print " Hostname:", hn
250 nss = pi.Get(NMI, "Nameservers")
251 print " Nameservers:", " ".join(map(self.ip_str, nss))
252 doms = pi.Get(NMI, "Domains")
253 print " Domains:", " ".join(doms)
254 nisd = pi.Get(NMI, "NisDomain")
255 print " NisDomain:", nisd
256 niss = pi.Get(NMI, "NisServers")
257 print " NisServers:", " ".join(map(self.ip_str, niss))
259 NM_DEVICE_CAP = {1: "NM_SUPPORTED", 2: "CARRIER_DETECT", 4: "SCANNING", }
262 def Dump(self):
263 print "Device:", self.opath
266 IW_MODE = ["AUTO", "ADHOC", "INFRA", "MASTER",
267 "REPEAT", "SECOND", "MONITOR",]
269 def APs(self):
270 return []
272 def ListNets(self):
273 for ap in self.APs():
274 ap.ListNets()
276 # mixin
277 class cDeviceEth:
278 pass
280 class cDevice_06(cDevice):
281 def DeviceType0(self):
282 if self.dt is None:
283 self.dt = self.devi.getProperties()[2]
284 if self.dt == 1:
285 self.__class__ = cDeviceEth_06
286 elif self.dt == 2:
287 self.__class__ = cDeviceWifi_06
288 return self.dt
290 NM_ACT_STAGE = [
291 "UNKNOWN", "DEVICE_PREPARE", "DEVICE_CONFIG", "NEED_USER_KEY",
292 "IP_CONFIG_START", "IP_CONFIG_GET", "IP_CONFIG_COMMIT",
293 "ACTIVATED", "FAILED", "CANCELLED", ]
295 def Dump(self):
296 cDevice.Dump(self)
297 print " Driver:", self.devi.getDriver()
298 props = self.devi.getProperties() # osusb ussss sssii biuus as
299 print " Self:", props[0] # o
300 print " Interface:", props[1] # s
301 print " Type:", self.DEVICE_TYPE[props[2]] # u
302 print " UDI:", props[3] # s
303 print " Active:", bool(props[4]) # b
304 print " Activation Stage:", self.NM_ACT_STAGE[props[5]] # u
305 print " IP:", props[6] # s
306 print " Mask:", props[7] # s
307 print " Bcast:", props[8] # s
308 print " HwAddress:", props[9] # s
309 print " GW:", props[10] # s
310 print " NS1:", props[11] # s
311 print " NS2:", props[12] # s
312 self.DumpMore()
314 def DumpMore(self):
315 print " (unknown device type, not dumping more)"
317 class cDeviceEth_06(cDevice_06, cDeviceEth):
318 def DumpMore(self):
319 props = self.devi.getProperties() # osusb ussss sssii biuus as
320 print " Link Active:", bool(props[15]) # b
321 print " Speed:", props[16] # i
322 print " Generic Capabilities:", bitmask_str(self.NM_DEVICE_CAP, props[17]) # u
324 class cDeviceWifi_06(cDevice_06):
325 NM_802_11_CAP = {
326 0x00000001: "PROTO_NONE",
327 0x00000002: "PROTO_WEP",
328 0x00000004: "PROTO_WPA",
329 0x00000008: "PROTO_WPA2",
330 0x00000010: "RESERVED1",
331 0x00000020: "RESERVED2",
332 0x00000040: "KEY_MGMT_PSK",
333 0x00000080: "KEY_MGMT_802_1X",
334 0x00000100: "RESERVED3",
335 0x00000200: "RESERVED4",
336 0x00000400: "RESERVED5",
337 0x00000800: "RESERVED6",
338 0x00001000: "CIPHER_WEP40",
339 0x00002000: "CIPHER_WEP104",
340 0x00004000: "CIPHER_TKIP",
341 0x00008000: "CIPHER_CCMP",
344 def APs(self):
345 self.wdevi = dbus.Interface(self.devo, NMI + ".Device.Wireless")
346 aps = self.devi.getProperties()[20]
347 return map(cAP_06, aps)
349 def DumpMore(self):
350 props = self.devi.getProperties() # osusb ussss sssii biuus as
351 print " Mode:", self.IW_MODE[props[13]] # i
352 print " Strength:", props[14] # i
353 print " Link Active:", bool(props[15]) # b
354 print " Speed:", props[16] # i
355 print " Generic Capabilities:", bitmask_str(self.NM_DEVICE_CAP, props[17]) # u
356 print " Capabilities:", bitmask_str(self.NM_802_11_CAP, props[18]) # u
357 print " Current net:", props[19] # s
358 nets = props[20] # as
359 print " Seen nets:", " ".join(nets)
360 if options.ap:
361 print " Access Points"
362 for ap in self.APs():
363 ap.Dump()
365 class cDevice_07(cDevice):
366 def DeviceType0(self):
367 if self.dt is None:
368 self.dt = self.devpi.Get(NMI, "DeviceType")
369 if self.dt == 1:
370 self.__class__ = cDeviceEth_07
371 elif self.dt == 2:
372 self.__class__ = cDeviceWifi_07
373 return self.dt
375 NM_DEVICE_STATE = [
376 "UNKNOWN", "UNMANAGED", "UNAVAILABLE", "DISCONNECTED", "PREPARE",
377 "CONFIG", "NEED_AUTH", "IP_CONFIG", "ACTIVATED", "FAILED",]
379 def Dump(self):
380 cDevice.Dump(self)
382 # "Ip4Config", only for NM_DEVICE_STATE_ACTIVATED
383 for P in ["Udi", "Interface", "Driver",]:
384 print " %s: %s" % (P, self.devpi.Get(NMI, P))
385 addr = self.devpi.Get(NMI, "Ip4Address")
386 print " Ip4Address:", self.ip_str(addr)
387 caps = self.devpi.Get(NMI, "Capabilities")
388 print " Capabilities:", bitmask_str(self.NM_DEVICE_CAP, caps)
389 state = self.NM_DEVICE_STATE[self.devpi.Get(NMI, "State")]
390 print " Dev State:", state
391 if state == "ACTIVATED":
392 self.DumpIp4Config(self.devpi.Get(NMI, "Ip4Config"))
394 dt = self.DeviceType()
395 print " Dev Type:", dt
396 self.DumpMore()
398 class cDeviceEth_07(cDevice_07, cDeviceEth):
399 def DumpMore(self):
400 for P in ["HwAddress", "Speed", "Carrier"]:
401 print " %s: %s" % (P, self.devpi.Get(NMI, P))
403 class cDeviceWifi_07(cDevice_07):
404 NM_802_11_DEVICE_CAP = {1:"CIPHER_WEP40", 2:"CIPHER_WEP104",
405 4:"CIPHER_TKIP", 8:"CIPHER_CCMP",
406 16:"WPA", 32:"RSN",}
408 def APs(self):
409 self.wdevi = dbus.Interface(self.devo, NMI + ".Device.Wireless")
410 aps = self.wdevi.GetAccessPoints()
411 return map(cAP_07, aps)
413 def DumpMore(self):
414 print " Dev Mode:", self.IW_MODE[self.devpi.Get(NMI, "Mode")]
415 wcaps = self.devpi.Get(NMI, "WirelessCapabilities")
416 print " Wifi Capabilities:", bitmask_str(self.NM_802_11_DEVICE_CAP, wcaps)
417 for P in ["HwAddress", "Bitrate", "ActiveAccessPoint"]:
418 print " %s: %s" % (P, self.devpi.Get(NMI, P))
419 if options.ap:
420 print " Access Points"
421 for ap in self.APs():
422 ap.Dump()
424 """An AP found around us"""
425 class cAP:
426 def __init__(self, opath):
427 self.opath = opath
428 self.apo = bus.get_object(NMC, self.opath)
429 self.appi = dbus.Interface(self.apo, PI)
430 # for _06
431 self.devi = dbus.Interface(self.apo, NMI + ".Devices")
433 NM_802_11_AP_FLAGS = {1: "PRIVACY",}
435 NM_802_11_AP_SEC = {
436 1: "PAIR_WEP40", 2: "PAIR_WEP104", 4: "PAIR_TKIP", 8: "PAIR_CCMP",
437 16: "GROUP_WEP40", 32: "GROUP_WEP104", 64: "GROUP_TKIP",
438 128: "GROUP_CCMP", 256: "KEY_MGMT_PSK", 512: "KEY_MGMT_802_1X",}
440 def ListNets(self, marker = " "):
441 # TODO *mark current
442 mbr = self.Mbr() / 1024 # 07 1000, 06 1024?
443 priv_s = self.PrivS()
444 print "%s%3d: %s (%dMb%s)" % (marker, self.Strength(), self.Ssid(), mbr, priv_s)
446 class cAP_06(cAP):
447 def Mbr(self, props=None):
448 if props is None:
449 props = self.devi.getProperties()
450 return props[5]
453 def PrivS(self):
454 props = self.devi.getProperties()
455 caps_s = bitmask_str(cDeviceWifi_06.NM_802_11_CAP, props[7]) + ","
456 priv_s = ""
457 if caps_s.find("PROTO_WEP,") != -1:
458 priv_s += " WEP"
459 if caps_s.find("PROTO_WPA,") != -1:
460 priv_s += " WPA"
461 if caps_s.find("PROTO_WPA2,") != -1:
462 priv_s += " WPA2"
463 if caps_s.find("KEY_MGMT_802_1X,") != -1:
464 priv_s += " Enterprise"
465 return priv_s
467 def Strength(self, props=None):
468 if props is None:
469 props = self.devi.getProperties()
470 return props[3]
472 def Ssid(self, props=None):
473 if props is None:
474 props = self.devi.getProperties()
475 return props[1]
478 def Dump(self):
479 props = self.devi.getProperties() # ossid iiib
480 print " Self:", props[0]
481 print " Ssid:", self.Ssid(props)
482 print " HwAddress:", props[2]
483 print " Strength:", self.Strength(props)
484 print " Frequency:", props[4]
485 print " MaxBitrate:", self.Mbr(props)
486 print " AP Mode:", cDevice.IW_MODE[props[6]]
487 print " Capabilities:", bitmask_str(cDeviceWifi_06.NM_802_11_CAP, props[7])
488 print " Broadcast:", props[8]
490 class cAP_07(cAP):
491 def Mbr(self):
492 return self.appi.Get(NMI, "MaxBitrate")
494 def PrivS(self):
495 priv = self.appi.Get(NMI, "Flags") != 0
496 wpa = self.appi.Get(NMI, "WpaFlags") != 0
497 wpa2 = self.appi.Get(NMI, "RsnFlags") != 0
498 priv_s = ""
499 if priv:
500 if not wpa and not wpa2:
501 priv_s = priv_s + " WEP"
502 if wpa:
503 priv_s = priv_s + " WPA"
504 if wpa2:
505 priv_s = priv_s + " WPA2"
506 return priv_s
508 def Strength(self):
509 return int(self.appi.Get(NMI, "Strength"))
511 def ssid_str(noself, array):
512 s = ""
513 for b in array:
514 s = s + ("%c" % b)
515 return s
517 def Ssid(self):
518 return self.ssid_str(self.appi.Get(NMI, "Ssid"))
520 def Dump(self):
521 print " AP:", self.opath
522 print " Ssid:", self.Ssid()
523 for P in ["Frequency", "HwAddress", "MaxBitrate",]:
524 print " %s: %s" % (P, self.appi.Get(NMI, P))
525 print " Strength:", self.Strength()
526 print " AP Mode:", cDevice.IW_MODE[self.appi.Get(NMI, "Mode")]
527 print " AP Flags:", bitmask_str(self.NM_802_11_AP_FLAGS,
528 self.appi.Get(NMI, "Flags"))
529 print " AP WPA Flags:", bitmask_str(self.NM_802_11_AP_SEC,
530 self.appi.Get(NMI, "WpaFlags"))
531 print " AP RSN Flags:", bitmask_str(self.NM_802_11_AP_SEC,
532 self.appi.Get(NMI, "RsnFlags"))
534 # this is the client side of the applet; see also UserSettings
535 class cApplet:
536 def __init__(self, svc, opath):
537 self.svc = svc
538 self.opath = opath
539 self.so = bus.get_object(self.svc, self.opath)
540 self.si = dbus.Interface(self.so, 'org.freedesktop.NetworkManagerSettings')
542 def isSystem(self):
543 return self.svc == SSC;
545 def Dump(self):
546 for conn in self.Connections():
547 conn.Dump()
548 if self.isSystem():
549 self.DumpSystem()
551 def DumpSystem(self):
552 sspi = dbus.Interface(self.so, PI)
553 print "Unmanaged Devices"
554 umds = sspi.Get(NMI, "UnmanagedDevices")
555 for umd in umds:
556 print " ", umd
557 # dump_settings_conn(svc, conn) umd?
560 def myConnection(self, opath):
561 return cConnection(self.svc, opath)
563 def Connections(self):
564 opaths = self.si.ListConnections()
565 return map(self.myConnection, opaths)
567 class cConnection:
568 def __init__(self, svc, opath):
569 self.svc = svc
570 self.opath = opath
571 self.co = bus.get_object(self.svc, self.opath)
572 self.ci = dbus.Interface(self.co, 'org.freedesktop.NetworkManagerSettings.Connection')
574 def Dump(self):
575 print "Conn:", self.opath
576 print " Id:", self.ci.GetID()
577 settings = self.Settings()
578 settings.Dump()
580 si = dbus.Interface(self.co, 'org.freedesktop.NetworkManagerSettings.Connection.Secrets')
581 security = settings.Security()
582 if security != "":
583 print " SECRETS:", security
584 # TODO merge them
585 secrets = cSettings(si.GetSecrets(security,[],False))
586 secrets.Dump()
588 def Settings(self):
589 return cSettings(self.ci.GetSettings())
592 class cSettings:
593 def __init__(self, conmap):
594 self.conmap = conmap
596 def Type(self):
597 return self.conmap["connection"]["type"]
599 def GetID(self):
600 return self.conmap["connection"]["id"]
602 def Security(self):
603 try:
604 return self.conmap[self.Type()]["security"]
605 except KeyError:
606 return ""
608 def isNet(self, net_name):
609 # FIXME also ssid ...
610 return self.GetID() == net_name
612 # FIXME check spec/NM what to censor
613 secrets = dict.fromkeys(["wep-key0", "psk"])
615 def ConMap(self):
616 "For GetSettings: censor secrets."
618 cm = dict()
619 for n1, v1 in self.conmap.iteritems():
620 cm[n1] = dict()
621 for n2, v2 in v1.iteritems():
622 cv2 = v2
623 if self.secrets.has_key(n2):
624 cv2 = ""
625 cm[n1][n2] = cv2
626 return cm
628 def SecMap(self):
629 "For GetSecrets: only secrets."
630 s = self.Security()
631 r = {
632 s: self.conmap[s]
634 print "SECMAP", r
635 return r
637 def Dump(self):
638 for n1, v1 in self.conmap.iteritems():
639 print " ",n1
640 for n2, v2 in v1.iteritems():
641 print " %s: %s" % (n2, v2)
643 # just an example, unused now
644 hardwired_conmaps = [
646 "connection": {
647 "id": "onenet",
648 "type": "802-11-wireless",
650 "802-11-wireless": {
651 "ssid": dbus.ByteArray("onenet"),
652 "mode": "infrastructure",
653 "security": "802-11-wireless-security",
655 # ipv4
656 # method: dhcp
657 "802-11-wireless-security": {
658 "key-mgmt": "wpa-psk",
659 "wep-tx-keyidx": 0,
660 "psk": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", # CENSORED
664 'connection': {
665 'id': 'frogs',
666 'type': '802-11-wireless',
668 '802-11-wireless': {
669 'ssid': dbus.ByteArray('frogs'),
670 'mode': 'infrastructure',
671 'security': '802-11-wireless-security',
673 '802-11-wireless-security': {
674 'key-mgmt': 'none',
675 'wep-tx-keyidx': 0,
676 'wep-key0': 'aaaaaaaaaaaaaaaaaaaaaaaaaa', # CENSORED
681 class UserSettings_06:
682 @dbus.service.method(dbus_interface="org.freedesktop.NetworkManagerInfo",
683 in_signature="i", out_signature='as')
684 def getNetworks(self, i):
685 return ["frogs"] # FIXME
687 @dbus.service.method(dbus_interface="org.freedesktop.NetworkManagerInfo",
688 in_signature="", out_signature='ao') # out??
689 def getVpnConnections(self):
690 return [] # FIXME
692 @dbus.service.method(dbus_interface="org.freedesktop.NetworkManagerInfo",
693 in_signature="si", out_signature='sibasisi')
694 # or additional i ???
695 def getNetworkProperties(self, net, i):
696 # essid, timestamp, ?, bssids, we_cipher, ?, ...
697 # we_cipher=16: i wep_auth_algorithm
698 # we_cipher=0: i wpa_psk_key_mgt, i wpa_psk_wpa_version
699 return ("frogs", 1213713468, 0, ['00:13:10:06:E3:77'], 16, "", 1)
700 return [] # FIXME
702 @dbus.service.method(dbus_interface="org.freedesktop.NetworkManagerInfo",
703 in_signature="oosib", out_signature="isi")
704 def getKeyForNetwork(self, dev, net, ssid, i, b):
705 return (16, "66666666666666666666666666",1) # FIXME
707 @dbus.service.method(dbus_interface="org.freedesktop.NetworkManagerInfo",
708 in_signature="sbsisi", out_signature='')
709 def updateNetworkInfo(self, ssid, b, ap, i1, secret, i2):
710 pass
714 # server analog of cApplet
715 class UserSettings(dbus.service.Object):
716 # conmaps is a list
717 def __init__(self, opath, conmaps):
718 dbus.service.Object.__init__(self, bus, opath)
719 #print "CONMAPS:", conmaps
720 self.conns = map(self.newCon, conmaps)
722 counter = 1
723 def newCon(self, conmap):
724 cpath = "/MyConnection/%d" % self.counter
725 self.counter = self.counter + 1
726 c = Connection(cpath, conmap)
727 self.NewConnection(cpath) # announce it
728 return c
730 @dbus.service.method(dbus_interface='org.freedesktop.NetworkManagerSettings',
731 in_signature='', out_signature='ao')
732 def ListConnections(self):
733 return [c.__dbus_object_path__ for c in self.conns]
735 #this is for EMITTING a signal, not receiving it
736 @dbus.service.signal(dbus_interface='org.freedesktop.NetworkManagerSettings',
737 signature='o')
738 def NewConnection(self, opath):
739 pass
740 #print "signalling newconn:", opath
742 def GetByNet(self, net_name):
743 "Returns connection, or None"
744 for c in self.conns:
745 if c.isNet(net_name):
746 return c
747 return None
750 # server analog of cConnection
751 class Connection(dbus.service.Object):
752 def __init__(self, opath, conmap):
753 dbus.service.Object.__init__(self, bus, opath)
754 self.settings = cSettings(conmap)
756 @dbus.service.method(dbus_interface='org.freedesktop.NetworkManagerSettings.Connection',
757 in_signature='', out_signature='a{sa{sv}}')
758 def GetSettings(self):
759 #print "Getting settings:", self. __dbus_object_path__
760 # return self.settings.ConMap()
761 # grr, censoring secrets makes NM complain!?
762 return self.settings.conmap
764 @dbus.service.method(dbus_interface='org.freedesktop.NetworkManagerSettings.Connection.Secrets',
765 in_signature='sasb', out_signature='a{sa{sv}}')
766 def GetSecrets(self, tag, hints, ask):
767 # FIXME respect args
768 print "Getting secrets:", self.__dbus_object_path__
769 return self.settings.SecMap()
771 @dbus.service.method(dbus_interface='org.freedesktop.NetworkManagerSettings.Connection',
772 in_signature='', out_signature='s')
773 def GetID(self):
774 return self.settings.GetID()
776 def isNet(self, net_name):
777 return self.settings.isNet(net_name)
779 class ConfigParserKNM:
780 "Parse ~/.kde/share/config/knetworkmanagerrc"
782 def __init__(self):
783 p = ConfigParser.RawConfigParser()
784 ok = p.read(os.getenv("HOME") + "/.kde/share/config/knetworkmanagerrc")
786 self.conmaps_d = {}
787 for s in p.sections():
788 path = s.split("_")
789 #print path
790 if path[0] in ["ConnectionSetting", "ConnectionSecrets"]:
791 cid = path[1]
792 self.conmaps_d.setdefault(cid, {})
793 part = path[2]
795 values = {}
796 for (n, v) in p.items(s):
797 # WTF, Value_ is transfrmed to value_
798 if n[:6] == "value_":
799 n = n[6:]
800 v = self.ParseValue(v)
801 values[n] = v
802 if len(values) != 0: # empty 802-1x confuses NM!?
803 self.conmaps_d[cid].setdefault(part, {})
804 self.conmaps_d[cid][part].update(**values)
805 #print "PARSED", cid, part, values
807 def ConMaps(self):
808 return self.conmaps_d.values()
810 def ParseValue(self, v):
811 v = eval('"%s"' % v) # unescape backslashes
812 dom = xml.dom.minidom.parseString(v)
813 return self.ParseNode(dom.documentElement)
815 def ParseNode(self, n):
816 t = n.localName
817 if t != "list":
818 v = self.NodeText(n)
820 if t == "string":
821 return v
822 elif t == "byte":
823 return dbus.Byte(int(v))
824 elif t == "bool":
825 return v == "true"
826 elif t == "int32" or t == "uint32":
827 return int(v)
828 elif t == "list":
829 v = []
830 c = n.firstChild
831 while c != None:
832 if c.localName != None: # whitespace
833 v.append(self.ParseNode(c))
834 c = c.nextSibling
835 return v
837 def NodeText(self, n):
838 if n.hasChildNodes():
839 return n.firstChild.wholeText
840 else:
841 return ""
843 def abbr_signal_handler(*args, **kwargs):
844 ifc = kwargs["interface"]
845 sig = kwargs["member"]
846 opath = kwargs["path"]
847 line = "SIG %s: %s.%s%s" % (abbrev(opath,"/"), abbrev(ifc,"."), sig, args)
848 print line
850 class Monitor:
851 def __init__(self):
852 self.amap = {}
853 bus.add_signal_receiver(self.abbr_signal_handler,
854 path_keyword="path",
855 interface_keyword="interface",
856 member_keyword="member")
858 def abbr_signal_handler(self, *args, **kwargs):
859 ifc = kwargs["interface"]
860 sig = kwargs["member"]
861 opath = kwargs["path"]
862 line = "SIG %s: %s.%s%s" % (self.abbrev(opath,"/"),
863 self.abbrev(ifc,"."),
864 sig, args)
865 print line
867 def abbrev(self, s, sep):
868 words = s.split(sep)
869 words = map (self.a1, words)
870 result = sep.join(words)
871 if not self.amap.has_key(s):
872 print "ABBR %s is %s" % (result, s)
873 self.amap[s] = result
874 else:
875 if self.amap[s] != result:
876 print "ABBR COLLISION %s was %s now %s" % (s, self.amap[s], result)
877 return result
879 def a1(self, s):
880 try:
881 return s[0]
882 except:
883 return ""
885 # main
887 op = OptionParser(version="%prog " + VERSION)
888 op.add_option("-d", "--dev",
889 action="store_true", default=False,
890 help="list devices")
891 op.add_option("-c", "--actcon",
892 action="store_true", default=False,
893 help="list active connections")
894 op.add_option("-u", "--usrcon",
895 action="store_true", default=False,
896 help="list user connection settings (can CRASH nm-applet)")
897 op.add_option("-s", "--syscon",
898 action="store_true", default=False,
899 help="list system connection settings")
900 op.add_option("-a", "--ap",
901 action="store_true", default=False,
902 help="list found access points")
903 op.add_option("-n", "--nets",
904 action="store_true", default=False,
905 help="list found wireless networks")
906 # TODO http://docs.python.org/lib/optparse-adding-new-types.html
907 op.add_option("-w", "--wifi",
908 choices=["0","1","off","on","no","yes","false","true"],
909 metavar="BOOL",
910 help="enable or disable wireless")
911 op.add_option("-o", "--online",
912 choices=["0","1","off","on","no","yes","false","true"],
913 metavar="BOOL",
914 help="enable or disable network at all")
916 op.add_option("-C", "--connect",
917 help="connect to a wireless network NET (using knetworkmanagerrc)",
918 metavar="NET")
919 op.add_option("-m", "--monitor",
920 action="store_true", default=False,
921 help="loop to show dbus signals")
924 (options, args) = op.parse_args()
926 if options.ap:
927 options.dev = True
928 if options.monitor:
929 LOOP = True
932 nmp = '/org/freedesktop/NetworkManager'
933 try:
934 nm = make_nm(nmp)
935 except dbus.exceptions.DBusException, e:
936 print e
937 print "NetworkManager is not running"
938 sys.exit(1)
939 if options.dev or options.actcon:
940 nm.Dump()
942 true_choices = ["1", "on", "yes", "true"]
943 if options.wifi != None:
944 nm.SetWifiEnabled(options.wifi in true_choices)
945 if options.online != None:
946 nm.SetOnline(options.online in true_choices)
948 if options.nets:
949 nm.ListNets()
951 if options.syscon:
952 print "SYSTEM Connections"
953 ss = cApplet(SSC, '/org/freedesktop/NetworkManagerSettings')
954 ss.Dump()
956 if options.usrcon:
957 print "USER Connections"
958 try:
959 us = cApplet(USC, '/org/freedesktop/NetworkManagerSettings')
960 us.Dump()
961 except dbus.exceptions.DBusException, e:
962 print e
963 #if e.get_dbus_name() == "org.freedesktop.DBus.Error.ServiceUnknown":
964 print "Applet is not running"
966 nmo = bus.get_object(NMC, nmp)
967 nmi = dbus.Interface(nmo, NMI)
969 # TODO UserSettings_06
970 if options.connect != None:
971 brn = bus.request_name(USC, _dbus_bindings.NAME_FLAG_DO_NOT_QUEUE)
972 if brn == _dbus_bindings.REQUEST_NAME_REPLY_EXISTS:
973 print "Could not provide settings service, another applet is running"
974 sys.exit(1)
975 cfg = ConfigParserKNM()
976 us = UserSettings("/org/freedesktop/NetworkManagerSettings",
977 cfg.ConMaps())
979 def Connect(wanted_net): # any. or take arg. net is config name or ssid name
980 # ... in general, look for string in all config data. ssid for wifi, whatever for dialup
981 # TODO also respect autoconnect
983 # ActivateConn wants setting device ap; can find device from ap? ap is "specific" for wifi devices
984 #print "Connection wanted to", wanted_net
985 found_con = found_ap = found_dev = None
986 for dev in nm.Devices():
987 for ap in dev.APs():
988 if wanted_net == ap.Ssid():
989 found_ap = ap
990 found_dev = dev
991 break # FIXME both loops
992 found_con = us.GetByNet(wanted_net)
993 if found_ap == None:
994 print "No AP found with SSID", wanted_net
995 return False
996 elif found_con == None:
997 print "No settings for net", wanted_net
998 return False
999 else:
1000 nm.ActivateConnection(found_con, found_dev, found_ap) # TODO async
1001 # TODO run loop, exit it when we have serviced the required calls
1002 return True
1004 if options.connect != None:
1005 if Connect(options.connect):
1006 LOOP = True
1008 if options.monitor:
1009 m = Monitor()
1011 def loop():
1012 loop = gobject.MainLoop()
1013 try:
1014 loop.run()
1015 except:
1016 print "Loop exited"
1018 if LOOP:
1019 loop()