xref: /haiku/src/add-ons/network_settings/dialup/IPCPAddon.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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 
44 IPCPAddon::IPCPAddon(BMessage *addons)
45 	: DialUpAddon(addons),
46 	fSettings(NULL),
47 	fProfile(NULL),
48 	fIPCPView(NULL)
49 {
50 }
51 
52 
53 IPCPAddon::~IPCPAddon()
54 {
55 }
56 
57 
58 bool
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, &parameter, &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, &parameter);
111 	}
112 
113 	index = 0;
114 	if(!FindMessageParameter(IPCP_PRIMARY_DNS_KEY, local, &parameter, &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, &parameter);
123 	}
124 
125 	index = 0;
126 	if(!FindMessageParameter(IPCP_SECONDARY_DNS_KEY, local, &parameter, &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, &parameter);
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
150 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
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
220 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*
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
249 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 
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
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
305 IPCPView::AttachedToWindow()
306 {
307 	SetViewColor(Parent()->ViewColor());
308 	fIsEnabled->SetTarget(this);
309 }
310 
311 
312 void
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
327 IPCPView::UpdateControls()
328 {
329 	fIPAddress->SetEnabled(IsEnabled());
330 	fPrimaryDNS->SetEnabled(IsEnabled());
331 	fSecondaryDNS->SetEnabled(IsEnabled());
332 }
333