dhcp client: add RPC implementation part 2
am: dbc689e
* commit 'dbc689e3565b1b0e6fad3f2eb6cf11b02b22f39c':
dhcp client: add RPC implementation part 2
Change-Id: I5e1ef07c5fb887c8e0c4bd47a68ef58aaf96f783
diff --git a/dbus/service_dbus_adaptor.cc b/dbus/service_dbus_adaptor.cc
index 57f6592..bffd334 100644
--- a/dbus/service_dbus_adaptor.cc
+++ b/dbus/service_dbus_adaptor.cc
@@ -36,7 +36,8 @@
const scoped_refptr<dbus::Bus>& bus,
ExportedObjectManager* object_manager,
Service* service)
- : adaptor_(this),
+ : org::chromium::dhcp_client::ServiceAdaptor(this),
+ adaptor_(this),
object_path_(
base::StringPrintf("%s/services/%d",
ManagerAdaptor::GetObjectPath().value().c_str(),
@@ -50,6 +51,12 @@
ServiceDBusAdaptor::~ServiceDBusAdaptor() {}
+void ServiceDBusAdaptor::EmitEvent(const std::string& reason,
+ const brillo::VariantDictionary& configs) {
+ SendEventSignal(reason, configs);
+}
+
+
RPCObjectIdentifier ServiceDBusAdaptor::GetRpcObjectIdentifier() {
return object_path_;
}
diff --git a/dbus/service_dbus_adaptor.h b/dbus/service_dbus_adaptor.h
index 80e555b..0c954b8 100644
--- a/dbus/service_dbus_adaptor.h
+++ b/dbus/service_dbus_adaptor.h
@@ -27,7 +27,8 @@
class Service;
-class ServiceDBusAdaptor : public org::chromium::dhcp_client::ServiceInterface,
+class ServiceDBusAdaptor : public org::chromium::dhcp_client::ServiceAdaptor,
+ public org::chromium::dhcp_client::ServiceInterface,
public ServiceAdaptorInterface {
public:
ServiceDBusAdaptor(const scoped_refptr<dbus::Bus>& bus,
@@ -37,7 +38,8 @@
// Implementation of ServiceAdaptorInterface.
RPCObjectIdentifier GetRpcObjectIdentifier() override;
- // TODO(nywang): implement signal 'Event'
+ void EmitEvent(const std::string& reason,
+ const brillo::VariantDictionary& configs) override;
private:
org::chromium::dhcp_client::ServiceAdaptor adaptor_;
diff --git a/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml b/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml
index e2d5101..78df6b0 100644
--- a/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml
+++ b/dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml
@@ -3,6 +3,7 @@
<node xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.chromium.dhcp_client.Service">
<signal name="Event">
+ <arg name="reason" type="s"/>
<arg name = "configuration" type="a{sv}"/>
</signal>
</interface>
diff --git a/dhcp_client.gyp b/dhcp_client.gyp
index 8240ed2..7ed15aa 100644
--- a/dhcp_client.gyp
+++ b/dhcp_client.gyp
@@ -53,7 +53,6 @@
],
'includes': ['../../../../platform2/common-mk/generate-dbus-adaptors.gypi'],
},
-
{
'target_name': 'libdhcp_client',
'type': 'static_library',
@@ -96,6 +95,28 @@
'main.cc',
],
},
+ # dhcp client library generated headers. Used by other daemons to
+ # interact with dhcp client.
+ {
+ 'target_name': 'libdhcp_client-client-headers',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'libdhcp_client-client-dbus-proxies',
+ 'variables': {
+ 'dbus_service_config': 'dbus_bindings/dbus-service-config.json',
+ 'proxy_output_file': 'include/dhcp_client/dbus-proxies.h',
+ 'mock_output_file': 'include/dhcp_client/dbus-proxy-mocks.h',
+ 'proxy_path_in_mocks': 'dhcp_client/dbus-proxies.h',
+ },
+ 'sources': [
+ 'dbus_bindings/org.chromium.dhcp_client.Manager.dbus-xml',
+ 'dbus_bindings/org.chromium.dhcp_client.Service.dbus-xml',
+ ],
+ 'includes': ['../../../../platform2/common-mk/generate-dbus-proxies.gypi'],
+ },
+ ]
+ },
],
'conditions': [
['USE_test == 1', {
diff --git a/dhcpv4.cc b/dhcpv4.cc
index bf78157..f213074 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -30,10 +30,12 @@
#include <base/bind.h>
#include <base/logging.h>
+#include <brillo/variant_dictionary.h>
#include "dhcp_client/dhcp_message.h"
#include "dhcp_client/dhcp_options.h"
#include "dhcp_client/file_io.h"
+#include "dhcp_client/service_adaptor_interface.h"
using base::Bind;
using base::Unretained;
@@ -88,9 +90,27 @@
// TODO(nywang): find a place for the lease file.
const char kIPV4LeaseFilePathFormat[] =
"/tmp/lease-ipv4-%s.conf";
+
+// TODO(nywang): These constant will be moved to:
+// <dbus/dhcp_client/dbus-constants.h>
+// In this way shill can include this header and parse
+// the messages.
+
+const char kConfigurationKeyDNS[] = "DomainNameServers";
+const char kConfigurationKeyDomainName[] = "DomainName";
+const char kConfigurationKeyIPAddress[] = "IPAddress";
+const char kConfigurationKeyMTU[] = "InterfaceMTU";
+const char kConfigurationKeyRouters[] = "Routers";
+const char kConfigurationKeyVendorEncapsulatedOptions[] =
+ "VendorEncapsulatedOptions";
+const char kConfigurationKeySubnetCIDR[] = "SubnetCIDR";
+const char kReasonBound[] = "BOUND";
+const char kReasonFail[] = "FAIL";
+const char kReasonNak[] = "NAK";
} // namespace
-DHCPV4::DHCPV4(const std::string& interface_name,
+DHCPV4::DHCPV4(ServiceAdaptorInterface* adaptor,
+ const std::string& interface_name,
const ByteString& hardware_address,
unsigned int interface_index,
const std::string& network_id,
@@ -98,7 +118,8 @@
bool arp_gateway,
bool unicast_arp,
EventDispatcherInterface* event_dispatcher)
- : interface_name_(interface_name),
+ : adaptor_(adaptor),
+ interface_name_(interface_name),
hardware_address_(hardware_address),
interface_index_(interface_index),
network_id_(network_id),
@@ -127,7 +148,6 @@
server_identifier_ = 0;
transaction_id_ = 0;
offered_ip_address_ = 0;
- subnet_mask_ = 0;
client_ip_ = INADDR_ANY;
server_ip_ = INADDR_BROADCAST;
}
@@ -207,6 +227,7 @@
LOG(INFO) << "Start from INIT_REBOOT state";
if (!SendRequest()) {
ResetStateVariables();
+ EmitEvent(kReasonFail);
return false;
}
state_ = State::REBOOT;
@@ -326,7 +347,6 @@
offered_ip_address_ = your_ip_address;
server_identifier_ = msg.server_identifier();
transaction_id_ = msg.transaction_id();
- subnet_mask_ = msg.subnet_mask();
if (!SendRequest()) {
return;
@@ -395,11 +415,19 @@
state_ = State::BOUND;
client_ip_ = offered_ip_address_;
server_ip_ = server_identifier_;
+ // Set the option parameters.
+ subnet_mask_ = msg.subnet_mask();
+ interface_mtu_ = msg.interface_mtu();
+ router_ = msg.router();
+ dns_server_ = msg.dns_server();
+ vendor_specific_info_ = msg.vendor_specific_info();
+ domain_name_ = msg.domain_name();
// Write lease to persistent stotrage.
if (!network_id_.empty()) {
WriteLease();
}
- // TODO(nywang): Notify shill to configure the ip, gateway and DNS server.
+ // Send the DHCP configuration to Shill.
+ EmitEvent(kReasonBound);
// TODO(nywang): Setup a udp socket for future unicast, so that kernel can
// fill the ethernet header with gateway mac address for us.
}
@@ -430,10 +458,11 @@
LOG(INFO) << "Received DHCP NAK message with the following error message: "
<< msg.error_message();
}
+
// Set state variables upon receiving a valid Nak.
ResetStateVariables();
- // TODO(nywang): Notify shill the DHCP failure.
+ EmitEvent(kReasonNak);
}
bool DHCPV4::SendDiscover() {
@@ -719,6 +748,32 @@
state_ = State::REBIND;
}
+void DHCPV4::EmitEvent(const std::string& reason) {
+ brillo::VariantDictionary configs;
+ if (reason == kReasonBound) {
+ configs.emplace(kConfigurationKeyIPAddress, client_ip_);
+ configs.emplace(kConfigurationKeyMTU, interface_mtu_);
+ configs.emplace(kConfigurationKeyRouters, router_);
+ configs.emplace(kConfigurationKeyDNS, dns_server_);
+ configs.emplace(kConfigurationKeyVendorEncapsulatedOptions,
+ vendor_specific_info_);
+ configs.emplace(kConfigurationKeyDomainName, domain_name_);
+ uint32_t subnet_cidr = MasktoCIDR(subnet_mask_);
+ configs.emplace(kConfigurationKeySubnetCIDR, subnet_cidr);
+ }
+ adaptor_->EmitEvent(reason, configs);
+}
+
+uint32_t DHCPV4::MasktoCIDR(uint32_t subnet_mask) {
+ subnet_mask = ~subnet_mask;
+ uint32_t count = 0;
+ while (subnet_mask & 1) {
+ count++;
+ subnet_mask = subnet_mask >> 1;
+ }
+ return 32 - count;
+}
+
const std::string DHCPV4::IPtoString(uint32_t ip) {
char buffer[INET_ADDRSTRLEN];
ip = htonl(ip);
diff --git a/dhcpv4.h b/dhcpv4.h
index df76070..e8083f5 100644
--- a/dhcpv4.h
+++ b/dhcpv4.h
@@ -34,9 +34,12 @@
namespace dhcp_client {
+class ServiceAdaptorInterface;
+
class DHCPV4 : public DHCP {
public:
- DHCPV4(const std::string& interface_name,
+ DHCPV4(ServiceAdaptorInterface* adaptor,
+ const std::string& interface_name,
const shill::ByteString& hardware_address,
unsigned int interface_index,
const std::string& network_id,
@@ -67,6 +70,8 @@
bool ValidateOptions(const DHCPMessage& msg);
void ResetStateVariables();
+ // Util functions.
+ uint32_t MasktoCIDR(uint32_t subnet_mask);
const std::string IPtoString(uint32_t ip);
void HandleOffer(const DHCPMessage& msg);
@@ -79,6 +84,11 @@
// renewal responese from server. Therefore it is time for
// a rebinding process.
void RebindTask();
+
+ // Emit events through RPC adaptor
+ void EmitEvent(const std::string& reason);
+ // Serivce RPC adaptor
+ ServiceAdaptorInterface* adaptor_;
// Interface parameters.
std::string interface_name_;
shill::ByteString hardware_address_;
@@ -113,6 +123,16 @@
// Server IP address.
// It can be either a bounded server address or an INADDR_BROADCAST constant.
uint32_t server_ip_;
+ // Interface mtu.
+ uint16_t interface_mtu_;
+ // Aka Default Gateway.
+ std::vector<uint32_t> router_;
+ // Domain Name Servers.
+ std::vector<uint32_t> dns_server_;
+ // Vendor specific information.
+ shill::ByteString vendor_specific_info_;
+ // Domain name.
+ std::string domain_name_;
// Timeout callbacks.
base::CancelableClosure renewal_task_callback_;
diff --git a/service.cc b/service.cc
index 562980c..12080bc 100644
--- a/service.cc
+++ b/service.cc
@@ -72,7 +72,8 @@
if (type_ == DHCP::SERVICE_TYPE_IPV4 ||
type_ == DHCP::SERVICE_TYPE_BOTH) {
- state_machine_ipv4_.reset(new DHCPV4(interface_name_,
+ state_machine_ipv4_.reset(new DHCPV4(adaptor(),
+ interface_name_,
hardware_address_,
interface_index_,
network_id_,
diff --git a/service_adaptor_interface.h b/service_adaptor_interface.h
index f720541..49f7cca 100644
--- a/service_adaptor_interface.h
+++ b/service_adaptor_interface.h
@@ -19,6 +19,8 @@
#include <string>
+#include <brillo/variant_dictionary.h>
+
#include "dhcp_client/rpc_interface.h"
namespace dhcp_client {
@@ -29,6 +31,8 @@
public:
virtual ~ServiceAdaptorInterface() {}
virtual RPCObjectIdentifier GetRpcObjectIdentifier() = 0;
+ virtual void EmitEvent(const std::string& reason,
+ const brillo::VariantDictionary& configs) = 0;
};
} // namespace dhcp_client