* Removed the polling of the network status; instead, it now uses the new
network notifications. * It also doesn't keep a socket open over the whole time which would prevent the network stack to be unloaded. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29904 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src apps networkstatus ;
|
|||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
UsePrivateHeaders shared ;
|
UsePrivateHeaders net shared ;
|
||||||
UseLibraryHeaders agg icon ;
|
UseLibraryHeaders agg icon ;
|
||||||
|
|
||||||
local icon_libs ;
|
local icon_libs ;
|
||||||
|
|||||||
@@ -11,8 +11,14 @@
|
|||||||
|
|
||||||
#include "NetworkStatusView.h"
|
#include "NetworkStatusView.h"
|
||||||
|
|
||||||
#include "NetworkStatus.h"
|
#include <arpa/inet.h>
|
||||||
#include "NetworkStatusIcons.h"
|
#include <net/if.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
@@ -29,22 +35,11 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <net_notifications.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <stdio.h>
|
#include "NetworkStatus.h"
|
||||||
#include <stdlib.h>
|
#include "NetworkStatusIcons.h"
|
||||||
#include <string.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
// BONE compatibility
|
|
||||||
# define IF_NAMESIZE IFNAMSIZ
|
|
||||||
# define IFF_LINK 0
|
|
||||||
# define IFF_CONFIGURING 0
|
|
||||||
# define ifc_value ifc_val
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *kStatusDescriptions[] = {
|
static const char *kStatusDescriptions[] = {
|
||||||
"Unknown",
|
"Unknown",
|
||||||
@@ -57,15 +52,41 @@ static const char *kStatusDescriptions[] = {
|
|||||||
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
||||||
|
|
||||||
|
|
||||||
const uint32 kMsgUpdate = 'updt';
|
|
||||||
const uint32 kMsgShowConfiguration = 'shcf';
|
const uint32 kMsgShowConfiguration = 'shcf';
|
||||||
const uint32 kMsgOpenNetworkPreferences = 'onwp';
|
const uint32 kMsgOpenNetworkPreferences = 'onwp';
|
||||||
|
|
||||||
const uint32 kMinIconWidth = 16;
|
const uint32 kMinIconWidth = 16;
|
||||||
const uint32 kMinIconHeight = 16;
|
const uint32 kMinIconHeight = 16;
|
||||||
|
|
||||||
const bigtime_t kUpdateInterval = 1000000;
|
|
||||||
// every second
|
class SocketOpener {
|
||||||
|
public:
|
||||||
|
SocketOpener()
|
||||||
|
{
|
||||||
|
fSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SocketOpener()
|
||||||
|
{
|
||||||
|
close(fSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t InitCheck()
|
||||||
|
{
|
||||||
|
return fSocket >= 0 ? B_OK : B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int() const
|
||||||
|
{
|
||||||
|
return fSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fSocket;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode,
|
NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode,
|
||||||
@@ -111,8 +132,6 @@ NetworkStatusView::~NetworkStatusView()
|
|||||||
void
|
void
|
||||||
NetworkStatusView::_Init()
|
NetworkStatusView::_Init()
|
||||||
{
|
{
|
||||||
fMessageRunner = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < kStatusCount; i++) {
|
for (int i = 0; i < kStatusCount; i++) {
|
||||||
fBitmaps[i] = NULL;
|
fBitmaps[i] = NULL;
|
||||||
}
|
}
|
||||||
@@ -206,10 +225,9 @@ NetworkStatusView::AttachedToWindow()
|
|||||||
|
|
||||||
SetLowColor(ViewColor());
|
SetLowColor(ViewColor());
|
||||||
|
|
||||||
BMessage update(kMsgUpdate);
|
start_watching_network(
|
||||||
fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval);
|
B_WATCH_NETWORK_INTERFACE_CHANGES | B_WATCH_NETWORK_LINK_CHANGES, this);
|
||||||
|
|
||||||
fSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
_Update();
|
_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,8 +235,7 @@ NetworkStatusView::AttachedToWindow()
|
|||||||
void
|
void
|
||||||
NetworkStatusView::DetachedFromWindow()
|
NetworkStatusView::DetachedFromWindow()
|
||||||
{
|
{
|
||||||
delete fMessageRunner;
|
stop_watching_network(this);
|
||||||
close(fSocket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -226,7 +243,7 @@ void
|
|||||||
NetworkStatusView::MessageReceived(BMessage* message)
|
NetworkStatusView::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case kMsgUpdate:
|
case B_NETWORK_MONITOR:
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -276,8 +293,8 @@ void
|
|||||||
NetworkStatusView::_ShowConfiguration(BMessage* message)
|
NetworkStatusView::_ShowConfiguration(BMessage* message)
|
||||||
{
|
{
|
||||||
static const struct information_entry {
|
static const struct information_entry {
|
||||||
const char *label;
|
const char* label;
|
||||||
int32 control;
|
int32 control;
|
||||||
} kInformationEntries[] = {
|
} kInformationEntries[] = {
|
||||||
{ "Address", SIOCGIFADDR },
|
{ "Address", SIOCGIFADDR },
|
||||||
{ "Broadcast", SIOCGIFBRDADDR },
|
{ "Broadcast", SIOCGIFBRDADDR },
|
||||||
@@ -285,7 +302,11 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *name;
|
SocketOpener socket;
|
||||||
|
if (socket.InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* name;
|
||||||
if (message->FindString("interface", &name) != B_OK)
|
if (message->FindString("interface", &name) != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -298,7 +319,7 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
|
|||||||
size_t boldLength = text.Length();
|
size_t boldLength = text.Length();
|
||||||
|
|
||||||
for (int i = 0; kInformationEntries[i].label; i++) {
|
for (int i = 0; kInformationEntries[i].label; i++) {
|
||||||
if (ioctl(fSocket, kInformationEntries[i].control, &request,
|
if (ioctl(socket, kInformationEntries[i].control, &request,
|
||||||
sizeof(request)) < 0) {
|
sizeof(request)) < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -341,7 +362,7 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
|
|||||||
void
|
void
|
||||||
NetworkStatusView::MouseDown(BPoint point)
|
NetworkStatusView::MouseDown(BPoint point)
|
||||||
{
|
{
|
||||||
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||||
menu->SetAsyncAutoDestruct(true);
|
menu->SetAsyncAutoDestruct(true);
|
||||||
menu->SetFont(be_plain_font);
|
menu->SetFont(be_plain_font);
|
||||||
|
|
||||||
@@ -376,7 +397,7 @@ NetworkStatusView::MouseDown(BPoint point)
|
|||||||
void
|
void
|
||||||
NetworkStatusView::_AboutRequested()
|
NetworkStatusView::_AboutRequested()
|
||||||
{
|
{
|
||||||
BAlert *alert = new BAlert("about", "NetworkStatus\n"
|
BAlert* alert = new BAlert("about", "NetworkStatus\n"
|
||||||
"\twritten by Axel Dörfler and Hugo Santos\n"
|
"\twritten by Axel Dörfler and Hugo Santos\n"
|
||||||
"\tCopyright 2007, Haiku, Inc.\n", "Ok");
|
"\tCopyright 2007, Haiku, Inc.\n", "Ok");
|
||||||
BTextView *view = alert->TextView();
|
BTextView *view = alert->TextView();
|
||||||
@@ -407,12 +428,16 @@ NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name)
|
|||||||
int32
|
int32
|
||||||
NetworkStatusView::_DetermineInterfaceStatus(const char* name)
|
NetworkStatusView::_DetermineInterfaceStatus(const char* name)
|
||||||
{
|
{
|
||||||
|
SocketOpener socket;
|
||||||
|
if (socket.InitCheck() != B_OK)
|
||||||
|
return kStatusUnknown;
|
||||||
|
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (!_PrepareRequest(request, name))
|
if (!_PrepareRequest(request, name))
|
||||||
return kStatusUnknown;
|
return kStatusUnknown;
|
||||||
|
|
||||||
uint32 flags = 0;
|
uint32 flags = 0;
|
||||||
if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
|
if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
|
||||||
flags = request.ifr_flags;
|
flags = request.ifr_flags;
|
||||||
|
|
||||||
int32 status = kStatusNoLink;
|
int32 status = kStatusNoLink;
|
||||||
@@ -431,29 +456,33 @@ NetworkStatusView::_DetermineInterfaceStatus(const char* name)
|
|||||||
void
|
void
|
||||||
NetworkStatusView::_Update(bool force)
|
NetworkStatusView::_Update(bool force)
|
||||||
{
|
{
|
||||||
|
SocketOpener socket;
|
||||||
|
if (socket.InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
// iterate over all interfaces and retrieve minimal status
|
// iterate over all interfaces and retrieve minimal status
|
||||||
|
|
||||||
ifconf config;
|
ifconf config;
|
||||||
config.ifc_len = sizeof(config.ifc_value);
|
config.ifc_len = sizeof(config.ifc_value);
|
||||||
if (ioctl(fSocket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
|
if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 count = (uint32)config.ifc_value;
|
uint32 count = (uint32)config.ifc_value;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void *buffer = malloc(count * sizeof(struct ifreq));
|
void* buffer = malloc(count * sizeof(struct ifreq));
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
config.ifc_len = count * sizeof(struct ifreq);
|
config.ifc_len = count * sizeof(struct ifreq);
|
||||||
config.ifc_buf = buffer;
|
config.ifc_buf = buffer;
|
||||||
if (ioctl(fSocket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
|
if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifreq *interface = (ifreq *)buffer;
|
ifreq* interface = (ifreq*)buffer;
|
||||||
|
|
||||||
int32 oldStatus = fStatus;
|
int32 oldStatus = fStatus;
|
||||||
fStatus = kStatusUnknown;
|
fStatus = kStatusUnknown;
|
||||||
@@ -481,15 +510,15 @@ NetworkStatusView::_Update(bool force)
|
|||||||
void
|
void
|
||||||
NetworkStatusView::_OpenNetworksPreferences()
|
NetworkStatusView::_OpenNetworksPreferences()
|
||||||
{
|
{
|
||||||
status_t ret = be_roster->Launch("application/x-vnd.Haiku-Network");
|
status_t status = be_roster->Launch("application/x-vnd.Haiku-Network");
|
||||||
if (ret < B_OK) {
|
if (status < B_OK) {
|
||||||
BString errorMessage("Launching the Network preflet failed.\n\n"
|
BString errorMessage("Launching the Network preflet failed.\n\n"
|
||||||
"Error: ");
|
"Error: ");
|
||||||
errorMessage << strerror(ret);
|
errorMessage << strerror(status);
|
||||||
BAlert* alert = new BAlert("launch error", errorMessage.String(),
|
BAlert* alert = new BAlert("launch error", errorMessage.String(),
|
||||||
"Ok");
|
"Ok");
|
||||||
// asynchronous alert in order to not block replicant host
|
|
||||||
// application
|
// asynchronous alert in order to not block replicant host application
|
||||||
alert->Go(NULL);
|
alert->Go(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -56,12 +56,10 @@ class NetworkStatusView : public BView {
|
|||||||
void _Update(bool force = false);
|
void _Update(bool force = false);
|
||||||
void _OpenNetworksPreferences();
|
void _OpenNetworksPreferences();
|
||||||
|
|
||||||
BMessageRunner* fMessageRunner;
|
|
||||||
BObjectList<BString> fInterfaces;
|
BObjectList<BString> fInterfaces;
|
||||||
bool fInDeskbar;
|
bool fInDeskbar;
|
||||||
BBitmap* fBitmaps[kStatusCount];
|
BBitmap* fBitmaps[kStatusCount];
|
||||||
int32 fStatus;
|
int32 fStatus;
|
||||||
int fSocket;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETWORK_STATUS_VIEW_H
|
#endif // NETWORK_STATUS_VIEW_H
|
||||||
|
|||||||
Reference in New Issue
Block a user