2 * Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 //! The backbone of the NetworkAvailable event, and condition.
10 #include "NetworkWatcher.h"
12 #include <Application.h>
14 #include <NetworkDevice.h>
15 #include <NetworkInterface.h>
16 #include <NetworkRoster.h>
21 static const bigtime_t kNetworkUpdateInterval
= 1000000;
22 // Update network availability every second
24 static BLocker
sLocker("network watcher");
25 static NetworkWatcher
* sWatcher
;
27 static bool sLastNetworkAvailable
;
28 static bigtime_t sLastNetworkUpdate
;
31 NetworkListener::~NetworkListener()
39 NetworkWatcher::NetworkWatcher()
41 BHandler("network watcher"),
45 be_app
->AddHandler(this);
47 start_watching_network(B_WATCH_NETWORK_INTERFACE_CHANGES
48 | B_WATCH_NETWORK_LINK_CHANGES
, this);
54 NetworkWatcher::~NetworkWatcher()
57 stop_watching_network(this);
59 be_app
->RemoveHandler(this);
66 NetworkWatcher::AddListener(NetworkListener
* listener
)
68 BAutolock
lock(sLocker
);
69 fListeners
.AddItem(listener
);
71 if (fListeners
.CountItems() == 1)
77 NetworkWatcher::RemoveListener(NetworkListener
* listener
)
79 BAutolock
lock(sLocker
);
80 fListeners
.RemoveItem(listener
);
85 NetworkWatcher::CountListeners() const
87 BAutolock
lock(sLocker
);
88 return fListeners
.CountItems();
93 NetworkWatcher::MessageReceived(BMessage
* message
)
95 switch (message
->what
) {
96 case B_NETWORK_MONITOR
:
104 NetworkWatcher::Register(NetworkListener
* listener
)
106 BAutolock
lock(sLocker
);
107 if (sWatcher
== NULL
)
108 sWatcher
= new NetworkWatcher();
110 sWatcher
->AddListener(listener
);
115 NetworkWatcher::Unregister(NetworkListener
* listener
)
117 BAutolock
lock(sLocker
);
118 sWatcher
->RemoveListener(listener
);
120 if (sWatcher
->CountListeners() == 0)
126 NetworkWatcher::NetworkAvailable(bool immediate
)
129 && system_time() - sLastNetworkUpdate
< kNetworkUpdateInterval
) {
130 return sLastNetworkAvailable
;
133 bool isAvailable
= false;
135 BNetworkRoster
& roster
= BNetworkRoster::Default();
136 BNetworkInterface interface
;
138 while (roster
.GetNextInterface(&cookie
, interface
) == B_OK
) {
139 uint32 flags
= interface
.Flags();
140 if ((flags
& (IFF_LOOPBACK
| IFF_CONFIGURING
| IFF_UP
| IFF_LINK
))
141 == (IFF_UP
| IFF_LINK
)) {
147 sLastNetworkAvailable
= isAvailable
;
148 sLastNetworkUpdate
= system_time();
154 NetworkWatcher::UpdateAvailability()
156 bool isAvailable
= NetworkAvailable(true);
157 if (isAvailable
!= fAvailable
) {
158 fAvailable
= isAvailable
;
160 BAutolock
lock(sLocker
);
161 for (int32 i
= 0; i
< fListeners
.CountItems(); i
++) {
162 fListeners
.ItemAt(i
)->NetworkAvailabilityChanged(fAvailable
);