2 * Copyright 2003-2004 Waldemar Kornewald. All rights reserved.
3 * Copyright 2017 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
7 //-----------------------------------------------------------------------
8 // PPPoEAddon saves the loaded settings.
9 // PPPoEView saves the current settings.
10 //-----------------------------------------------------------------------
12 #include "PPPoEAddon.h"
14 #include "InterfaceUtils.h"
15 #include "MessageDriverSettingsUtils.h"
16 #include "TextRequestDialog.h"
19 #include <MenuField.h>
21 #include <PopUpMenu.h>
22 #include <StringView.h>
24 #include <PPPManager.h>
30 static const uint32 kDefaultButtonWidth
= 80;
33 static const uint32 kMsgSelectInterface
= 'SELI';
34 static const uint32 kMsgSelectOther
= 'SELO';
35 static const uint32 kMsgFinishSelectOther
= 'FISO';
36 static const uint32 kMsgShowServiceWindow
= 'SHSW';
37 static const uint32 kMsgChangeService
= 'CHGS';
38 static const uint32 kMsgResetService
= 'RESS';
41 static const char *kLabelInterfaceName
= "Network Interface: ";
42 static const char *kLabelOptional
= "(Optional)";
43 static const char *kLabelOtherInterface
= "Other:";
44 static const char *kLabelSelectInterface
= "Select Interface...";
45 static const char *kLabelServiceName
= "Service: ";
48 static const char *kRequestInterfaceName
= "Network Interface Name: ";
50 // add-on descriptions
51 static const char *kFriendlyName
= "Broadband: DSL, Cable, etc.";
52 static const char *kTechnicalName
= "PPPoE";
53 static const char *kKernelModuleName
= "pppoe";
56 PPPoEAddon::PPPoEAddon(BMessage
*addons
)
57 : DialUpAddon(addons
),
62 fHeight
= 20 // interface name control
63 + 20 // service control
64 + 5 + 2; // space between controls and bottom
68 PPPoEAddon::~PPPoEAddon()
71 // this may have been set to NULL from the view's destructor!
76 PPPoEAddon::FriendlyName() const
83 PPPoEAddon::TechnicalName() const
85 return kTechnicalName
;
90 PPPoEAddon::KernelModuleName() const
92 return kKernelModuleName
;
97 PPPoEAddon::LoadSettings(BMessage
*settings
, BMessage
*profile
, bool isNew
)
100 fInterfaceName
= fServiceName
= "";
101 fSettings
= settings
;
105 fPPPoEView
->Reload();
107 if(!settings
|| !profile
|| isNew
)
111 int32 deviceIndex
= 0;
112 if(!FindMessageParameter(PPP_DEVICE_KEY
, *fSettings
, &device
, &deviceIndex
))
117 if(device
.FindString(MDSU_VALUES
, &name
) != B_OK
|| name
!= kKernelModuleName
)
123 if(!FindMessageParameter(PPPoE_INTERFACE_KEY
, device
, ¶meter
, &index
)
124 || parameter
.FindString(MDSU_VALUES
, &fInterfaceName
) != B_OK
)
126 // error: no interface
128 parameter
.AddBool(MDSU_VALID
, true);
129 device
.ReplaceMessage(MDSU_PARAMETERS
, index
, ¶meter
);
133 if(!FindMessageParameter(PPPoE_SERVICE_NAME_KEY
, device
, ¶meter
, &index
)
134 || parameter
.FindString(MDSU_VALUES
, &fServiceName
) != B_OK
)
137 parameter
.AddBool(MDSU_VALID
, true);
138 device
.ReplaceMessage(MDSU_PARAMETERS
, index
, ¶meter
);
141 device
.AddBool(MDSU_VALID
, true);
142 fSettings
->ReplaceMessage(MDSU_PARAMETERS
, deviceIndex
, &device
);
145 fPPPoEView
->Reload();
152 PPPoEAddon::IsModified(bool *settings
, bool *profile
) const
161 *settings
= (fInterfaceName
!= fPPPoEView
->InterfaceName()
162 || fServiceName
!= fPPPoEView
->ServiceName());
167 PPPoEAddon::SaveSettings(BMessage
*settings
, BMessage
*profile
, bool saveTemporary
)
169 if(!fSettings
|| !settings
|| !fPPPoEView
->InterfaceName()
170 || strlen(fPPPoEView
->InterfaceName()) == 0)
172 // TODO: tell user that an interface is needed (if we fail because of this)
174 BMessage device
, interface
;
175 device
.AddString(MDSU_NAME
, PPP_DEVICE_KEY
);
176 device
.AddString(MDSU_VALUES
, kKernelModuleName
);
178 interface
.AddString(MDSU_NAME
, PPPoE_INTERFACE_KEY
);
179 interface
.AddString(MDSU_VALUES
, fPPPoEView
->InterfaceName());
180 device
.AddMessage(MDSU_PARAMETERS
, &interface
);
182 if(fPPPoEView
->ServiceName() && strlen(fPPPoEView
->ServiceName()) > 0) {
183 // save service name, too
185 service
.AddString(MDSU_NAME
, PPPoE_SERVICE_NAME_KEY
);
186 service
.AddString(MDSU_VALUES
, fPPPoEView
->ServiceName());
187 device
.AddMessage(MDSU_PARAMETERS
, &service
);
190 settings
->AddMessage(MDSU_PARAMETERS
, &device
);
197 PPPoEAddon::GetPreferredSize(float *width
, float *height
) const
200 if(Addons()->FindFloat(DUN_DEVICE_VIEW_WIDTH
, &viewWidth
) != B_OK
)
214 PPPoEAddon::CreateView()
218 if(!Addons()->FindFloat(DUN_DEVICE_VIEW_WIDTH
, &width
))
222 BRect
rect(0, 0, width
, fHeight
);
223 fPPPoEView
= new PPPoEView(this, rect
);
224 fPPPoEView
->Reload();
231 PPPoEView::PPPoEView(PPPoEAddon
*addon
, BRect frame
)
232 : BView(frame
, "PPPoEView", B_FOLLOW_NONE
, 0),
235 BRect rect
= Bounds();
238 fInterface
= new BMenuField(rect
, "interface", kLabelInterfaceName
,
239 new BPopUpMenu(kLabelSelectInterface
));
240 fInterface
->SetDivider(StringWidth(fInterface
->Label()) + 5);
241 fInterface
->Menu()->AddSeparatorItem();
242 fOtherInterface
= new BMenuItem(kLabelOtherInterface
,
243 new BMessage(kMsgSelectOther
));
244 fInterface
->Menu()->AddItem(fOtherInterface
);
245 rect
.top
= rect
.bottom
+ 5;
246 rect
.bottom
= rect
.top
+ 20;
248 fServiceName
= new BTextControl(rect
, "service", kLabelServiceName
, NULL
, NULL
);
249 fServiceName
->SetDivider(StringWidth(fServiceName
->Label()) + 5);
250 rect
.left
= rect
.right
+ 5;
252 rect
.bottom
= rect
.top
+ 15;
253 AddChild(new BStringView(rect
, "optional", kLabelOptional
));
255 AddChild(fInterface
);
256 AddChild(fServiceName
);
260 PPPoEView::~PPPoEView()
262 Addon()->UnregisterView();
270 fServiceName
->SetText(Addon()->ServiceName());
275 PPPoEView::AttachedToWindow()
277 SetViewColor(Parent()->ViewColor());
278 fInterface
->Menu()->SetTargetForItems(this);
279 fServiceName
->SetTarget(this);
284 PPPoEView::MessageReceived(BMessage
*message
)
286 switch(message
->what
) {
287 case kMsgSelectInterface
: {
288 BMenuItem
*item
= fInterface
->Menu()->FindMarked();
290 fInterfaceName
= item
->Label();
293 case kMsgSelectOther
:
294 (new TextRequestDialog("InterfaceName", NULL
, kRequestInterfaceName
,
295 fInterfaceName
.String()))->Go(new BInvoker(
296 new BMessage(kMsgFinishSelectOther
), this));
299 case kMsgFinishSelectOther
: {
301 message
->FindInt32("which", &which
);
303 const char *name
= message
->FindString("text");
304 BMenu
*menu
= fInterface
->Menu();
306 if(which
!= 1 || !name
|| strlen(name
) == 0) {
307 item
= menu
->FindItem(fInterfaceName
.String());
308 if(item
&& menu
->IndexOf(item
) <= menu
->CountItems() - 2)
309 item
->SetMarked(true);
311 fOtherInterface
->SetMarked(true);
316 fInterfaceName
= name
;
318 item
= menu
->FindItem(fInterfaceName
.String());
319 if(item
&& menu
->IndexOf(item
) <= menu
->CountItems() - 2) {
320 item
->SetMarked(true);
324 BString
label(kLabelOtherInterface
);
325 label
<< " " << name
;
326 fOtherInterface
->SetLabel(label
.String());
327 fOtherInterface
->SetMarked(true);
328 // XXX: this is needed to tell the owning menu to update its label
332 BView::MessageReceived(message
);
338 PPPoEView::ReloadInterfaces()
340 // delete all items and request a new bunch from the pppoe kernel module
341 BMenu
*menu
= fInterface
->Menu();
342 while(menu
->CountItems() > 2)
343 delete menu
->RemoveItem((int32
) 0);
344 fOtherInterface
->SetLabel(kLabelOtherInterface
);
347 char *interfaces
= new char[8192];
348 // reserve enough space for approximately 512 entries
349 int32 count
= manager
.ControlModule("pppoe", PPPoE_GET_INTERFACES
, interfaces
,
353 char *name
= interfaces
;
355 for(int32 index
= 0; index
< count
; index
++) {
356 item
= new BMenuItem(name
, new BMessage(kMsgSelectInterface
));
357 insertAt
= FindNextMenuInsertionIndex(menu
, name
);
358 if(insertAt
> menu
->CountItems() - 2)
359 insertAt
= menu
->CountItems() - 2;
361 item
->SetTarget(this);
362 menu
->AddItem(item
, insertAt
);
363 name
+= strlen(name
) + 1;
366 // set interface or some default value if nothing was found
367 if(Addon()->InterfaceName() && strlen(Addon()->InterfaceName()) > 0)
368 fInterfaceName
= Addon()->InterfaceName();
370 fInterfaceName
= interfaces
;
376 item
= menu
->FindItem(fInterfaceName
.String());
377 if(item
&& menu
->IndexOf(item
) <= menu
->CountItems() - 2)
378 item
->SetMarked(true);
379 else if(Addon()->InterfaceName()) {
380 BString
label(kLabelOtherInterface
);
381 label
<< " " << fInterfaceName
;
382 fOtherInterface
->SetLabel(label
.String());
383 fOtherInterface
->SetMarked(true);