1f01106c3SAxel Dörfler /* 2f01106c3SAxel Dörfler * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. 3f01106c3SAxel Dörfler * Distributed under the terms of the MIT License. 4f01106c3SAxel Dörfler * 5f01106c3SAxel Dörfler * Authors: 6f01106c3SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 7f01106c3SAxel Dörfler * Hugo Santos, hugosantos@gmail.com 83b41ad86SStephan Aßmus * Dario Casalinuovo 9f01106c3SAxel Dörfler */ 10f01106c3SAxel Dörfler 11f01106c3SAxel Dörfler 12f01106c3SAxel Dörfler #include "NetworkStatusView.h" 13f01106c3SAxel Dörfler 14f01106c3SAxel Dörfler #include "NetworkStatus.h" 15f01106c3SAxel Dörfler #include "NetworkStatusIcons.h" 16f01106c3SAxel Dörfler 17f01106c3SAxel Dörfler #include <Alert.h> 18f01106c3SAxel Dörfler #include <Application.h> 19f01106c3SAxel Dörfler #include <Bitmap.h> 20f01106c3SAxel Dörfler #include <Deskbar.h> 21f01106c3SAxel Dörfler #include <Dragger.h> 22f01106c3SAxel Dörfler #include <Drivers.h> 23f01106c3SAxel Dörfler #include <IconUtils.h> 24f01106c3SAxel Dörfler #include <MenuItem.h> 25f01106c3SAxel Dörfler #include <MessageRunner.h> 26f01106c3SAxel Dörfler #include <PopUpMenu.h> 27f01106c3SAxel Dörfler #include <Resources.h> 28d5ba07a3SAxel Dörfler #include <Roster.h> 29f01106c3SAxel Dörfler #include <String.h> 30f01106c3SAxel Dörfler #include <TextView.h> 31f01106c3SAxel Dörfler 32f01106c3SAxel Dörfler #include <arpa/inet.h> 33f01106c3SAxel Dörfler #include <net/if.h> 34f01106c3SAxel Dörfler #include <stdio.h> 35f01106c3SAxel Dörfler #include <stdlib.h> 36f01106c3SAxel Dörfler #include <string.h> 37f01106c3SAxel Dörfler #include <sys/socket.h> 38f01106c3SAxel Dörfler #include <sys/sockio.h> 39f01106c3SAxel Dörfler #include <unistd.h> 40f01106c3SAxel Dörfler 41f01106c3SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_HAIKU 42f01106c3SAxel Dörfler // BONE compatibility 43f01106c3SAxel Dörfler # define IF_NAMESIZE IFNAMSIZ 44f01106c3SAxel Dörfler # define IFF_LINK 0 45f01106c3SAxel Dörfler # define IFF_CONFIGURING 0 46f01106c3SAxel Dörfler # define ifc_value ifc_val 47f01106c3SAxel Dörfler #endif 48f01106c3SAxel Dörfler 49f01106c3SAxel Dörfler static const char *kStatusDescriptions[] = { 50f01106c3SAxel Dörfler "Unknown", 51f01106c3SAxel Dörfler "No Link", 52f01106c3SAxel Dörfler "No stateful configuration", 53f01106c3SAxel Dörfler "Configuring", 54f01106c3SAxel Dörfler "Ready" 55f01106c3SAxel Dörfler }; 56f01106c3SAxel Dörfler 57f01106c3SAxel Dörfler extern "C" _EXPORT BView *instantiate_deskbar_item(void); 58f01106c3SAxel Dörfler 59f01106c3SAxel Dörfler 60f01106c3SAxel Dörfler const uint32 kMsgUpdate = 'updt'; 61f01106c3SAxel Dörfler const uint32 kMsgShowConfiguration = 'shcf'; 62c1502c9aSStephan Aßmus const uint32 kMsgOpenNetworkPreferences = 'onwp'; 63f01106c3SAxel Dörfler 64f01106c3SAxel Dörfler const uint32 kMinIconWidth = 16; 65f01106c3SAxel Dörfler const uint32 kMinIconHeight = 16; 66f01106c3SAxel Dörfler 67f01106c3SAxel Dörfler const bigtime_t kUpdateInterval = 1000000; 68f01106c3SAxel Dörfler // every second 69f01106c3SAxel Dörfler 70f01106c3SAxel Dörfler 71f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode, 72f01106c3SAxel Dörfler bool inDeskbar) 73f01106c3SAxel Dörfler : BView(frame, kDeskbarItemName, resizingMode, 74d5ba07a3SAxel Dörfler B_WILL_DRAW | B_FRAME_EVENTS), 75f01106c3SAxel Dörfler fInDeskbar(inDeskbar), 76f01106c3SAxel Dörfler fStatus(kStatusUnknown) 77f01106c3SAxel Dörfler { 78f01106c3SAxel Dörfler _Init(); 79f01106c3SAxel Dörfler 80f01106c3SAxel Dörfler if (!inDeskbar) { 81f01106c3SAxel Dörfler // we were obviously added to a standard window - let's add a dragger 82f01106c3SAxel Dörfler frame.OffsetTo(B_ORIGIN); 83f01106c3SAxel Dörfler frame.top = frame.bottom - 7; 84f01106c3SAxel Dörfler frame.left = frame.right - 7; 85f01106c3SAxel Dörfler BDragger* dragger = new BDragger(frame, this, 86f01106c3SAxel Dörfler B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 87f01106c3SAxel Dörfler AddChild(dragger); 88f01106c3SAxel Dörfler } else 89f01106c3SAxel Dörfler _Update(); 90f01106c3SAxel Dörfler } 91f01106c3SAxel Dörfler 92f01106c3SAxel Dörfler 93f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BMessage* archive) 94d5ba07a3SAxel Dörfler : BView(archive), 95d5ba07a3SAxel Dörfler fInDeskbar(false) 96f01106c3SAxel Dörfler { 97d5ba07a3SAxel Dörfler app_info info; 98d5ba07a3SAxel Dörfler if (be_app->GetAppInfo(&info) == B_OK 99d5ba07a3SAxel Dörfler && !strcasecmp(info.signature, "application/x-vnd.Be-TSKB")) 100d5ba07a3SAxel Dörfler fInDeskbar = true; 101d5ba07a3SAxel Dörfler 102f01106c3SAxel Dörfler _Init(); 103f01106c3SAxel Dörfler } 104f01106c3SAxel Dörfler 105f01106c3SAxel Dörfler 106f01106c3SAxel Dörfler NetworkStatusView::~NetworkStatusView() 107f01106c3SAxel Dörfler { 108f01106c3SAxel Dörfler } 109f01106c3SAxel Dörfler 110f01106c3SAxel Dörfler 111f01106c3SAxel Dörfler void 112f01106c3SAxel Dörfler NetworkStatusView::_Init() 113f01106c3SAxel Dörfler { 114f01106c3SAxel Dörfler fMessageRunner = NULL; 115f01106c3SAxel Dörfler 116f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 117f01106c3SAxel Dörfler fBitmaps[i] = NULL; 118f01106c3SAxel Dörfler } 119f01106c3SAxel Dörfler 120f01106c3SAxel Dörfler _UpdateBitmaps(); 121f01106c3SAxel Dörfler } 122f01106c3SAxel Dörfler 123f01106c3SAxel Dörfler 124f01106c3SAxel Dörfler void 125f01106c3SAxel Dörfler NetworkStatusView::_UpdateBitmaps() 126f01106c3SAxel Dörfler { 127f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 128f01106c3SAxel Dörfler delete fBitmaps[i]; 129f01106c3SAxel Dörfler fBitmaps[i] = NULL; 130f01106c3SAxel Dörfler } 131f01106c3SAxel Dörfler 132f01106c3SAxel Dörfler image_info info; 133f01106c3SAxel Dörfler if (our_image(info) != B_OK) 134f01106c3SAxel Dörfler return; 135f01106c3SAxel Dörfler 136f01106c3SAxel Dörfler BFile file(info.name, B_READ_ONLY); 137f01106c3SAxel Dörfler if (file.InitCheck() < B_OK) 138f01106c3SAxel Dörfler return; 139f01106c3SAxel Dörfler 140f01106c3SAxel Dörfler BResources resources(&file); 141f01106c3SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_HAIKU 142f01106c3SAxel Dörfler if (resources.InitCheck() < B_OK) 143f01106c3SAxel Dörfler return; 144f01106c3SAxel Dörfler #endif 145f01106c3SAxel Dörfler 146f01106c3SAxel Dörfler for (int i = 0; i < kStatusCount; i++) { 147f01106c3SAxel Dörfler const void* data = NULL; 148f01106c3SAxel Dörfler size_t size; 149f01106c3SAxel Dörfler data = resources.LoadResource(B_VECTOR_ICON_TYPE, 150f01106c3SAxel Dörfler kNetworkStatusNoDevice + i, &size); 151f01106c3SAxel Dörfler if (data != NULL) { 1524c28a737SStephan Aßmus BBitmap* icon = new BBitmap(Bounds(), B_RGBA32); 153f01106c3SAxel Dörfler if (icon->InitCheck() == B_OK 154f01106c3SAxel Dörfler && BIconUtils::GetVectorIcon((const uint8 *)data, 155f01106c3SAxel Dörfler size, icon) == B_OK) { 156f01106c3SAxel Dörfler fBitmaps[i] = icon; 157f01106c3SAxel Dörfler } else 158f01106c3SAxel Dörfler delete icon; 159f01106c3SAxel Dörfler } 160f01106c3SAxel Dörfler } 161f01106c3SAxel Dörfler } 162f01106c3SAxel Dörfler 163f01106c3SAxel Dörfler 164f01106c3SAxel Dörfler void 165f01106c3SAxel Dörfler NetworkStatusView::_Quit() 166f01106c3SAxel Dörfler { 167f01106c3SAxel Dörfler if (fInDeskbar) { 168f01106c3SAxel Dörfler BDeskbar deskbar; 169f01106c3SAxel Dörfler deskbar.RemoveItem(kDeskbarItemName); 170f01106c3SAxel Dörfler } else 171f01106c3SAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 172f01106c3SAxel Dörfler } 173f01106c3SAxel Dörfler 174f01106c3SAxel Dörfler 175f01106c3SAxel Dörfler NetworkStatusView * 176f01106c3SAxel Dörfler NetworkStatusView::Instantiate(BMessage* archive) 177f01106c3SAxel Dörfler { 178f01106c3SAxel Dörfler if (!validate_instantiation(archive, "NetworkStatusView")) 179f01106c3SAxel Dörfler return NULL; 180f01106c3SAxel Dörfler 181f01106c3SAxel Dörfler return new NetworkStatusView(archive); 182f01106c3SAxel Dörfler } 183f01106c3SAxel Dörfler 184f01106c3SAxel Dörfler 185f01106c3SAxel Dörfler status_t 186f01106c3SAxel Dörfler NetworkStatusView::Archive(BMessage* archive, bool deep) const 187f01106c3SAxel Dörfler { 188f01106c3SAxel Dörfler status_t status = BView::Archive(archive, deep); 189f01106c3SAxel Dörfler if (status == B_OK) 190f01106c3SAxel Dörfler status = archive->AddString("add_on", kSignature); 191f01106c3SAxel Dörfler if (status == B_OK) 192f01106c3SAxel Dörfler status = archive->AddString("class", "NetworkStatusView"); 193f01106c3SAxel Dörfler 194f01106c3SAxel Dörfler return status; 195f01106c3SAxel Dörfler } 196f01106c3SAxel Dörfler 197f01106c3SAxel Dörfler 198f01106c3SAxel Dörfler void 199f01106c3SAxel Dörfler NetworkStatusView::AttachedToWindow() 200f01106c3SAxel Dörfler { 201f01106c3SAxel Dörfler BView::AttachedToWindow(); 202f01106c3SAxel Dörfler if (Parent()) 203f01106c3SAxel Dörfler SetViewColor(Parent()->ViewColor()); 204f01106c3SAxel Dörfler else 205f01106c3SAxel Dörfler SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 206f01106c3SAxel Dörfler 207f01106c3SAxel Dörfler SetLowColor(ViewColor()); 208f01106c3SAxel Dörfler 209f01106c3SAxel Dörfler BMessage update(kMsgUpdate); 210f01106c3SAxel Dörfler fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval); 211f01106c3SAxel Dörfler 212f01106c3SAxel Dörfler fSocket = socket(AF_INET, SOCK_DGRAM, 0); 213f01106c3SAxel Dörfler _Update(); 214f01106c3SAxel Dörfler } 215f01106c3SAxel Dörfler 216f01106c3SAxel Dörfler 217f01106c3SAxel Dörfler void 218f01106c3SAxel Dörfler NetworkStatusView::DetachedFromWindow() 219f01106c3SAxel Dörfler { 220f01106c3SAxel Dörfler delete fMessageRunner; 221f01106c3SAxel Dörfler close(fSocket); 222f01106c3SAxel Dörfler } 223f01106c3SAxel Dörfler 224f01106c3SAxel Dörfler 225f01106c3SAxel Dörfler void 226f01106c3SAxel Dörfler NetworkStatusView::MessageReceived(BMessage* message) 227f01106c3SAxel Dörfler { 228f01106c3SAxel Dörfler switch (message->what) { 229f01106c3SAxel Dörfler case kMsgUpdate: 230f01106c3SAxel Dörfler _Update(); 231f01106c3SAxel Dörfler break; 232f01106c3SAxel Dörfler 233f01106c3SAxel Dörfler case kMsgShowConfiguration: 234f01106c3SAxel Dörfler _ShowConfiguration(message); 235f01106c3SAxel Dörfler break; 236f01106c3SAxel Dörfler 237c1502c9aSStephan Aßmus case kMsgOpenNetworkPreferences: 2383b41ad86SStephan Aßmus _OpenNetworksPreferences(); 2393b41ad86SStephan Aßmus break; 2403b41ad86SStephan Aßmus 241f01106c3SAxel Dörfler case B_ABOUT_REQUESTED: 242f01106c3SAxel Dörfler _AboutRequested(); 243f01106c3SAxel Dörfler break; 244f01106c3SAxel Dörfler 245f01106c3SAxel Dörfler case B_QUIT_REQUESTED: 246f01106c3SAxel Dörfler _Quit(); 247f01106c3SAxel Dörfler break; 248f01106c3SAxel Dörfler 249f01106c3SAxel Dörfler default: 250f01106c3SAxel Dörfler BView::MessageReceived(message); 251f01106c3SAxel Dörfler } 252f01106c3SAxel Dörfler } 253f01106c3SAxel Dörfler 254f01106c3SAxel Dörfler 255f01106c3SAxel Dörfler void 256f01106c3SAxel Dörfler NetworkStatusView::FrameResized(float width, float height) 257f01106c3SAxel Dörfler { 258f01106c3SAxel Dörfler _UpdateBitmaps(); 259d5ba07a3SAxel Dörfler Invalidate(); 260f01106c3SAxel Dörfler } 261f01106c3SAxel Dörfler 262f01106c3SAxel Dörfler 263f01106c3SAxel Dörfler void 264f01106c3SAxel Dörfler NetworkStatusView::Draw(BRect updateRect) 265f01106c3SAxel Dörfler { 266f01106c3SAxel Dörfler if (fBitmaps[fStatus] == NULL) 267f01106c3SAxel Dörfler return; 268f01106c3SAxel Dörfler 269f01106c3SAxel Dörfler SetDrawingMode(B_OP_ALPHA); 270f01106c3SAxel Dörfler DrawBitmap(fBitmaps[fStatus]); 271f01106c3SAxel Dörfler SetDrawingMode(B_OP_COPY); 272f01106c3SAxel Dörfler } 273f01106c3SAxel Dörfler 274f01106c3SAxel Dörfler 275f01106c3SAxel Dörfler void 276f01106c3SAxel Dörfler NetworkStatusView::_ShowConfiguration(BMessage* message) 277f01106c3SAxel Dörfler { 278f01106c3SAxel Dörfler static const struct information_entry { 279f01106c3SAxel Dörfler const char *label; 280f01106c3SAxel Dörfler int32 control; 281f01106c3SAxel Dörfler } kInformationEntries[] = { 282f01106c3SAxel Dörfler { "Address", SIOCGIFADDR }, 283f01106c3SAxel Dörfler { "Broadcast", SIOCGIFBRDADDR }, 284f01106c3SAxel Dörfler { "Netmask", SIOCGIFNETMASK }, 285f01106c3SAxel Dörfler { NULL } 286f01106c3SAxel Dörfler }; 287f01106c3SAxel Dörfler 288f01106c3SAxel Dörfler const char *name; 289f01106c3SAxel Dörfler if (message->FindString("interface", &name) != B_OK) 290f01106c3SAxel Dörfler return; 291f01106c3SAxel Dörfler 292f01106c3SAxel Dörfler ifreq request; 293f01106c3SAxel Dörfler if (!_PrepareRequest(request, name)) 294f01106c3SAxel Dörfler return; 295f01106c3SAxel Dörfler 296f01106c3SAxel Dörfler BString text = name; 297f01106c3SAxel Dörfler text += " information:\n"; 298f01106c3SAxel Dörfler size_t boldLength = text.Length(); 299f01106c3SAxel Dörfler 300f01106c3SAxel Dörfler for (int i = 0; kInformationEntries[i].label; i++) { 301f01106c3SAxel Dörfler if (ioctl(fSocket, kInformationEntries[i].control, &request, 302f01106c3SAxel Dörfler sizeof(request)) < 0) { 303f01106c3SAxel Dörfler continue; 304f01106c3SAxel Dörfler } 305f01106c3SAxel Dörfler 306f01106c3SAxel Dörfler char address[32]; 307f01106c3SAxel Dörfler sockaddr_in* inetAddress = NULL; 308f01106c3SAxel Dörfler switch (kInformationEntries[i].control) { 309f01106c3SAxel Dörfler case SIOCGIFNETMASK: 310f01106c3SAxel Dörfler inetAddress = (sockaddr_in*)&request.ifr_mask; 311f01106c3SAxel Dörfler break; 312f01106c3SAxel Dörfler default: 313f01106c3SAxel Dörfler inetAddress = (sockaddr_in*)&request.ifr_addr; 314f01106c3SAxel Dörfler break; 315f01106c3SAxel Dörfler } 316f01106c3SAxel Dörfler 317f01106c3SAxel Dörfler if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, 318f01106c3SAxel Dörfler sizeof(address)) == NULL) { 319f01106c3SAxel Dörfler return; 320f01106c3SAxel Dörfler } 321f01106c3SAxel Dörfler 322f01106c3SAxel Dörfler text += "\n"; 323f01106c3SAxel Dörfler text += kInformationEntries[i].label; 324f01106c3SAxel Dörfler text += ": "; 325f01106c3SAxel Dörfler text += address; 326f01106c3SAxel Dörfler } 327f01106c3SAxel Dörfler 328f01106c3SAxel Dörfler BAlert* alert = new BAlert(name, text.String(), "Ok"); 329f01106c3SAxel Dörfler BTextView* view = alert->TextView(); 330f01106c3SAxel Dörfler BFont font; 331f01106c3SAxel Dörfler 332f01106c3SAxel Dörfler view->SetStylable(true); 333f01106c3SAxel Dörfler view->GetFont(&font); 334f01106c3SAxel Dörfler font.SetFace(B_BOLD_FACE); 335f01106c3SAxel Dörfler view->SetFontAndColor(0, boldLength, &font); 336f01106c3SAxel Dörfler 337f01106c3SAxel Dörfler alert->Go(NULL); 338f01106c3SAxel Dörfler } 339f01106c3SAxel Dörfler 340f01106c3SAxel Dörfler 341f01106c3SAxel Dörfler void 342f01106c3SAxel Dörfler NetworkStatusView::MouseDown(BPoint point) 343f01106c3SAxel Dörfler { 344f01106c3SAxel Dörfler BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false); 345*a31688d2SAxel Dörfler menu->SetAsyncAutoDestruct(true); 346f01106c3SAxel Dörfler menu->SetFont(be_plain_font); 347f01106c3SAxel Dörfler 348f01106c3SAxel Dörfler for (int32 i = 0; i < fInterfaces.CountItems(); i++) { 349f01106c3SAxel Dörfler BString& name = *fInterfaces.ItemAt(i); 350f01106c3SAxel Dörfler 351f01106c3SAxel Dörfler BString label = name; 352f01106c3SAxel Dörfler label += ": "; 353f01106c3SAxel Dörfler label += kStatusDescriptions[ 354f01106c3SAxel Dörfler _DetermineInterfaceStatus(name.String())]; 355f01106c3SAxel Dörfler 356f01106c3SAxel Dörfler BMessage* info = new BMessage(kMsgShowConfiguration); 357f01106c3SAxel Dörfler info->AddString("interface", name.String()); 358f01106c3SAxel Dörfler menu->AddItem(new BMenuItem(label.String(), info)); 359f01106c3SAxel Dörfler } 360f01106c3SAxel Dörfler 361f01106c3SAxel Dörfler menu->AddSeparatorItem(); 362*a31688d2SAxel Dörfler //menu->AddItem(new BMenuItem("About NetworkStatus" B_UTF8_ELLIPSIS, 363*a31688d2SAxel Dörfler // new BMessage(B_ABOUT_REQUESTED))); 3643b41ad86SStephan Aßmus menu->AddItem(new BMenuItem("Open Networks Preferences" B_UTF8_ELLIPSIS, 365c1502c9aSStephan Aßmus new BMessage(kMsgOpenNetworkPreferences))); 3663b41ad86SStephan Aßmus 367f01106c3SAxel Dörfler if (fInDeskbar) 368f01106c3SAxel Dörfler menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED))); 369f01106c3SAxel Dörfler menu->SetTargetForItems(this); 370f01106c3SAxel Dörfler 371f01106c3SAxel Dörfler ConvertToScreen(&point); 372*a31688d2SAxel Dörfler menu->Go(point, true, true, true); 373f01106c3SAxel Dörfler } 374f01106c3SAxel Dörfler 375f01106c3SAxel Dörfler 376f01106c3SAxel Dörfler void 377f01106c3SAxel Dörfler NetworkStatusView::_AboutRequested() 378f01106c3SAxel Dörfler { 379f01106c3SAxel Dörfler BAlert *alert = new BAlert("about", "NetworkStatus\n" 380f01106c3SAxel Dörfler "\twritten by Axel Dörfler and Hugo Santos\n" 381f01106c3SAxel Dörfler "\tCopyright 2007, Haiku, Inc.\n", "Ok"); 382f01106c3SAxel Dörfler BTextView *view = alert->TextView(); 383f01106c3SAxel Dörfler BFont font; 384f01106c3SAxel Dörfler 385f01106c3SAxel Dörfler view->SetStylable(true); 386f01106c3SAxel Dörfler 387f01106c3SAxel Dörfler view->GetFont(&font); 388f01106c3SAxel Dörfler font.SetSize(18); 389f01106c3SAxel Dörfler font.SetFace(B_BOLD_FACE); 390f01106c3SAxel Dörfler view->SetFontAndColor(0, 13, &font); 391f01106c3SAxel Dörfler 392f01106c3SAxel Dörfler alert->Go(); 393f01106c3SAxel Dörfler } 394f01106c3SAxel Dörfler 395f01106c3SAxel Dörfler 396f01106c3SAxel Dörfler bool 397f01106c3SAxel Dörfler NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name) 398f01106c3SAxel Dörfler { 399f01106c3SAxel Dörfler if (strlen(name) > IF_NAMESIZE) 400f01106c3SAxel Dörfler return false; 401f01106c3SAxel Dörfler 402f01106c3SAxel Dörfler strcpy(request.ifr_name, name); 403f01106c3SAxel Dörfler return true; 404f01106c3SAxel Dörfler } 405f01106c3SAxel Dörfler 406f01106c3SAxel Dörfler 407f01106c3SAxel Dörfler int32 408f01106c3SAxel Dörfler NetworkStatusView::_DetermineInterfaceStatus(const char* name) 409f01106c3SAxel Dörfler { 410f01106c3SAxel Dörfler ifreq request; 411f01106c3SAxel Dörfler if (!_PrepareRequest(request, name)) 412f01106c3SAxel Dörfler return kStatusUnknown; 413f01106c3SAxel Dörfler 414f01106c3SAxel Dörfler uint32 flags = 0; 415f01106c3SAxel Dörfler if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0) 416f01106c3SAxel Dörfler flags = request.ifr_flags; 417f01106c3SAxel Dörfler 418f01106c3SAxel Dörfler int32 status = kStatusNoLink; 419f01106c3SAxel Dörfler 420f01106c3SAxel Dörfler // TODO: no kStatusLinkNoConfig yet 421f01106c3SAxel Dörfler 422f01106c3SAxel Dörfler if (flags & IFF_CONFIGURING) 423f01106c3SAxel Dörfler status = kStatusConnecting; 4242a17be44SAxel Dörfler else if ((flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK)) 425f01106c3SAxel Dörfler status = kStatusReady; 426f01106c3SAxel Dörfler 427f01106c3SAxel Dörfler return status; 428f01106c3SAxel Dörfler } 429f01106c3SAxel Dörfler 430f01106c3SAxel Dörfler 431f01106c3SAxel Dörfler void 432f01106c3SAxel Dörfler NetworkStatusView::_Update(bool force) 433f01106c3SAxel Dörfler { 434f01106c3SAxel Dörfler // iterate over all interfaces and retrieve minimal status 435f01106c3SAxel Dörfler 436f01106c3SAxel Dörfler ifconf config; 437f01106c3SAxel Dörfler config.ifc_len = sizeof(config.ifc_value); 438f01106c3SAxel Dörfler if (ioctl(fSocket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 439f01106c3SAxel Dörfler return; 440f01106c3SAxel Dörfler 441f01106c3SAxel Dörfler uint32 count = (uint32)config.ifc_value; 442f01106c3SAxel Dörfler if (count == 0) 443f01106c3SAxel Dörfler return; 444f01106c3SAxel Dörfler 445f01106c3SAxel Dörfler void *buffer = malloc(count * sizeof(struct ifreq)); 446f01106c3SAxel Dörfler if (buffer == NULL) 447f01106c3SAxel Dörfler return; 448f01106c3SAxel Dörfler 449f01106c3SAxel Dörfler config.ifc_len = count * sizeof(struct ifreq); 450f01106c3SAxel Dörfler config.ifc_buf = buffer; 45153bc7943SStephan Aßmus if (ioctl(fSocket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { 45253bc7943SStephan Aßmus free(buffer); 453f01106c3SAxel Dörfler return; 45453bc7943SStephan Aßmus } 455f01106c3SAxel Dörfler 456f01106c3SAxel Dörfler ifreq *interface = (ifreq *)buffer; 457f01106c3SAxel Dörfler 458f01106c3SAxel Dörfler int32 oldStatus = fStatus; 459f01106c3SAxel Dörfler fStatus = kStatusUnknown; 460f01106c3SAxel Dörfler fInterfaces.MakeEmpty(); 461f01106c3SAxel Dörfler 462f01106c3SAxel Dörfler for (uint32 i = 0; i < count; i++) { 463f01106c3SAxel Dörfler if (strncmp(interface->ifr_name, "loop", 4) && interface->ifr_name[0]) { 464f01106c3SAxel Dörfler fInterfaces.AddItem(new BString(interface->ifr_name)); 465f01106c3SAxel Dörfler int32 status = _DetermineInterfaceStatus(interface->ifr_name); 466f01106c3SAxel Dörfler if (status > fStatus) 467f01106c3SAxel Dörfler fStatus = status; 468f01106c3SAxel Dörfler } 469f01106c3SAxel Dörfler 470f01106c3SAxel Dörfler interface = (ifreq *)((addr_t)interface + IF_NAMESIZE 471f01106c3SAxel Dörfler + interface->ifr_addr.sa_len); 472f01106c3SAxel Dörfler } 473f01106c3SAxel Dörfler 474f01106c3SAxel Dörfler free(buffer); 475f01106c3SAxel Dörfler 476f01106c3SAxel Dörfler if (fStatus != oldStatus) 477f01106c3SAxel Dörfler Invalidate(); 478f01106c3SAxel Dörfler } 479f01106c3SAxel Dörfler 480f01106c3SAxel Dörfler 4813b41ad86SStephan Aßmus void 4823b41ad86SStephan Aßmus NetworkStatusView::_OpenNetworksPreferences() 4833b41ad86SStephan Aßmus { 4843b41ad86SStephan Aßmus status_t ret = be_roster->Launch("application/x-vnd.Haiku-Network"); 4853b41ad86SStephan Aßmus if (ret < B_OK) { 4863b41ad86SStephan Aßmus BString errorMessage("Launching the Network preflet failed.\n\n" 4873b41ad86SStephan Aßmus "Error: "); 4883b41ad86SStephan Aßmus errorMessage << strerror(ret); 4893b41ad86SStephan Aßmus BAlert* alert = new BAlert("launch error", errorMessage.String(), 4903b41ad86SStephan Aßmus "Ok"); 4913b41ad86SStephan Aßmus // asynchronous alert in order to not block replicant host 4923b41ad86SStephan Aßmus // application 4933b41ad86SStephan Aßmus alert->Go(NULL); 4943b41ad86SStephan Aßmus } 4953b41ad86SStephan Aßmus } 4963b41ad86SStephan Aßmus 4973b41ad86SStephan Aßmus 498f01106c3SAxel Dörfler // #pragma mark - 499f01106c3SAxel Dörfler 500f01106c3SAxel Dörfler 501f01106c3SAxel Dörfler extern "C" _EXPORT BView * 502f01106c3SAxel Dörfler instantiate_deskbar_item(void) 503f01106c3SAxel Dörfler { 50466eba86fSAxel Dörfler return new NetworkStatusView(BRect(0, 0, 15, 15), 50566eba86fSAxel Dörfler B_FOLLOW_LEFT | B_FOLLOW_TOP, true); 506f01106c3SAxel Dörfler } 507f01106c3SAxel Dörfler 508