NetWatcher: detect when networkmanager has lost network connection
This is a better approach to finding both when NM has lost a network connection, and when a new network connection is made by NM. Tested with network-manager 0.9.8.8. This commit was sponsored by Cedric Staub.
This commit is contained in:
parent
a33b30d0c4
commit
bb44df206d
2 changed files with 37 additions and 25 deletions
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue