blob: 6cea9f701e9399d9cd0a2b44b5dee7ec3918672d [file] [log] [blame]
repo sync90ee0fa2012-12-18 10:08:08 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/attribute_list.h"
6
7#include <ctype.h>
8#include <linux/nl80211.h>
9#include <netlink/attr.h>
10#include <netlink/netlink.h>
11
12#include <iomanip>
13#include <map>
14#include <string>
15
16#include <base/stl_util.h>
repo sync1538d442012-12-20 15:24:35 -080017#include <base/stringprintf.h>
repo sync90ee0fa2012-12-18 10:08:08 -080018
19#include "shill/logging.h"
20#include "shill/nl80211_attribute.h"
21#include "shill/scope_logger.h"
22
repo sync1538d442012-12-20 15:24:35 -080023using base::StringAppendF;
repo sync12cca802012-12-19 17:34:22 -080024using base::WeakPtr;
repo sync90ee0fa2012-12-18 10:08:08 -080025using std::map;
repo sync12cca802012-12-19 17:34:22 -080026using std::string;
repo sync90ee0fa2012-12-18 10:08:08 -080027
28namespace shill {
29
Wade Guthrie68da97c2013-02-26 13:09:35 -080030bool AttributeList::CreateAttribute(
31 int id, AttributeList::NewFromIdMethod factory) {
repo sync12cca802012-12-19 17:34:22 -080032 if (ContainsKey(attributes_, id)) {
33 LOG(ERROR) << "Trying to re-add attribute: " << id;
repo sync90ee0fa2012-12-18 10:08:08 -080034 return false;
35 }
Wade Guthrie68da97c2013-02-26 13:09:35 -080036 attributes_[id] = AttributePointer(factory.Run(id));
repo sync90ee0fa2012-12-18 10:08:08 -080037 return true;
38}
39
Wade Guthrie68da97c2013-02-26 13:09:35 -080040bool AttributeList::CreateAndInitAttribute(
41 int id, const nlattr *data, AttributeList::NewFromIdMethod factory) {
42 if (!CreateAttribute(id, factory)) {
repo sync90ee0fa2012-12-18 10:08:08 -080043 return false;
44 }
repo sync12cca802012-12-19 17:34:22 -080045 return attributes_[id]->InitFromNlAttr(data);
repo sync90ee0fa2012-12-18 10:08:08 -080046}
47
Wade Guthrie8e278612013-02-26 10:32:34 -080048void AttributeList::Print(int log_level, int indent) const {
repo sync1538d442012-12-20 15:24:35 -080049 map<int, AttributePointer>::const_iterator i;
50
51 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
Wade Guthrie8e278612013-02-26 10:32:34 -080052 i->second->Print(log_level, indent);
repo sync1538d442012-12-20 15:24:35 -080053 }
repo sync1538d442012-12-20 15:24:35 -080054}
55
repo syncdc085c82012-12-28 08:54:41 -080056ByteString AttributeList::Encode() const {
57 ByteString result;
58 map<int, AttributePointer>::const_iterator i;
59
60 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
61 result.Append(i->second->Encode());
62 }
63 return result;
64}
65
repo sync90ee0fa2012-12-18 10:08:08 -080066// U8 Attribute.
67
repo sync12cca802012-12-19 17:34:22 -080068bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080069 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080070 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080071 return false;
repo sync1538d442012-12-20 15:24:35 -080072 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080073}
74
repo sync12cca802012-12-19 17:34:22 -080075bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
76 if (ContainsKey(attributes_, id)) {
77 LOG(ERROR) << "Trying to re-add attribute: " << id;
78 return false;
79 }
repo sync1538d442012-12-20 15:24:35 -080080 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -080081 new NetlinkU8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080082 return true;
83}
84
Wade Guthrieefe1f0c2013-02-26 17:42:01 -080085bool AttributeList::SetU8AttributeValue(int id, uint8_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -080086 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080087 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080088 return false;
repo sync1538d442012-12-20 15:24:35 -080089 return attribute->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080090}
91
92
repo sync90ee0fa2012-12-18 10:08:08 -080093// U16 Attribute.
94
repo sync12cca802012-12-19 17:34:22 -080095bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080096 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080097 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080098 return false;
repo sync1538d442012-12-20 15:24:35 -080099 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800100}
101
repo sync12cca802012-12-19 17:34:22 -0800102bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
103 if (ContainsKey(attributes_, id)) {
104 LOG(ERROR) << "Trying to re-add attribute: " << id;
105 return false;
106 }
repo sync1538d442012-12-20 15:24:35 -0800107 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800108 new NetlinkU16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800109 return true;
110}
111
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800112bool AttributeList::SetU16AttributeValue(int id, uint16_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800113 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800114 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800115 return false;
repo sync1538d442012-12-20 15:24:35 -0800116 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800117}
118
repo sync90ee0fa2012-12-18 10:08:08 -0800119// U32 Attribute.
120
repo sync12cca802012-12-19 17:34:22 -0800121bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800122 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800123 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800124 return false;
repo sync1538d442012-12-20 15:24:35 -0800125 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800126}
127
repo sync12cca802012-12-19 17:34:22 -0800128bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
129 if (ContainsKey(attributes_, id)) {
130 LOG(ERROR) << "Trying to re-add attribute: " << id;
131 return false;
132 }
repo sync1538d442012-12-20 15:24:35 -0800133 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800134 new NetlinkU32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800135 return true;
136}
137
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800138bool AttributeList::SetU32AttributeValue(int id, uint32_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800139 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800140 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800141 return false;
repo sync1538d442012-12-20 15:24:35 -0800142 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800143}
144
repo sync90ee0fa2012-12-18 10:08:08 -0800145// U64 Attribute.
146
repo sync12cca802012-12-19 17:34:22 -0800147bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800148 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800149 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800150 return false;
repo sync1538d442012-12-20 15:24:35 -0800151 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800152}
153
repo sync12cca802012-12-19 17:34:22 -0800154bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
155 if (ContainsKey(attributes_, id)) {
156 LOG(ERROR) << "Trying to re-add attribute: " << id;
157 return false;
158 }
repo sync1538d442012-12-20 15:24:35 -0800159 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800160 new NetlinkU64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800161 return true;
162}
163
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800164bool AttributeList::SetU64AttributeValue(int id, uint64_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800165 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800166 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800167 return false;
repo sync1538d442012-12-20 15:24:35 -0800168 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800169}
170
repo sync90ee0fa2012-12-18 10:08:08 -0800171// Flag Attribute.
172
repo sync12cca802012-12-19 17:34:22 -0800173bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800174 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800175 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800176 return false;
repo sync1538d442012-12-20 15:24:35 -0800177 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800178}
179
repo sync12cca802012-12-19 17:34:22 -0800180bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
181 if (ContainsKey(attributes_, id)) {
182 LOG(ERROR) << "Trying to re-add attribute: " << id;
183 return false;
184 }
repo sync1538d442012-12-20 15:24:35 -0800185 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800186 new NetlinkFlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800187 return true;
188}
repo sync90ee0fa2012-12-18 10:08:08 -0800189
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800190bool AttributeList::SetFlagAttributeValue(int id, bool value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800191 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800192 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800193 return false;
repo sync1538d442012-12-20 15:24:35 -0800194 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800195}
196
197bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800198 bool flag;
199 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800200 return false;
201 }
202 return flag;
203}
204
205// String Attribute.
206
repo sync12cca802012-12-19 17:34:22 -0800207bool AttributeList::GetStringAttributeValue(int id, string *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800208 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800209 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800210 return false;
repo sync1538d442012-12-20 15:24:35 -0800211 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800212}
213
repo sync12cca802012-12-19 17:34:22 -0800214bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
215 if (ContainsKey(attributes_, id)) {
216 LOG(ERROR) << "Trying to re-add attribute: " << id;
217 return false;
218 }
repo sync1538d442012-12-20 15:24:35 -0800219 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800220 new NetlinkStringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800221 return true;
222}
223
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800224bool AttributeList::SetStringAttributeValue(int id, string value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800225 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800226 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800227 return false;
repo sync1538d442012-12-20 15:24:35 -0800228 return attribute->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800229}
230
231// Nested Attribute.
232
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800233bool AttributeList::GetNestedAttributeList(int id,
234 AttributeListRefPtr *value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800235 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800236 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800237 return false;
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800238 return attribute->GetNestedAttributeList(value);
239}
240
241bool AttributeList::ConstGetNestedAttributeList(
242 int id, AttributeListConstRefPtr *value) const {
243 NetlinkAttribute *attribute = GetAttribute(id);
244 if (!attribute)
245 return false;
246 return attribute->ConstGetNestedAttributeList(value);
247}
248
249bool AttributeList::SetNestedAttributeHasAValue(int id) {
250 NetlinkAttribute *attribute = GetAttribute(id);
251 if (!attribute)
252 return false;
253 return attribute->SetNestedHasAValue();
repo sync12cca802012-12-19 17:34:22 -0800254}
255
256bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
257 if (ContainsKey(attributes_, id)) {
258 LOG(ERROR) << "Trying to re-add attribute: " << id;
259 return false;
260 }
repo sync1538d442012-12-20 15:24:35 -0800261 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800262 new NetlinkNestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800263 return true;
264}
265
repo sync90ee0fa2012-12-18 10:08:08 -0800266// Raw Attribute.
267
repo sync1538d442012-12-20 15:24:35 -0800268bool AttributeList::GetRawAttributeValue(int id,
269 ByteString *output) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800270 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800271 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800272 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800273
274 ByteString raw_value;
275
repo sync1538d442012-12-20 15:24:35 -0800276 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800277 return false;
278
279 if (output) {
280 const nlattr *const_data =
281 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
282 // nla_data and nla_len don't change their parameters but don't declare
283 // them to be const. Hence the cast.
284 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
285 *output = ByteString(
286 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
287 nla_len(data_nlattr));
288 }
289 return true;
290}
291
Wade Guthrie68da97c2013-02-26 13:09:35 -0800292const NetlinkRawAttribute *AttributeList::GetRawAttribute(
repo sync1538d442012-12-20 15:24:35 -0800293 int id) const {
294 if (!HasRawAttribute(id)) {
repo sync12cca802012-12-19 17:34:22 -0800295 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
296 return NULL;
297 }
Wade Guthrie68da97c2013-02-26 13:09:35 -0800298 const NetlinkRawAttribute *attr =
299 reinterpret_cast<const NetlinkRawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800300 return attr;
301}
302
Wade Guthrie68da97c2013-02-26 13:09:35 -0800303NetlinkAttribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800304 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800305 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800306 if (i == attributes_.end()) {
307 return NULL;
308 }
repo sync1538d442012-12-20 15:24:35 -0800309 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800310}
311
repo sync1538d442012-12-20 15:24:35 -0800312bool AttributeList::HasRawAttribute(int id) const {
313 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800314 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800315 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800316 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800317 return false;
318 }
Wade Guthrie68da97c2013-02-26 13:09:35 -0800319 return (i->second->datatype() == NetlinkAttribute::kTypeRaw) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800320}
321
322
323} // namespace shill