// // Copyright (C) 2015 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "shill/dhcp_properties.h" #include #include #if defined(__ANDROID__) #include #else #include #endif // __ANDROID__ #include "shill/key_value_store.h" #include "shill/logging.h" #include "shill/property_accessor.h" #include "shill/property_store.h" #include "shill/store_interface.h" using std::string; namespace shill { namespace Logging { static auto kModuleLogScope = ScopeLogger::kDHCP; static string ObjectID(const DhcpProperties* d) { return "(dhcp_properties)"; } } namespace { // Prefix used for DhcpProperties in the PropertyStore. const char kStoragePrefix[] = "DHCPProperty."; const char* kPropertyNames[] = {DhcpProperties::kHostnameProperty, DhcpProperties::kVendorClassProperty}; std::string GetFullPropertyName(const std::string& property_name) { return kStoragePrefix + property_name; } } // namespace const char DhcpProperties::kHostnameProperty[] = "Hostname"; const char DhcpProperties::kVendorClassProperty[] = "VendorClass"; DhcpProperties::DhcpProperties() {} DhcpProperties::~DhcpProperties() {} void DhcpProperties::InitPropertyStore(PropertyStore* store) { SLOG(this, 2) << __func__; int i = 0; for (const auto& name : kPropertyNames) { store->RegisterDerivedString( GetFullPropertyName(name), StringAccessor( new CustomMappedAccessor( this, &DhcpProperties::ClearMappedStringProperty, &DhcpProperties::GetMappedStringProperty, &DhcpProperties::SetMappedStringProperty, i))); ++i; } } void DhcpProperties::Load(StoreInterface* storage, const string& id) { SLOG(this, 2) << __func__; properties_.Clear(); for (const auto& name : kPropertyNames) { string property_value; if (storage->GetString(id, GetFullPropertyName(name), &property_value)) { properties_.SetString(name, property_value); SLOG(this, 3) << "found DhcpProperty: setting " << name; } } } void DhcpProperties::Save(StoreInterface* storage, const string& id) const { SLOG(this, 2) << __func__; for (const auto& name : kPropertyNames) { string property_value; if (properties_.Contains(name)) { // The property is in the property store and it may have a setting or be // set to an empty string. This setting should be saved to the profile. property_value = properties_.GetString(name); storage->SetString(id, GetFullPropertyName(name), property_value); SLOG(this, 3) << "saved " << GetFullPropertyName(name); } else { // The property is not found and should be deleted from the property store // if it was there. storage->DeleteKey(id, GetFullPropertyName(name)); } } } std::unique_ptr DhcpProperties::Combine( const DhcpProperties& base, const DhcpProperties& to_merge) { SLOG(nullptr, 2) << __func__; std::unique_ptr to_return(new DhcpProperties()); to_return->properties_ = base.properties_; for (const auto& it : to_merge.properties_.properties()) { const string& name = it.first; const brillo::Any& value = it.second; to_return->properties_.Set(name, value); } return to_return; } bool DhcpProperties::GetValueForProperty(const string& name, string* value) const { if (properties_.ContainsString(name)) { *value = properties_.GetString(name); return true; } return false; } void DhcpProperties::ClearMappedStringProperty(const size_t& index, Error* error) { CHECK(index < arraysize(kPropertyNames)); if (properties_.ContainsString(kPropertyNames[index])) { properties_.RemoveString(kPropertyNames[index]); } else { error->Populate(Error::kNotFound, "Property is not set"); } } string DhcpProperties::GetMappedStringProperty(const size_t& index, Error* error) { CHECK(index < arraysize(kPropertyNames)); if (properties_.ContainsString(kPropertyNames[index])) { return properties_.GetString(kPropertyNames[index]); } error->Populate(Error::kNotFound, "Property is not set"); return string(); } bool DhcpProperties::SetMappedStringProperty( const size_t& index, const string& value, Error* error) { CHECK(index < arraysize(kPropertyNames)); if (properties_.ContainsString(kPropertyNames[index]) && properties_.GetString(kPropertyNames[index]) == value) { return false; } properties_.SetString(kPropertyNames[index], value); return true; } } // namespace shill