1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/dhcp_properties.h"
18
19 #include <string>
20
21 #include <base/macros.h>
22 #if defined(__ANDROID__)
23 #include <dbus/service_constants.h>
24 #else
25 #include <chromeos/dbus/service_constants.h>
26 #endif // __ANDROID__
27
28 #include "shill/key_value_store.h"
29 #include "shill/logging.h"
30 #include "shill/property_accessor.h"
31 #include "shill/property_store.h"
32 #include "shill/store_interface.h"
33
34 using std::string;
35
36 namespace shill {
37
38 namespace Logging {
39 static auto kModuleLogScope = ScopeLogger::kDHCP;
ObjectID(const DhcpProperties * d)40 static string ObjectID(const DhcpProperties* d) { return "(dhcp_properties)"; }
41 }
42
43 namespace {
44
45 // Prefix used for DhcpProperties in the PropertyStore.
46 const char kStoragePrefix[] = "DHCPProperty.";
47
48 const char* kPropertyNames[] = {DhcpProperties::kHostnameProperty,
49 DhcpProperties::kVendorClassProperty};
50
GetFullPropertyName(const std::string & property_name)51 std::string GetFullPropertyName(const std::string& property_name) {
52 return kStoragePrefix + property_name;
53 }
54
55 } // namespace
56
57 const char DhcpProperties::kHostnameProperty[] = "Hostname";
58 const char DhcpProperties::kVendorClassProperty[] = "VendorClass";
59
DhcpProperties()60 DhcpProperties::DhcpProperties() {}
61
~DhcpProperties()62 DhcpProperties::~DhcpProperties() {}
63
InitPropertyStore(PropertyStore * store)64 void DhcpProperties::InitPropertyStore(PropertyStore* store) {
65 SLOG(this, 2) << __func__;
66 int i = 0;
67 for (const auto& name : kPropertyNames) {
68 store->RegisterDerivedString(
69 GetFullPropertyName(name),
70 StringAccessor(
71 new CustomMappedAccessor<DhcpProperties, string, size_t>(
72 this,
73 &DhcpProperties::ClearMappedStringProperty,
74 &DhcpProperties::GetMappedStringProperty,
75 &DhcpProperties::SetMappedStringProperty,
76 i)));
77 ++i;
78 }
79 }
80
Load(StoreInterface * storage,const string & id)81 void DhcpProperties::Load(StoreInterface* storage, const string& id) {
82 SLOG(this, 2) << __func__;
83 properties_.Clear();
84 for (const auto& name : kPropertyNames) {
85 string property_value;
86 if (storage->GetString(id, GetFullPropertyName(name), &property_value)) {
87 properties_.SetString(name, property_value);
88 SLOG(this, 3) << "found DhcpProperty: setting " << name;
89 }
90 }
91 }
92
Save(StoreInterface * storage,const string & id) const93 void DhcpProperties::Save(StoreInterface* storage, const string& id) const {
94 SLOG(this, 2) << __func__;
95 for (const auto& name : kPropertyNames) {
96 string property_value;
97 if (properties_.Contains(name)) {
98 // The property is in the property store and it may have a setting or be
99 // set to an empty string. This setting should be saved to the profile.
100 property_value = properties_.GetString(name);
101 storage->SetString(id, GetFullPropertyName(name), property_value);
102 SLOG(this, 3) << "saved " << GetFullPropertyName(name);
103 } else {
104 // The property is not found and should be deleted from the property store
105 // if it was there.
106 storage->DeleteKey(id, GetFullPropertyName(name));
107 }
108 }
109 }
110
Combine(const DhcpProperties & base,const DhcpProperties & to_merge)111 std::unique_ptr<DhcpProperties> DhcpProperties::Combine(
112 const DhcpProperties& base, const DhcpProperties& to_merge) {
113 SLOG(nullptr, 2) << __func__;
114 std::unique_ptr<DhcpProperties> to_return(new DhcpProperties());
115 to_return->properties_ = base.properties_;
116 for (const auto& it : to_merge.properties_.properties()) {
117 const string& name = it.first;
118 const brillo::Any& value = it.second;
119 to_return->properties_.Set(name, value);
120 }
121 return to_return;
122 }
123
GetValueForProperty(const string & name,string * value) const124 bool DhcpProperties::GetValueForProperty(const string& name,
125 string* value) const {
126 if (properties_.ContainsString(name)) {
127 *value = properties_.GetString(name);
128 return true;
129 }
130 return false;
131 }
132
ClearMappedStringProperty(const size_t & index,Error * error)133 void DhcpProperties::ClearMappedStringProperty(const size_t& index,
134 Error* error) {
135 CHECK(index < arraysize(kPropertyNames));
136 if (properties_.ContainsString(kPropertyNames[index])) {
137 properties_.RemoveString(kPropertyNames[index]);
138 } else {
139 error->Populate(Error::kNotFound, "Property is not set");
140 }
141 }
142
GetMappedStringProperty(const size_t & index,Error * error)143 string DhcpProperties::GetMappedStringProperty(const size_t& index,
144 Error* error) {
145 CHECK(index < arraysize(kPropertyNames));
146 if (properties_.ContainsString(kPropertyNames[index])) {
147 return properties_.GetString(kPropertyNames[index]);
148 }
149 error->Populate(Error::kNotFound, "Property is not set");
150 return string();
151 }
152
SetMappedStringProperty(const size_t & index,const string & value,Error * error)153 bool DhcpProperties::SetMappedStringProperty(
154 const size_t& index, const string& value, Error* error) {
155 CHECK(index < arraysize(kPropertyNames));
156 if (properties_.ContainsString(kPropertyNames[index]) &&
157 properties_.GetString(kPropertyNames[index]) == value) {
158 return false;
159 }
160 properties_.SetString(kPropertyNames[index], value);
161 return true;
162 }
163
164 } // namespace shill
165