 Chromium Code Reviews
 Chromium Code Reviews Issue 681723003:
  Add new shill client for VPN  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 681723003:
  Add new shill client for VPN  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: chromeos/dbus/shill_third_party_vpn_driver_client.cc | 
| diff --git a/chromeos/dbus/shill_third_party_vpn_driver_client.cc b/chromeos/dbus/shill_third_party_vpn_driver_client.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..00b7c21deb574b26f82d67e7c451b13d11db06db | 
| --- /dev/null | 
| +++ b/chromeos/dbus/shill_third_party_vpn_driver_client.cc | 
| @@ -0,0 +1,288 @@ | 
| +// Copyright 2014 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "chromeos/dbus/shill_third_party_vpn_driver_client.h" | 
| + | 
| +#include "base/bind.h" | 
| +#include "chromeos/dbus/shill_third_party_vpn_observer.h" | 
| +#include "dbus/bus.h" | 
| +#include "dbus/message.h" | 
| +#include "dbus/object_proxy.h" | 
| +#include "third_party/cros_system_api/dbus/service_constants.h" | 
| + | 
| +namespace shill { | 
| + | 
| +// TODO(kaliamoorthi): Move these constants to dbus/service_constants.h | 
| +const char kFlimflamThirdPartyVpnInterface[] = | 
| + "org.chromium.flimflam.ThirdPartyVpn"; | 
| +const char kSetParametersFunction[] = "SetParameters"; | 
| +const char kSendPacketFunction[] = "SendPacket"; | 
| +const char kUpdateConnectionStateFunction[] = "UpdateConnectionState"; | 
| +const char kOnPacketReceivedFunction[] = "OnPacketReceived"; | 
| +const char kOnPlatformMessageFunction[] = "OnPlatformMessage"; | 
| +const char* kSetParametersKeyList[] = {"address", | 
| + "broadcast_address", | 
| + "gateway", | 
| + "bypass_tunnel_for_ip", | 
| + "subnet_prefix", | 
| + "mtu", | 
| + "domain_search", | 
| + "dns_servers"}; | 
| +} // namespace shill | 
| + | 
| +namespace chromeos { | 
| + | 
| +namespace { | 
| + | 
| +// The ShillThirdPartyVpnDriverClient implementation. | 
| +class ShillThirdPartyVpnDriverClientImpl | 
| + : public ShillThirdPartyVpnDriverClient { | 
| + public: | 
| + ShillThirdPartyVpnDriverClientImpl(); | 
| + ~ShillThirdPartyVpnDriverClientImpl() override; | 
| + | 
| 
stevenjb
2014/10/30 20:55:36
// ShillThirdPartyVpnDriverClient
 
kaliamoorthi
2014/10/31 11:03:48
Done.
 | 
| + void AddShillThirdPartyVpnObserver( | 
| + const dbus::ObjectPath& object_path, | 
| + ShillThirdPartyVpnObserver* observer) override; | 
| + | 
| + void RemoveShillThirdPartyVpnObserver( | 
| + const dbus::ObjectPath& object_path) override; | 
| + | 
| + void SetParameters(const dbus::ObjectPath& object_path, | 
| + const base::DictionaryValue& parameters, | 
| + const VoidDBusMethodCallback& callback) override; | 
| + | 
| + void UpdateConnectionState(const dbus::ObjectPath& object_path, | 
| + const uint32 connection_state, | 
| + const VoidDBusMethodCallback& callback) override; | 
| + | 
| + void SendPacket(const dbus::ObjectPath& object_path, | 
| + const std::vector<uint8>& ip_packet, | 
| + const VoidDBusMethodCallback& callback) override; | 
| + | 
| + protected: | 
| + void Init(dbus::Bus* bus) override { bus_ = bus; } | 
| + | 
| + ShillThirdPartyVpnDriverClient::TestInterface* GetTestInterface() override { | 
| + return NULL; | 
| + } | 
| + | 
| + private: | 
| + struct HelperInfo { | 
| + explicit HelperInfo(dbus::ObjectProxy* object_proxy); | 
| + ShillClientHelper helper; | 
| + ShillThirdPartyVpnObserver* observer; | 
| + }; | 
| + typedef std::map<std::string, HelperInfo*> HelperMap; | 
| + | 
| + void ReleaseHelper(const dbus::ObjectPath& object_path); | 
| + | 
| + static void OnPacketReceived(HelperInfo* helper_info, dbus::Signal* signal); | 
| + static void OnPlatformMessage(HelperInfo* helper_info, dbus::Signal* signal); | 
| + static void OnSignalConnected(const std::string& interface, | 
| + const std::string& signal, | 
| + bool success); | 
| + | 
| + // Returns the corresponding ShillClientHelper for the profile. | 
| + ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { | 
| + HelperMap::iterator it = helpers_.find(service_path.value()); | 
| + if (it != helpers_.end()) | 
| + return &it->second->helper; | 
| + | 
| + // There is no helper for the profile, create it. | 
| + dbus::ObjectProxy* object_proxy = | 
| + bus_->GetObjectProxy(shill::kFlimflamServiceName, service_path); | 
| + HelperInfo* helper_info = new HelperInfo(object_proxy); | 
| + helpers_.insert(HelperMap::value_type(service_path.value(), helper_info)); | 
| + return &helper_info->helper; | 
| + } | 
| + | 
| + dbus::Bus* bus_; | 
| + HelperMap helpers_; | 
| + std::set<std::string> valid_keys_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(ShillThirdPartyVpnDriverClientImpl); | 
| +}; | 
| + | 
| +ShillThirdPartyVpnDriverClientImpl::HelperInfo::HelperInfo( | 
| + dbus::ObjectProxy* object_proxy) | 
| + : helper(object_proxy), observer(NULL) { | 
| +} | 
| + | 
| +ShillThirdPartyVpnDriverClientImpl::ShillThirdPartyVpnDriverClientImpl() | 
| + : bus_(NULL) { | 
| + for (uint32 i = 0; i < sizeof(shill::kSetParametersKeyList) / | 
| + sizeof(shill::kSetParametersKeyList[0]); | 
| 
stevenjb
2014/10/30 20:55:36
Ugh, clang format did this? Maybe use a tmp for si
 
kaliamoorthi
2014/10/31 11:03:47
Done.
 | 
| + ++i) { | 
| + valid_keys_.insert(shill::kSetParametersKeyList[i]); | 
| + } | 
| +} | 
| + | 
| +ShillThirdPartyVpnDriverClientImpl::~ShillThirdPartyVpnDriverClientImpl() { | 
| + for (HelperMap::iterator iter = helpers_.begin(); iter != helpers_.end(); | 
| + ++iter) { | 
| + HelperInfo* helper_info = iter->second; | 
| + bus_->RemoveObjectProxy(shill::kFlimflamServiceName, | 
| + helper_info->helper.object_proxy()->object_path(), | 
| + base::Bind(&base::DoNothing)); | 
| + delete helper_info; | 
| + } | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::AddShillThirdPartyVpnObserver( | 
| + const dbus::ObjectPath& object_path, | 
| + ShillThirdPartyVpnObserver* observer) { | 
| + bus_->AssertOnOriginThread(); | 
| + HelperMap::iterator it = helpers_.find(object_path.value()); | 
| + if (it == helpers_.end()) { | 
| + LOG(ERROR) << "Unknown object_path " << object_path.value(); | 
| + return; | 
| + } | 
| 
stevenjb
2014/10/30 20:55:36
This pattern is used in several places, consider w
 
kaliamoorthi
2014/10/31 11:03:48
Done.
 | 
| + | 
| + HelperInfo* helper_info = it->second; | 
| + CHECK(helper_info->observer == NULL); | 
| + helper_info->observer = observer; | 
| + dbus::ObjectProxy* proxy = | 
| + const_cast<dbus::ObjectProxy*>(helper_info->helper.object_proxy()); | 
| + | 
| + proxy->ConnectToSignal( | 
| + shill::kFlimflamThirdPartyVpnInterface, shill::kOnPlatformMessageFunction, | 
| + base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage, | 
| + helper_info), | 
| + base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected)); | 
| + | 
| + proxy->ConnectToSignal( | 
| + shill::kFlimflamThirdPartyVpnInterface, shill::kOnPacketReceivedFunction, | 
| + base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPacketReceived, | 
| + helper_info), | 
| + base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected)); | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::RemoveShillThirdPartyVpnObserver( | 
| + const dbus::ObjectPath& object_path) { | 
| + bus_->AssertOnOriginThread(); | 
| + HelperMap::iterator it = helpers_.find(object_path.value()); | 
| + if (it == helpers_.end()) { | 
| + LOG(ERROR) << "Unknown object_path " << object_path.value(); | 
| + return; | 
| + } | 
| + | 
| + HelperInfo* helper_info = it->second; | 
| + CHECK(helper_info->observer); | 
| + helper_info->observer = NULL; | 
| + ReleaseHelper(object_path); | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::ReleaseHelper( | 
| + const dbus::ObjectPath& object_path) { | 
| + HelperMap::iterator it = helpers_.find(object_path.value()); | 
| + if (it == helpers_.end()) { | 
| + LOG(ERROR) << "Unknown object_path " << object_path.value(); | 
| + return; | 
| + } | 
| + | 
| + HelperInfo* helper_info = it->second; | 
| + bus_->RemoveObjectProxy(shill::kFlimflamServiceName, object_path, | 
| + base::Bind(&base::DoNothing)); | 
| + helpers_.erase(it); | 
| + delete helper_info; | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::SetParameters( | 
| + const dbus::ObjectPath& object_path, | 
| + const base::DictionaryValue& parameters, | 
| + const VoidDBusMethodCallback& callback) { | 
| + dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
| + shill::kSetParametersFunction); | 
| + dbus::MessageWriter writer(&method_call); | 
| + dbus::MessageWriter array_writer(NULL); | 
| + writer.OpenArray("{ss}", &array_writer); | 
| + for (base::DictionaryValue::Iterator it(parameters); !it.IsAtEnd(); | 
| + it.Advance()) { | 
| + std::string value; | 
| + if (valid_keys_.find(it.key()) != valid_keys_.end() && | 
| + it.value().GetAsString(&value)) { | 
| 
stevenjb
2014/10/30 20:55:36
Invert logic, LOG(WARNING), and continue
 
kaliamoorthi
2014/10/31 11:03:47
Done.
 | 
| + dbus::MessageWriter entry_writer(NULL); | 
| + array_writer.OpenDictEntry(&entry_writer); | 
| + entry_writer.AppendString(it.key()); | 
| + entry_writer.AppendString(value); | 
| + array_writer.CloseContainer(&entry_writer); | 
| + } | 
| + } | 
| + writer.CloseContainer(&array_writer); | 
| + GetHelper(object_path)->CallVoidMethod(&method_call, callback); | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::UpdateConnectionState( | 
| + const dbus::ObjectPath& object_path, | 
| + const uint32 connection_state, | 
| + const VoidDBusMethodCallback& callback) { | 
| + dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
| + shill::kUpdateConnectionStateFunction); | 
| + dbus::MessageWriter writer(&method_call); | 
| + writer.AppendUint32(connection_state); | 
| + GetHelper(object_path)->CallVoidMethod(&method_call, callback); | 
| +} | 
| + | 
| +void ShillThirdPartyVpnDriverClientImpl::SendPacket( | 
| + const dbus::ObjectPath& object_path, | 
| + const std::vector<uint8>& ip_packet, | 
| + const VoidDBusMethodCallback& callback) { | 
| + dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
| + shill::kSendPacketFunction); | 
| + dbus::MessageWriter writer(&method_call); | 
| + writer.AppendArrayOfBytes(ip_packet.data(), ip_packet.size()); | 
| + GetHelper(object_path)->CallVoidMethod(&method_call, callback); | 
| +} | 
| + | 
| +// static | 
| +void ShillThirdPartyVpnDriverClientImpl::OnPacketReceived( | 
| + ShillThirdPartyVpnDriverClientImpl::HelperInfo* helper_info, | 
| + dbus::Signal* signal) { | 
| + if (!helper_info->observer) | 
| + return; | 
| + | 
| + dbus::MessageReader reader(signal); | 
| + const uint8* data; | 
| + size_t length; | 
| + if (reader.PopArrayOfBytes(&data, &length)) | 
| + helper_info->observer->OnPacketReceived(data, length); | 
| +} | 
| + | 
| +// static | 
| +void ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage( | 
| + ShillThirdPartyVpnDriverClientImpl::HelperInfo* helper_info, | 
| + dbus::Signal* signal) { | 
| + if (!helper_info->observer) | 
| + return; | 
| + | 
| + dbus::MessageReader reader(signal); | 
| + uint32 platform_message; | 
| + if (reader.PopUint32(&platform_message)) | 
| + helper_info->observer->OnPlatformMessage(platform_message); | 
| +} | 
| + | 
| +// static | 
| +void ShillThirdPartyVpnDriverClientImpl::OnSignalConnected( | 
| + const std::string& interface, | 
| + const std::string& signal, | 
| + bool success) { | 
| + LOG_IF(ERROR, !success) << "Connect to " << interface << " " << signal | 
| + << " failed."; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +ShillThirdPartyVpnDriverClient::ShillThirdPartyVpnDriverClient() { | 
| +} | 
| + | 
| +ShillThirdPartyVpnDriverClient::~ShillThirdPartyVpnDriverClient() { | 
| +} | 
| + | 
| +// static | 
| +ShillThirdPartyVpnDriverClient* ShillThirdPartyVpnDriverClient::Create() { | 
| + return new ShillThirdPartyVpnDriverClientImpl(); | 
| +} | 
| + | 
| +} // namespace chromeos |