shill: Added nested attributes.
Nested attributes are now supported (and the crowd goes wild). A unit
test has been added for a nested attribute.
With this checkin, many of the methods had their |nl80211_attrs|
parameters replaced with |int|. This is because the nested attributes
each index into their respective attribute lists with custom indexes
rather than with |nl80211_attrs|. The code, therefore, needed to
support arbitrary integers if it was to support nested attributes.
As part of this checkin, the strict 'CHECK' for |HasAttribute| on access
has been replaced with a less drastic 'if/return false'.
There's some wonky code in here that will be fixed in the next checkin.
Currently, attribute_list.h needs to include nl80211_attribute.h because
the former needs an enum that is defined in the latter (can't do a
forward delcaration of an enum). Unfortunately, the latter needs to
include the former since a Nested attribute contains an AttributeList.
Currently, this is addressed by having the Nested attribute contain a
pointer to the list. That will be addressed in the next checkin.
BUG=chromium-os:36637, chromium-os:37496
TEST=unittests.
Change-Id: I01776909dc5f25340f5111f8f536dd0d34942617
Reviewed-on: https://gerrit.chromium.org/gerrit/40143
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Queue: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/attribute_list.cc b/attribute_list.cc
index 59e226e..dd61ff8 100644
--- a/attribute_list.cc
+++ b/attribute_list.cc
@@ -19,8 +19,9 @@
#include "shill/nl80211_attribute.h"
#include "shill/scope_logger.h"
-using std::string;
+using base::WeakPtr;
using std::map;
+using std::string;
namespace shill {
@@ -31,83 +32,188 @@
}
}
-bool AttributeList::CreateAttribute(nl80211_attrs name) {
- if (ContainsKey(attributes_, name)) {
- LOG(ERROR) << "Trying to re-add attribute: " << name;
+bool AttributeList::CreateAttribute(nl80211_attrs id) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
return false;
}
- attributes_[name] = Nl80211Attribute::NewFromName(name);
+ attributes_[id] = Nl80211Attribute::NewFromName(id);
return true;
}
-bool AttributeList::CreateAndInitFromNlAttr(nl80211_attrs name,
+bool AttributeList::CreateAndInitFromNlAttr(nl80211_attrs id,
const nlattr *data) {
- if (!CreateAttribute(name)) {
+ if (!CreateAttribute(id)) {
return false;
}
- return attributes_[name]->InitFromNlAttr(data);
+ return attributes_[id]->InitFromNlAttr(data);
}
// U8 Attribute.
-bool AttributeList::GetU8AttributeValue(nl80211_attrs name,
- uint8_t *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeU8));
+bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU8)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU8 exists.";
+ return false;
+ }
const Nl80211U8Attribute *attr =
- reinterpret_cast<const Nl80211U8Attribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211U8Attribute *>(GetAttribute(id));
return attr->GetU8Value(value);
}
+bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211U8Attribute(id, id_string);
+ return true;
+}
+
+bool AttributeList::SetU8AttributeValue(int id, uint8_t value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU8)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU8 exists.";
+ return false;
+ }
+ Nl80211U8Attribute *attr =
+ reinterpret_cast<Nl80211U8Attribute *>(GetAttribute(id));
+ return attr->SetU8Value(value);
+}
+
+
// U16 Attribute.
-bool AttributeList::GetU16AttributeValue(nl80211_attrs name,
- uint16_t *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeU16));
+bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU16)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU16 exists.";
+ return false;
+ }
const Nl80211U16Attribute *attr =
- reinterpret_cast<const Nl80211U16Attribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211U16Attribute *>(GetAttribute(id));
return attr->GetU16Value(value);
}
+bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211U16Attribute(id, id_string);
+ return true;
+}
+
+bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU16)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU16 exists.";
+ return false;
+ }
+ Nl80211U16Attribute *attr =
+ reinterpret_cast<Nl80211U16Attribute *>(GetAttribute(id));
+ return attr->SetU16Value(value);
+}
+
// U32 Attribute.
-bool AttributeList::GetU32AttributeValue(nl80211_attrs name,
- uint32_t *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeU32));
+bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU32)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU32 exists.";
+ return false;
+ }
const Nl80211U32Attribute *attr =
- reinterpret_cast<const Nl80211U32Attribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211U32Attribute *>(GetAttribute(id));
return attr->GetU32Value(value);
}
+bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211U32Attribute(id, id_string);
+ return true;
+}
+
+bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU32)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU32 exists.";
+ return false;
+ }
+ Nl80211U32Attribute *attr =
+ reinterpret_cast<Nl80211U32Attribute *>(GetAttribute(id));
+ return attr->SetU32Value(value);
+}
+
// U64 Attribute.
-bool AttributeList::GetU64AttributeValue(nl80211_attrs name,
- uint64_t *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeU64));
+bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU64)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU64 exists.";
+ return false;
+ }
const Nl80211U64Attribute *attr =
- reinterpret_cast<const Nl80211U64Attribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211U64Attribute *>(GetAttribute(id));
return attr->GetU64Value(value);
}
+bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211U64Attribute(id, id_string);
+ return true;
+}
+
+bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeU64)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeU64 exists.";
+ return false;
+ }
+ Nl80211U64Attribute *attr =
+ reinterpret_cast<Nl80211U64Attribute *>(GetAttribute(id));
+ return attr->SetU64Value(value);
+}
+
// Flag Attribute.
-bool AttributeList::GetFlagAttributeValue(nl80211_attrs name,
- bool *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeFlag));
+bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeFlag exists.";
+ return false;
+ }
const Nl80211FlagAttribute *attr =
- reinterpret_cast<const Nl80211FlagAttribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211FlagAttribute *>(GetAttribute(id));
return attr->GetFlagValue(value);
}
-bool AttributeList::IsFlagAttributeTrue(nl80211_attrs name) const {
- bool flag;
+bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211FlagAttribute(id, id_string);
+ return true;
+}
+bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeFlag exists.";
+ return false;
+ }
+ Nl80211FlagAttribute *attr =
+ reinterpret_cast<Nl80211FlagAttribute *>(GetAttribute(id));
+ return attr->SetFlagValue(value);
+}
+
+bool AttributeList::IsFlagAttributeTrue(int id) const {
// TODO(wdg): After message constructors add attributes, remove the following
// lines.
- if (!HasAttribute(name, Nl80211Attribute::kTypeFlag)) {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
return false;
}
- if (!GetFlagAttributeValue(name, &flag)) {
+ bool flag;
+ if (!GetFlagAttributeValue(id, &flag)) {
return false;
}
return flag;
@@ -115,21 +221,66 @@
// String Attribute.
-bool AttributeList::GetStringAttributeValue(nl80211_attrs name,
- string *value) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeString));
+bool AttributeList::GetStringAttributeValue(int id, string *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeString)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeString exists.";
+ return false;
+ }
const Nl80211StringAttribute *attr =
- reinterpret_cast<const Nl80211StringAttribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211StringAttribute *>(GetAttribute(id));
return attr->GetStringValue(value);
}
+bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211StringAttribute(id, id_string);
+ return true;
+}
+
+bool AttributeList::SetStringAttributeValue(int id, string value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeString)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeString exists.";
+ return false;
+ }
+ Nl80211StringAttribute *attr =
+ reinterpret_cast<Nl80211StringAttribute *>(GetAttribute(id));
+ return attr->SetStringValue(value);
+}
+
+// Nested Attribute.
+
+bool AttributeList::GetNestedAttributeValue(
+ int id, WeakPtr<AttributeList> *value) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeNested)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeNested exists.";
+ return false;
+ }
+ Nl80211NestedAttribute *attr =
+ reinterpret_cast<Nl80211NestedAttribute *>(GetAttribute(id));
+ return attr->GetNestedValue(value);
+}
+
+bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
+ if (ContainsKey(attributes_, id)) {
+ LOG(ERROR) << "Trying to re-add attribute: " << id;
+ return false;
+ }
+ attributes_[id] = new Nl80211NestedAttribute(id, id_string);
+ return true;
+}
+
// Raw Attribute.
-bool AttributeList::GetRawAttributeValue(nl80211_attrs name,
- ByteString *output) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeRaw));
+bool AttributeList::GetRawAttributeValue(int id, ByteString *output) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeRaw)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
+ return false;
+ }
const Nl80211RawAttribute *attr =
- reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
ByteString raw_value;
@@ -149,32 +300,34 @@
return true;
}
-const Nl80211RawAttribute *AttributeList::GetRawAttribute(
- nl80211_attrs name) const {
- CHECK(HasAttribute(name, Nl80211Attribute::kTypeRaw));
+const Nl80211RawAttribute *AttributeList::GetRawAttribute(int id) const {
+ if (!HasAttribute(id, Nl80211Attribute::kTypeRaw)) {
+ LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
+ return NULL;
+ }
const Nl80211RawAttribute *attr =
- reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(name));
+ reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
return attr;
}
-Nl80211Attribute *AttributeList::GetAttribute(nl80211_attrs name) const {
+Nl80211Attribute *AttributeList::GetAttribute(int id) const {
map<int, Nl80211Attribute *>::const_iterator i;
- i = attributes_.find(name);
+ i = attributes_.find(id);
if (i == attributes_.end()) {
return NULL;
}
return i->second;
}
-bool AttributeList::HasAttribute(nl80211_attrs name,
- Nl80211Attribute::Type type) const {
+bool AttributeList::HasAttribute(int id,
+ Nl80211Attribute::Type datatype) const {
map<int, Nl80211Attribute *>::const_iterator i;
- i = attributes_.find(name);
+ i = attributes_.find(id);
if (i == attributes_.end()) {
- LOG(ERROR) << "FALSE - Didn't find name " << name;
+ LOG(ERROR) << "FALSE - Didn't find id " << id;
return false;
}
- return (i->second->type() == type) ? true : false;
+ return (i->second->datatype() == datatype) ? true : false;
}