1 /*
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.
5 */
6
7 //-----------------------------------------------------------------------
8 // IPCPAddon saves the loaded settings.
9 // IPCPView saves the current settings.
10 //-----------------------------------------------------------------------
11
12 #include "IPCPAddon.h"
13
14 #include "MessageDriverSettingsUtils.h"
15
16 #include <StringView.h>
17 #include <LayoutBuilder.h>
18 #include <SpaceLayoutItem.h>
19
20 #include <PPPDefs.h>
21 #include <IPCP.h>
22 // from IPCP addon
23
24
25 // GUI constants
26 static const uint32 kDefaultButtonWidth = 80;
27
28 // message constants
29 static const uint32 kMsgUpdateControls = 'UCTL';
30
31 // labels
32 static const char *kLabelIPCP = "TCP/IP";
33 static const char *kLabelIPAddress = "IP address: ";
34 static const char *kLabelPrimaryDNS = "Primary DNS: ";
35 static const char *kLabelSecondaryDNS = "Secondary DNS: ";
36 static const char *kLabelOptional = "(Optional)";
37 static const char *kLabelExtendedOptions = "Extended options:";
38 static const char *kLabelEnabled = "Enable TCP/IP protocol";
39
40 // add-on descriptions
41 static const char *kKernelModuleName = "ipcp";
42
43
IPCPAddon(BMessage * addons)44 IPCPAddon::IPCPAddon(BMessage *addons)
45 : DialUpAddon(addons),
46 fSettings(NULL),
47 fProfile(NULL),
48 fIPCPView(NULL)
49 {
50 }
51
52
~IPCPAddon()53 IPCPAddon::~IPCPAddon()
54 {
55 }
56
57
58 bool
LoadSettings(BMessage * settings,BMessage * profile,bool isNew)59 IPCPAddon::LoadSettings(BMessage *settings, BMessage *profile, bool isNew)
60 {
61 fIsNew = isNew;
62 fIsEnabled = false;
63 fIPAddress = fPrimaryDNS = fSecondaryDNS = "";
64 fSettings = settings;
65 fProfile = profile;
66
67 if(fIPCPView)
68 fIPCPView->Reload();
69 // reset all views (empty settings)
70
71 if(!settings || !profile || isNew)
72 return true;
73
74 BMessage protocol;
75
76 // settings
77 int32 protocolIndex = FindIPCPProtocol(*fSettings, &protocol);
78 if(protocolIndex < 0)
79 return true;
80
81 protocol.AddBool(MDSU_VALID, true);
82 fSettings->ReplaceMessage(MDSU_PARAMETERS, protocolIndex, &protocol);
83
84 // profile
85 protocolIndex = FindIPCPProtocol(*fProfile, &protocol);
86 if(protocolIndex < 0)
87 return true;
88
89 fIsEnabled = true;
90
91 // the "Local" side parameter
92 BMessage local;
93 int32 localSideIndex = 0;
94 if(!FindMessageParameter(IPCP_LOCAL_SIDE_KEY, protocol, &local, &localSideIndex))
95 local.MakeEmpty();
96 // just fall through and pretend we have an empty "Local" side parameter
97
98 // now load the supported parameters (the client-relevant subset)
99 BString name;
100 BMessage parameter;
101 int32 index = 0;
102 if(!FindMessageParameter(IPCP_IP_ADDRESS_KEY, local, ¶meter, &index)
103 || parameter.FindString(MDSU_VALUES, &fIPAddress) != B_OK)
104 fIPAddress = "";
105 else {
106 if(fIPAddress == "auto")
107 fIPAddress = "";
108
109 parameter.AddBool(MDSU_VALID, true);
110 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter);
111 }
112
113 index = 0;
114 if(!FindMessageParameter(IPCP_PRIMARY_DNS_KEY, local, ¶meter, &index)
115 || parameter.FindString(MDSU_VALUES, &fPrimaryDNS) != B_OK)
116 fPrimaryDNS = "";
117 else {
118 if(fPrimaryDNS == "auto")
119 fPrimaryDNS = "";
120
121 parameter.AddBool(MDSU_VALID, true);
122 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter);
123 }
124
125 index = 0;
126 if(!FindMessageParameter(IPCP_SECONDARY_DNS_KEY, local, ¶meter, &index)
127 || parameter.FindString(MDSU_VALUES, &fSecondaryDNS) != B_OK)
128 fSecondaryDNS = "";
129 else {
130 if(fSecondaryDNS == "auto")
131 fSecondaryDNS = "";
132
133 parameter.AddBool(MDSU_VALID, true);
134 local.ReplaceMessage(MDSU_PARAMETERS, index, ¶meter);
135 }
136
137 local.AddBool(MDSU_VALID, true);
138 protocol.ReplaceMessage(MDSU_PARAMETERS, localSideIndex, &local);
139 protocol.AddBool(MDSU_VALID, true);
140 fProfile->ReplaceMessage(MDSU_PARAMETERS, protocolIndex, &protocol);
141
142 if(fIPCPView)
143 fIPCPView->Reload();
144
145 return true;
146 }
147
148
149 void
IsModified(bool * settings,bool * profile) const150 IPCPAddon::IsModified(bool *settings, bool *profile) const
151 {
152 if(!fSettings) {
153 *settings = *profile = false;
154 return;
155 }
156
157 *settings = fIsEnabled != fIPCPView->IsEnabled();
158 *profile = (*settings || fIPAddress != fIPCPView->IPAddress()
159 || fPrimaryDNS != fIPCPView->PrimaryDNS()
160 || fSecondaryDNS != fIPCPView->SecondaryDNS());
161 }
162
163
164 bool
SaveSettings(BMessage * settings,BMessage * profile,bool saveTemporary)165 IPCPAddon::SaveSettings(BMessage *settings, BMessage *profile, bool saveTemporary)
166 {
167 if(!fSettings || !settings)
168 return false;
169
170 if(!fIPCPView->IsEnabled())
171 return true;
172
173 BMessage protocol, local;
174 protocol.AddString(MDSU_NAME, PPP_PROTOCOL_KEY);
175 protocol.AddString(MDSU_VALUES, kKernelModuleName);
176 settings->AddMessage(MDSU_PARAMETERS, &protocol);
177 // the settings contain a simple "protocol ipcp" string
178
179 // now create the profile with all subparameters
180 local.AddString(MDSU_NAME, IPCP_LOCAL_SIDE_KEY);
181 bool needsLocal = false;
182
183 if(fIPCPView->IPAddress() && strlen(fIPCPView->IPAddress()) > 0) {
184 // save IP address, too
185 needsLocal = true;
186 BMessage ip;
187 ip.AddString(MDSU_NAME, IPCP_IP_ADDRESS_KEY);
188 ip.AddString(MDSU_VALUES, fIPCPView->IPAddress());
189 local.AddMessage(MDSU_PARAMETERS, &ip);
190 }
191
192 if(fIPCPView->PrimaryDNS() && strlen(fIPCPView->PrimaryDNS()) > 0) {
193 // save service name, too
194 needsLocal = true;
195 BMessage dns;
196 dns.AddString(MDSU_NAME, IPCP_PRIMARY_DNS_KEY);
197 dns.AddString(MDSU_VALUES, fIPCPView->PrimaryDNS());
198 local.AddMessage(MDSU_PARAMETERS, &dns);
199 }
200
201 if(fIPCPView->SecondaryDNS() && strlen(fIPCPView->SecondaryDNS()) > 0) {
202 // save service name, too
203 needsLocal = true;
204 BMessage dns;
205 dns.AddString(MDSU_NAME, IPCP_SECONDARY_DNS_KEY);
206 dns.AddString(MDSU_VALUES, fIPCPView->SecondaryDNS());
207 local.AddMessage(MDSU_PARAMETERS, &dns);
208 }
209
210 if(needsLocal)
211 protocol.AddMessage(MDSU_PARAMETERS, &local);
212
213 profile->AddMessage(MDSU_PARAMETERS, &protocol);
214
215 return true;
216 }
217
218
219 bool
GetPreferredSize(float * width,float * height) const220 IPCPAddon::GetPreferredSize(float *width, float *height) const
221 {
222 BRect rect;
223 if(Addons()->FindRect(DUN_TAB_VIEW_RECT, &rect) != B_OK)
224 rect.Set(0, 0, 200, 300);
225 // set default values
226
227 if(width)
228 *width = rect.Width();
229 if(height)
230 *height = rect.Height();
231
232 return true;
233 }
234
235
236 BView*
CreateView()237 IPCPAddon::CreateView()
238 {
239 if (!fIPCPView) {
240 fIPCPView = new IPCPView(this);
241 fIPCPView->Reload();
242 }
243
244 return fIPCPView;
245 }
246
247
248 int32
FindIPCPProtocol(const BMessage & message,BMessage * protocol) const249 IPCPAddon::FindIPCPProtocol(const BMessage& message, BMessage *protocol) const
250 {
251 if(!protocol)
252 return -1;
253
254 BString name;
255 for(int32 index = 0; FindMessageParameter(PPP_PROTOCOL_KEY, message, protocol,
256 &index); index++)
257 if(protocol->FindString(MDSU_VALUES, &name) == B_OK
258 && name == kKernelModuleName)
259 return index;
260
261 return -1;
262 }
263
264
IPCPView(IPCPAddon * addon)265 IPCPView::IPCPView(IPCPAddon *addon)
266 : BView(kLabelIPCP, 0),
267 fAddon(addon)
268 {
269 fIPAddress = new BTextControl("ip", kLabelIPAddress, NULL, NULL);
270 fPrimaryDNS = new BTextControl("primaryDNS", kLabelPrimaryDNS, NULL, NULL);
271 fSecondaryDNS = new BTextControl("secondaryDNS", kLabelSecondaryDNS, NULL,
272 NULL);
273 fIsEnabled = new BCheckBox("isEnabled", kLabelEnabled,
274 new BMessage(kMsgUpdateControls));
275
276 BLayoutBuilder::Grid<>(this, B_USE_HALF_ITEM_SPACING)
277 .SetInsets(B_USE_HALF_ITEM_INSETS)
278 .Add(fIsEnabled, 0, 0)
279 .Add(new BStringView("expert", kLabelExtendedOptions), 0, 1)
280 .Add(fIPAddress, 0, 2)
281 .Add(new BStringView("optional_1", kLabelOptional), 1, 2)
282 .Add(fPrimaryDNS, 0, 3)
283 .Add(new BStringView("optional_2", kLabelOptional), 1, 3)
284 .Add(fSecondaryDNS, 0, 4)
285 .Add(new BStringView("optional_3", kLabelOptional), 1, 4)
286 .Add(BSpaceLayoutItem::CreateGlue(), 0, 5)
287 .End();
288 }
289
290
291 void
Reload()292 IPCPView::Reload()
293 {
294 fIsEnabled->SetValue(Addon()->IsEnabled() || Addon()->IsNew());
295 // enable TCP/IP by default
296 fIPAddress->SetText(Addon()->IPAddress());
297 fPrimaryDNS->SetText(Addon()->PrimaryDNS());
298 fSecondaryDNS->SetText(Addon()->SecondaryDNS());
299
300 UpdateControls();
301 }
302
303
304 void
AttachedToWindow()305 IPCPView::AttachedToWindow()
306 {
307 SetViewColor(Parent()->ViewColor());
308 fIsEnabled->SetTarget(this);
309 }
310
311
312 void
MessageReceived(BMessage * message)313 IPCPView::MessageReceived(BMessage *message)
314 {
315 switch(message->what) {
316 case kMsgUpdateControls:
317 UpdateControls();
318 break;
319
320 default:
321 BView::MessageReceived(message);
322 }
323 }
324
325
326 void
UpdateControls()327 IPCPView::UpdateControls()
328 {
329 fIPAddress->SetEnabled(IsEnabled());
330 fPrimaryDNS->SetEnabled(IsEnabled());
331 fSecondaryDNS->SetEnabled(IsEnabled());
332 }
333