diff options
-rw-r--r-- | Assistant/Threads/NetWatcher.hs | 56 | ||||
-rw-r--r-- | doc/design/git-remote-daemon.mdwn | 6 |
2 files changed, 37 insertions, 25 deletions
diff --git a/Assistant/Threads/NetWatcher.hs b/Assistant/Threads/NetWatcher.hs index 0ff605edc..c1115f637 100644 --- a/Assistant/Threads/NetWatcher.hs +++ b/Assistant/Threads/NetWatcher.hs @@ -22,7 +22,6 @@ import Utility.NotificationBroadcaster import Utility.DBus import DBus.Client import DBus -import Data.Word (Word32) import Assistant.NetMessager #else #ifdef linux_HOST_OS @@ -63,15 +62,19 @@ dbusThread = do where go client = ifM (checkNetMonitor client) ( do - listenNMConnections client <~> handleconn - listenWicdConnections client <~> handleconn + callback <- asIO1 connchange + liftIO $ do + listenNMConnections client callback + listenWicdConnections client callback , do liftAnnex $ warning "No known network monitor available through dbus; falling back to polling" ) - handleconn = do - debug ["detected network connection"] + connchange False = do + debug ["detected network disconnection"] sendRemoteControl LOSTNET + connchange True = do + debug ["detected network connection"] notifyNetMessagerRestart handleConnection sendRemoteControl RESUME @@ -99,31 +102,40 @@ checkNetMonitor client = do networkmanager = "org.freedesktop.NetworkManager" wicd = "org.wicd.daemon" -{- Listens for new NetworkManager connections. -} -listenNMConnections :: Client -> IO () -> IO () -listenNMConnections client callback = - listen client matcher $ \event -> - when (Just True == anyM activeconnection (signalBody event)) $ - callback +{- Listens for NetworkManager connections and diconnections. + - + - Connection example (once fully connected): + - [Variant {"ActivatingConnection": Variant (ObjectPath "/"), "PrimaryConnection": Variant (ObjectPath "/org/freedesktop/NetworkManager/ActiveConnection/34"), "State": Variant 70}] + - + - Disconnection example: + - [Variant {"ActiveConnections": Variant []}] + -} +listenNMConnections :: Client -> (Bool -> IO ()) -> IO () +listenNMConnections client setconnected = + listen client matcher $ \event -> mapM_ handle + (map dictionaryItems $ mapMaybe fromVariant $ signalBody event) where matcher = matchAny - { matchInterface = Just "org.freedesktop.NetworkManager.Connection.Active" + { matchInterface = Just "org.freedesktop.NetworkManager" , matchMember = Just "PropertiesChanged" } - nm_connection_activated = toVariant (2 :: Word32) - nm_state_key = toVariant ("State" :: String) - activeconnection v = do - m <- fromVariant v - vstate <- lookup nm_state_key $ dictionaryItems m - state <- fromVariant vstate - return $ state == nm_connection_activated + nm_active_connections_key = toVariant ("ActiveConnections" :: String) + nm_activatingconnection_key = toVariant ("ActivatingConnection" :: String) + noconnections = Just $ toVariant $ toVariant ([] :: [ObjectPath]) + rootconnection = Just $ toVariant $ toVariant $ objectPath_ "/" + handle m + | lookup nm_active_connections_key m == noconnections = + setconnected False + | lookup nm_activatingconnection_key m == rootconnection = + setconnected True + | otherwise = noop -{- Listens for new Wicd connections. -} -listenWicdConnections :: Client -> IO () -> IO () +{- Listens for Wicd connections (not currently disconnections). -} +listenWicdConnections :: Client -> (Bool -> IO ()) -> IO () listenWicdConnections client callback = listen client matcher $ \event -> when (any (== wicd_success) (signalBody event)) $ - callback + callback False >> callback True where matcher = matchAny { matchInterface = Just "org.wicd.daemon" diff --git a/doc/design/git-remote-daemon.mdwn b/doc/design/git-remote-daemon.mdwn index a3d07eaa6..a0e24198c 100644 --- a/doc/design/git-remote-daemon.mdwn +++ b/doc/design/git-remote-daemon.mdwn @@ -164,9 +164,9 @@ No pushing is done for CHANGED, since git handles ssh natively. TODO: -* The NetWatcher does not detect network loss, only network gain, - so PAUSE is only sent when a new network is detected, followed - immediately by RESUME. +* For wicd, the NetWatcher does not detect network loss, only network gain. + So PAUSE is only sent when a new network is detected, followed + immediately by RESUME. This was already fixed for networkmanager. * Remote system might not be available. Find a smart way to detect it, ideally w/o generating network traffic. One way might be to check if the ssh connection caching control socket exists, for example. |