Fix FreeBSD build.
[haiku.git] / src / preferences / network / InterfaceView.cpp
blob58ca818d0daf0f9421e80ff0a5d07967fbf28910
1 /*
2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, <axeld@pinc-software.de>
7 * Alexander von Gluck, kallisti5@unixzen.com
8 * John Scipione, jscipione@gmail.com
9 */
12 #include "InterfaceView.h"
14 #include <set>
16 #include <net/if_media.h>
18 #include <Button.h>
19 #include <Catalog.h>
20 #include <ControlLook.h>
21 #include <LayoutBuilder.h>
22 #include <NetworkAddress.h>
23 #include <NetworkDevice.h>
24 #include <StringForSize.h>
25 #include <StringView.h>
26 #include <TextControl.h>
28 #include "MediaTypes.h"
29 #include "WirelessNetworkMenuItem.h"
32 static const uint32 kMsgInterfaceToggle = 'onof';
33 static const uint32 kMsgInterfaceRenegotiate = 'redo';
34 static const uint32 kMsgJoinNetwork = 'join';
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "IntefaceView"
41 // #pragma mark - InterfaceView
44 InterfaceView::InterfaceView()
46 BGroupView(B_VERTICAL),
47 fPulseCount(0)
49 SetFlags(Flags() | B_PULSE_NEEDED);
51 // TODO: Small graph of throughput?
53 float minimumWidth = be_control_look->DefaultItemSpacing() * 16;
55 BStringView* statusLabel = new BStringView("status label",
56 B_TRANSLATE("Status:"));
57 statusLabel->SetAlignment(B_ALIGN_RIGHT);
58 fStatusField = new BStringView("status field", "");
59 fStatusField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET));
60 BStringView* macAddressLabel = new BStringView("mac address label",
61 B_TRANSLATE("MAC address:"));
62 macAddressLabel->SetAlignment(B_ALIGN_RIGHT);
63 fMacAddressField = new BStringView("mac address field", "");
64 fMacAddressField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET));
65 BStringView* linkSpeedLabel = new BStringView("link speed label",
66 B_TRANSLATE("Link speed:"));
67 linkSpeedLabel->SetAlignment(B_ALIGN_RIGHT);
68 fLinkSpeedField = new BStringView("link speed field", "");
69 fLinkSpeedField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET));
71 // TODO: These metrics may be better in a BScrollView?
72 BStringView* linkTxLabel = new BStringView("tx label",
73 B_TRANSLATE("Sent:"));
74 linkTxLabel->SetAlignment(B_ALIGN_RIGHT);
75 fLinkTxField = new BStringView("tx field", "");
76 fLinkTxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET));
77 BStringView* linkRxLabel = new BStringView("rx label",
78 B_TRANSLATE("Received:"));
79 linkRxLabel->SetAlignment(B_ALIGN_RIGHT);
80 fLinkRxField = new BStringView("rx field", "");
81 fLinkRxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET));
83 fNetworkMenuField = new BMenuField(B_TRANSLATE("Network:"), new BMenu(
84 B_TRANSLATE("Choose automatically")));
85 fNetworkMenuField->SetAlignment(B_ALIGN_RIGHT);
86 fNetworkMenuField->Menu()->SetLabelFromMarked(true);
88 // Construct the BButtons
89 fToggleButton = new BButton("onoff", B_TRANSLATE("Disable"),
90 new BMessage(kMsgInterfaceToggle));
92 fRenegotiateButton = new BButton("heal", B_TRANSLATE("Renegotiate"),
93 new BMessage(kMsgInterfaceRenegotiate));
94 fRenegotiateButton->SetEnabled(false);
96 BLayoutBuilder::Group<>(this)
97 .AddGrid()
98 .Add(statusLabel, 0, 0)
99 .Add(fStatusField, 1, 0)
100 .Add(fNetworkMenuField->CreateLabelLayoutItem(), 0, 1)
101 .Add(fNetworkMenuField->CreateMenuBarLayoutItem(), 1, 1)
102 .Add(macAddressLabel, 0, 2)
103 .Add(fMacAddressField, 1, 2)
104 .Add(linkSpeedLabel, 0, 3)
105 .Add(fLinkSpeedField, 1, 3)
106 .Add(linkTxLabel, 0, 4)
107 .Add(fLinkTxField, 1, 4)
108 .Add(linkRxLabel, 0, 5)
109 .Add(fLinkRxField, 1, 5)
110 .End()
111 .AddGlue()
112 .AddGroup(B_HORIZONTAL)
113 .AddGlue()
114 .Add(fToggleButton)
115 .Add(fRenegotiateButton)
116 .End();
120 InterfaceView::~InterfaceView()
125 void
126 InterfaceView::SetTo(const char* name)
128 fInterface.SetTo(name);
132 void
133 InterfaceView::AttachedToWindow()
135 _Update();
136 // Populate the fields
138 fToggleButton->SetTarget(this);
139 fRenegotiateButton->SetTarget(this);
143 void
144 InterfaceView::MessageReceived(BMessage* message)
146 switch (message->what) {
147 case kMsgJoinNetwork:
149 const char* name;
150 BNetworkAddress address;
151 if (message->FindString("name", &name) == B_OK
152 && message->FindFlat("address", &address) == B_OK) {
153 BNetworkDevice device(fInterface.Name());
154 status_t status = device.JoinNetwork(address);
155 if (status != B_OK) {
156 // This does not really matter, as it's stored this way,
157 // anyway.
159 // TODO: store value
161 break;
163 case kMsgInterfaceToggle:
165 // Disable/enable interface
166 uint32 flags = fInterface.Flags();
167 if ((flags & IFF_UP) != 0)
168 flags &= ~IFF_UP;
169 else
170 flags |= IFF_UP;
172 if (fInterface.SetFlags(flags) == B_OK)
173 _Update();
174 break;
177 case kMsgInterfaceRenegotiate:
179 // TODO: renegotiate addresses
180 break;
183 default:
184 BView::MessageReceived(message);
189 void
190 InterfaceView::Pulse()
192 // Update the wireless network menu every 5 seconds
193 _Update((fPulseCount++ % 5) == 0);
197 /*! Populate fields with current settings.
199 status_t
200 InterfaceView::_Update(bool updateWirelessNetworks)
202 BNetworkDevice device(fInterface.Name());
203 bool isWireless = device.IsWireless();
204 bool disabled = (fInterface.Flags() & IFF_UP) == 0;
206 if (fInterface.HasLink()) {
207 if (isWireless) {
208 // TODO!
209 BString network = "---";
210 network.Prepend(" (");
211 network.Prepend(B_TRANSLATE("connected"));
212 network.Append(")");
213 fStatusField->SetText(network.String());
214 } else {
215 fStatusField->SetText(B_TRANSLATE("connected"));
217 } else
218 fStatusField->SetText(B_TRANSLATE("disconnected"));
220 BNetworkAddress hardwareAddress;
221 if (device.GetHardwareAddress(hardwareAddress) == B_OK)
222 fMacAddressField->SetText(hardwareAddress.ToString());
223 else
224 fMacAddressField->SetText("-");
226 int media = fInterface.Media();
227 if ((media & IFM_ACTIVE) != 0)
228 fLinkSpeedField->SetText(media_type_to_string(media));
229 else
230 fLinkSpeedField->SetText("-");
232 // Update Link stats
233 ifreq_stats stats;
234 if (fInterface.GetStats(stats) == B_OK) {
235 char buffer[100];
237 string_for_size(stats.send.bytes, buffer, sizeof(buffer));
238 fLinkTxField->SetText(buffer);
240 string_for_size(stats.receive.bytes, buffer, sizeof(buffer));
241 fLinkRxField->SetText(buffer);
244 // TODO: move the wireless info to a separate tab. We should have a
245 // BListView of available networks, rather than a menu, to make them more
246 // readable and easier to browse and select.
247 if (fNetworkMenuField->IsHidden(fNetworkMenuField) && isWireless)
248 fNetworkMenuField->Show();
249 else if (!fNetworkMenuField->IsHidden(fNetworkMenuField) && !isWireless)
250 fNetworkMenuField->Hide();
252 if (isWireless && updateWirelessNetworks) {
253 // Rebuild network menu
254 BMenu* menu = fNetworkMenuField->Menu();
255 menu->RemoveItems(0, menu->CountItems(), true);
257 std::set<BNetworkAddress> associated;
258 BNetworkAddress address;
259 uint32 cookie = 0;
260 while (device.GetNextAssociatedNetwork(cookie, address) == B_OK)
261 associated.insert(address);
263 wireless_network network;
264 int32 count = 0;
265 cookie = 0;
266 while (device.GetNextNetwork(cookie, network) == B_OK) {
267 BMessage* message = new BMessage(kMsgJoinNetwork);
269 message->AddString("device", fInterface.Name());
270 message->AddString("name", network.name);
271 message->AddFlat("address", &network.address);
273 BMenuItem* item = new WirelessNetworkMenuItem(network.name,
274 network.signal_strength,
275 network.authentication_mode, message);
276 if (associated.find(network.address) != associated.end())
277 item->SetMarked(true);
278 menu->AddItem(item);
280 count++;
282 if (count == 0) {
283 BMenuItem* item = new BMenuItem(
284 B_TRANSLATE("<no wireless networks found>"), NULL);
285 item->SetEnabled(false);
286 menu->AddItem(item);
287 } else {
288 BMenuItem* item = new BMenuItem(
289 B_TRANSLATE("Choose automatically"), NULL);
290 if (menu->FindMarked() == NULL)
291 item->SetMarked(true);
292 menu->AddItem(item, 0);
293 menu->AddItem(new BSeparatorItem(), 1);
295 menu->SetTargetForItems(this);
298 //fRenegotiateButton->SetEnabled(!disabled);
299 fToggleButton->SetLabel(disabled ? "Enable" : "Disable");
301 return B_OK;