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