2012-01-20 14 views
3

私は、LinuxボックスでWifiに接続して切断する必要があるPythonアプリケーションを構築しています。私はNetworkManager層を使用しています。ネットワークマネージャーのlib(cnetworkmanagerにあるNetworkManager http://vidner.net/martin/software/cnetworkmanager/のpython CLI、Martin Vidnerにはありません)、デーモン(stationdという名前)にあります。 このデーモンはgobject.MainLoopを実行します。 timeout_add_seconds目を覚まし(GUIにおけるユーザーの行動によってトリガ)したら、私は現在実行中の無線LAN接続を切断し、新しいものに接続する必要があります。NetworkManagerとPythonを使ってWiFiアクセスポイントを切断する

from dbus.mainloop.glib import DBusGMainLoop 
DBusGMainLoop(set_as_default=True) 

from networkmanager import NetworkManager 
import networkmanager.applet.settings as settings 
from networkmanager.applet import USER_SERVICE 
from networkmanager.applet.service import NetworkManagerUserSettings, NetworkManagerSettings 
import time 
import memcache 

import gobject 
loop = gobject.MainLoop() 

nm = NetworkManager() 

dummy_handler = lambda *args: None 

cache = memcache.Client(['127.0.0.1:11211',]) 


def get_device(dev_spec, hint): 
    candidates = [] 
    devs = NetworkManager().GetDevices() 
    for dev in devs: 
     if dev._settings_type() == hint: 
      candidates.append(dev) 
    if len(candidates) == 1: 
     return candidates[0] 
    for dev in devs: 
     if dev["Interface"] == dev_spec: 
      return dev 
    print "Device '%s' not found" % dev_spec 
    return None 

def kill_allconnections(): 
    connections=nm['ActiveConnections'] 
    for c in connections: 
     print c.object_path 
     nm.DeactivateConnection(c.object_path) 

class Wifi(object): 

    def connect(self, ssid, security="open", password=None): 
     "Connects to given Wifi network" 
     c=None # connection settings 
     us = NetworkManagerUserSettings([]) 
     if security=="open": 
      c = settings.WiFi(ssid) 
     elif security=="wep": 
      c = settings.Wep(ssid, password) 
     elif security=="wpa": 
      c = settings.WpaPsk(ssid, password) 
     else: 
      raise AttributeError("invalid security model '%s'"%security) 
     svc = USER_SERVICE 
     svc_conn = us.addCon(c.conmap) 
     hint = svc_conn.settings["connection"]["type"] 
     dev = get_device("", hint) 
     appath = "/" 
     nm.ActivateConnection(svc, svc_conn, dev, appath, reply_handler=dummy_handler, error_handler=dummy_handler) 


def change_network_settings(): 
    key="station:network:change" 
    change=cache.get(key) 
    if change is not None: 
     print "DISCONNECT" 
     kill_allconnections() 
     print "CHANGE SETTINGS" 
     wifi=cache.get(key+':wifi') 
     if wifi is not None: 
      ssid=cache.get(key+':wifi:ssid') 
      security=cache.get(key+':wifi:security') 
      password=cache.get(key+':wifi:password') 
      print "SWITCHING TO %s"%ssid 
      Wifi().connect(ssid, security, password) 
     cache.delete(key) 
    return True  

def mainloop(): 
    gobject.timeout_add_seconds(1, change_network_settings) 
    try: 
     loop.run() 
    except KeyboardInterrupt: 
     loop.quit() 

if __name__=="__main__": 
    mainloop() 

これは、最初の接続のために完璧に動作します(読み:ボックスではありませんデーモンは走り、ボックスは無事にWifiに接続します)。私は別の無線LANに接続しようとすると問題がある:kill_allconnectionsは、()静かに走り、方法はnm.ActivateConnection上の例外を発生させる接続されています

Traceback (most recent call last): 
    File "stationd.py", line 40, in change_network_settings 
    Wifi().connect(ssid, security, password) 
    File "/home/biopredictive/station/lib/network.py", line 88, in connect 
    us = NetworkManagerUserSettings([]) 
    File "/home/biopredictive/station/lib/networkmanager/applet/service/__init__.py", line 71, in __init__ 
    super(NetworkManagerUserSettings, self).__init__(conmaps, USER_SERVICE) 
    File "/home/biopredictive/station/lib/networkmanager/applet/service/__init__.py", line 33, in __init__ 
    dbus.service.Object.__init__(self, bus, opath, bus_name) 
    File "/usr/lib/pymodules/python2.6/dbus/service.py", line 480, in __init__ 
    self.add_to_connection(conn, object_path) 
    File "/usr/lib/pymodules/python2.6/dbus/service.py", line 571, in add_to_connection 
    self._fallback) 
KeyError: "Can't register the object-path handler for '/org/freedesktop/NetworkManagerSettings': there is already a handler" 

私の以前の接続は、すべてのリソースを解放していないように見えますか? 私はgobject/dbusプログラミングの新機能です。助けてくれませんか?

+0

助けてください! :) –

答えて

3

D-Busメーリングリストにansweredがあります。アーカイブについてここで引用します:

class Wifi(...): 
    def connect(...): 
     ... 
     us = NetworkManagerUserSettings([]) 

NetworkManagerUserSettingsはクライアントではなくサーバーです。 ( NM 0.9の中で削除されたNMのクール) デーモン用に1つだけ作成し、各接続用には を作成しないでください。

関連する問題