1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h"
10 #include "chromeos/dbus/shill_third_party_vpn_observer.h"
12 #include "dbus/message.h"
13 #include "dbus/object_proxy.h"
14 #include "third_party/cros_system_api/dbus/service_constants.h"
20 const char* kSetParametersKeyList
[] = {
21 shill::kAddressParameterThirdPartyVpn
,
22 shill::kBroadcastAddressParameterThirdPartyVpn
,
23 shill::kGatewayParameterThirdPartyVpn
,
24 shill::kBypassTunnelForIpParameterThirdPartyVpn
,
25 shill::kSubnetPrefixParameterThirdPartyVpn
,
26 shill::kMtuParameterThirdPartyVpn
,
27 shill::kDomainSearchParameterThirdPartyVpn
,
28 shill::kDnsServersParameterThirdPartyVpn
};
30 // The ShillThirdPartyVpnDriverClient implementation.
31 class ShillThirdPartyVpnDriverClientImpl
32 : public ShillThirdPartyVpnDriverClient
{
34 ShillThirdPartyVpnDriverClientImpl();
35 ~ShillThirdPartyVpnDriverClientImpl() override
;
37 // ShillThirdPartyVpnDriverClient overrides
38 void AddShillThirdPartyVpnObserver(
39 const std::string
& object_path_value
,
40 ShillThirdPartyVpnObserver
* observer
) override
;
42 void RemoveShillThirdPartyVpnObserver(
43 const std::string
& object_path_value
) override
;
46 const std::string
& object_path_value
,
47 const base::DictionaryValue
& parameters
,
48 const base::Closure
& callback
,
49 const ShillClientHelper::ErrorCallback
& error_callback
) override
;
51 void UpdateConnectionState(
52 const std::string
& object_path_value
,
53 const uint32_t connection_state
,
54 const base::Closure
& callback
,
55 const ShillClientHelper::ErrorCallback
& error_callback
) override
;
58 const std::string
& object_path_value
,
59 const std::string
& ip_packet
,
60 const base::Closure
& callback
,
61 const ShillClientHelper::ErrorCallback
& error_callback
) override
;
64 void Init(dbus::Bus
* bus
) override
{ bus_
= bus
; }
66 ShillThirdPartyVpnDriverClient::TestInterface
* GetTestInterface() override
{
73 explicit HelperInfo(dbus::ObjectProxy
* object_proxy
);
75 ShillClientHelper
* helper() { return &helper_
; }
76 ShillThirdPartyVpnObserver
* observer() { return observer_
; }
78 void set_observer(ShillThirdPartyVpnObserver
* observer
) {
82 base::WeakPtr
<HelperInfo
> GetWeakPtr() {
83 return weak_ptr_factory_
.GetWeakPtr();
87 ShillClientHelper helper_
;
88 ShillThirdPartyVpnObserver
* observer_
;
90 base::WeakPtrFactory
<HelperInfo
> weak_ptr_factory_
;
92 using HelperMap
= std::map
<std::string
, HelperInfo
*>;
94 static void OnPacketReceived(base::WeakPtr
<HelperInfo
> helper_info
,
95 dbus::Signal
* signal
);
96 static void OnPlatformMessage(base::WeakPtr
<HelperInfo
> helper_info
,
97 dbus::Signal
* signal
);
98 static void OnSignalConnected(const std::string
& interface
,
99 const std::string
& signal
,
102 // Returns or creates the corresponding ShillClientHelper for the
103 // |object_path_value|.
104 ShillClientHelper
* GetHelper(const std::string
& object_path_value
);
106 // Returns or creates the corresponding HelperInfo for the
107 // |object_path_value|.
108 HelperInfo
* GetHelperInfo(const std::string
& object_path_value
);
110 // Returns the corresponding HelperInfo for the |object_path| if exists,
112 HelperInfo
* FindHelperInfo(const dbus::ObjectPath
& object_path
);
114 // Deletes the helper object corresponding to |object_path|.
115 void DeleteHelper(const dbus::ObjectPath
& object_path
);
119 std::set
<std::string
> valid_keys_
;
121 DISALLOW_COPY_AND_ASSIGN(ShillThirdPartyVpnDriverClientImpl
);
124 ShillThirdPartyVpnDriverClientImpl::HelperInfo::HelperInfo(
125 dbus::ObjectProxy
* object_proxy
)
126 : helper_(object_proxy
), observer_(nullptr), weak_ptr_factory_(this) {
129 ShillThirdPartyVpnDriverClientImpl::ShillThirdPartyVpnDriverClientImpl()
131 for (uint32_t i
= 0; i
< arraysize(kSetParametersKeyList
); ++i
) {
132 valid_keys_
.insert(kSetParametersKeyList
[i
]);
136 ShillThirdPartyVpnDriverClientImpl::~ShillThirdPartyVpnDriverClientImpl() {
137 for (auto& iter
: helpers_
) {
138 HelperInfo
* helper_info
= iter
.second
;
139 bus_
->RemoveObjectProxy(
140 shill::kFlimflamServiceName
,
141 helper_info
->helper()->object_proxy()->object_path(),
142 base::Bind(&base::DoNothing
));
147 void ShillThirdPartyVpnDriverClientImpl::AddShillThirdPartyVpnObserver(
148 const std::string
& object_path_value
,
149 ShillThirdPartyVpnObserver
* observer
) {
150 HelperInfo
* helper_info
= GetHelperInfo(object_path_value
);
151 if (helper_info
->observer()) {
152 LOG(ERROR
) << "Observer exists for " << object_path_value
;
156 // TODO(kaliamoorthi): Remove the const_cast.
157 helper_info
->set_observer(observer
);
158 dbus::ObjectProxy
* proxy
=
159 const_cast<dbus::ObjectProxy
*>(helper_info
->helper()->object_proxy());
161 proxy
->ConnectToSignal(
162 shill::kFlimflamThirdPartyVpnInterface
, shill::kOnPlatformMessageFunction
,
163 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage
,
164 helper_info
->GetWeakPtr()),
165 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected
));
167 proxy
->ConnectToSignal(
168 shill::kFlimflamThirdPartyVpnInterface
, shill::kOnPacketReceivedFunction
,
169 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPacketReceived
,
170 helper_info
->GetWeakPtr()),
171 base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected
));
174 void ShillThirdPartyVpnDriverClientImpl::RemoveShillThirdPartyVpnObserver(
175 const std::string
& object_path_value
) {
176 HelperInfo
* helper_info
= FindHelperInfo(dbus::ObjectPath(object_path_value
));
178 LOG(ERROR
) << "Unknown object_path_value " << object_path_value
;
182 CHECK(helper_info
->observer());
183 helper_info
->set_observer(nullptr);
184 DeleteHelper(dbus::ObjectPath(object_path_value
));
187 void ShillThirdPartyVpnDriverClientImpl::DeleteHelper(
188 const dbus::ObjectPath
& object_path
) {
189 HelperInfo
* helper_info
= FindHelperInfo(dbus::ObjectPath(object_path
));
191 LOG(ERROR
) << "Unknown object_path " << object_path
.value();
195 bus_
->RemoveObjectProxy(shill::kFlimflamServiceName
, object_path
,
196 base::Bind(&base::DoNothing
));
197 helpers_
.erase(helpers_
.find(object_path
.value()));
201 void ShillThirdPartyVpnDriverClientImpl::SetParameters(
202 const std::string
& object_path_value
,
203 const base::DictionaryValue
& parameters
,
204 const base::Closure
& callback
,
205 const ShillClientHelper::ErrorCallback
& error_callback
) {
206 dbus::MethodCall
method_call(shill::kFlimflamThirdPartyVpnInterface
,
207 shill::kSetParametersFunction
);
208 dbus::MessageWriter
writer(&method_call
);
209 dbus::MessageWriter
array_writer(nullptr);
210 writer
.OpenArray("{ss}", &array_writer
);
211 for (base::DictionaryValue::Iterator
it(parameters
); !it
.IsAtEnd();
213 if (valid_keys_
.find(it
.key()) == valid_keys_
.end()) {
214 LOG(WARNING
) << "Unknown key " << it
.key();
218 if (!it
.value().GetAsString(&value
)) {
219 LOG(WARNING
) << "Non string value " << it
.value();
222 dbus::MessageWriter
entry_writer(nullptr);
223 array_writer
.OpenDictEntry(&entry_writer
);
224 entry_writer
.AppendString(it
.key());
225 entry_writer
.AppendString(value
);
226 array_writer
.CloseContainer(&entry_writer
);
228 writer
.CloseContainer(&array_writer
);
229 GetHelper(object_path_value
)
230 ->CallVoidMethodWithErrorCallback(&method_call
, callback
, error_callback
);
233 void ShillThirdPartyVpnDriverClientImpl::UpdateConnectionState(
234 const std::string
& object_path_value
,
235 const uint32_t connection_state
,
236 const base::Closure
& callback
,
237 const ShillClientHelper::ErrorCallback
& error_callback
) {
238 dbus::MethodCall
method_call(shill::kFlimflamThirdPartyVpnInterface
,
239 shill::kUpdateConnectionStateFunction
);
240 dbus::MessageWriter
writer(&method_call
);
241 writer
.AppendUint32(connection_state
);
242 GetHelper(object_path_value
)
243 ->CallVoidMethodWithErrorCallback(&method_call
, callback
, error_callback
);
246 void ShillThirdPartyVpnDriverClientImpl::SendPacket(
247 const std::string
& object_path_value
,
248 const std::string
& ip_packet
,
249 const base::Closure
& callback
,
250 const ShillClientHelper::ErrorCallback
& error_callback
) {
251 dbus::MethodCall
method_call(shill::kFlimflamThirdPartyVpnInterface
,
252 shill::kSendPacketFunction
);
253 dbus::MessageWriter
writer(&method_call
);
254 writer
.AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(ip_packet
.data()),
256 GetHelper(object_path_value
)
257 ->CallVoidMethodWithErrorCallback(&method_call
, callback
, error_callback
);
261 void ShillThirdPartyVpnDriverClientImpl::OnPacketReceived(
262 base::WeakPtr
<HelperInfo
> helper_info
,
263 dbus::Signal
* signal
) {
264 if (!helper_info
|| !helper_info
->observer())
267 dbus::MessageReader
reader(signal
);
268 const uint8_t* data
= nullptr;
270 if (reader
.PopArrayOfBytes(&data
, &length
)) {
271 helper_info
->observer()->OnPacketReceived(
272 std::string(reinterpret_cast<const char*>(data
), length
));
277 void ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage(
278 base::WeakPtr
<HelperInfo
> helper_info
,
279 dbus::Signal
* signal
) {
280 if (!helper_info
|| !helper_info
->observer())
283 dbus::MessageReader
reader(signal
);
284 uint32_t platform_message
= 0;
285 if (reader
.PopUint32(&platform_message
))
286 helper_info
->observer()->OnPlatformMessage(platform_message
);
290 void ShillThirdPartyVpnDriverClientImpl::OnSignalConnected(
291 const std::string
& interface
,
292 const std::string
& signal
,
294 LOG_IF(ERROR
, !success
) << "Connect to " << interface
<< " " << signal
298 ShillClientHelper
* ShillThirdPartyVpnDriverClientImpl::GetHelper(
299 const std::string
& object_path_value
) {
300 return GetHelperInfo(object_path_value
)->helper();
303 ShillThirdPartyVpnDriverClientImpl::HelperInfo
*
304 ShillThirdPartyVpnDriverClientImpl::FindHelperInfo(
305 const dbus::ObjectPath
& object_path
) {
306 HelperMap::iterator it
= helpers_
.find(object_path
.value());
307 return (it
!= helpers_
.end()) ? it
->second
: nullptr;
310 ShillThirdPartyVpnDriverClientImpl::HelperInfo
*
311 ShillThirdPartyVpnDriverClientImpl::GetHelperInfo(
312 const std::string
& object_path_value
) {
313 dbus::ObjectPath
object_path(object_path_value
);
314 HelperInfo
* helper_info
= FindHelperInfo(object_path
);
318 // There is no helper for the profile, create it.
319 dbus::ObjectProxy
* object_proxy
=
320 bus_
->GetObjectProxy(shill::kFlimflamServiceName
, object_path
);
321 helper_info
= new HelperInfo(object_proxy
);
322 helpers_
[object_path_value
] = helper_info
;
328 ShillThirdPartyVpnDriverClient::ShillThirdPartyVpnDriverClient() {
331 ShillThirdPartyVpnDriverClient::~ShillThirdPartyVpnDriverClient() {
335 ShillThirdPartyVpnDriverClient
* ShillThirdPartyVpnDriverClient::Create() {
336 return new ShillThirdPartyVpnDriverClientImpl();
339 } // namespace chromeos