blob: ea797a06f4ee47b2b15844d471e55ac02d1f1d17 [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
repo sync12cca802012-12-19 17:34:22 -080030bool AttributeList::CreateAttribute(nl80211_attrs id) {
31 if (ContainsKey(attributes_, id)) {
32 LOG(ERROR) << "Trying to re-add attribute: " << id;
repo sync90ee0fa2012-12-18 10:08:08 -080033 return false;
34 }
repo sync1538d442012-12-20 15:24:35 -080035 attributes_[id] = AttributePointer(Nl80211Attribute::NewFromName(id));
repo sync90ee0fa2012-12-18 10:08:08 -080036 return true;
37}
38
repo sync12cca802012-12-19 17:34:22 -080039bool AttributeList::CreateAndInitFromNlAttr(nl80211_attrs id,
repo sync90ee0fa2012-12-18 10:08:08 -080040 const nlattr *data) {
repo sync12cca802012-12-19 17:34:22 -080041 if (!CreateAttribute(id)) {
repo sync90ee0fa2012-12-18 10:08:08 -080042 return false;
43 }
repo sync12cca802012-12-19 17:34:22 -080044 return attributes_[id]->InitFromNlAttr(data);
repo sync90ee0fa2012-12-18 10:08:08 -080045}
46
repo sync1538d442012-12-20 15:24:35 -080047string AttributeList::ToString() const {
48 string output;
49 map<int, AttributePointer>::const_iterator i;
50
51 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
52 string attribute_string;
53 i->second->ToString(&attribute_string);
54 StringAppendF(&output, " Attr: %s(%d)=%s, Type: %s\n",
55 i->second->id_string(),
56 i->second->id(),
57 attribute_string.c_str(),
58 i->second->datatype_string());
59 }
60 return output;
61}
62
repo sync90ee0fa2012-12-18 10:08:08 -080063// U8 Attribute.
64
repo sync12cca802012-12-19 17:34:22 -080065bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080066 Nl80211Attribute *attribute = GetAttribute(id);
67 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080068 return false;
repo sync1538d442012-12-20 15:24:35 -080069 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080070}
71
repo sync12cca802012-12-19 17:34:22 -080072bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
73 if (ContainsKey(attributes_, id)) {
74 LOG(ERROR) << "Trying to re-add attribute: " << id;
75 return false;
76 }
repo sync1538d442012-12-20 15:24:35 -080077 attributes_[id] = AttributePointer(
78 new Nl80211U8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080079 return true;
80}
81
82bool AttributeList::SetU8AttributeValue(int id, uint8_t value) const {
repo sync1538d442012-12-20 15:24:35 -080083 Nl80211Attribute *attribute = GetAttribute(id);
84 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080085 return false;
repo sync1538d442012-12-20 15:24:35 -080086 return attribute->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080087}
88
89
repo sync90ee0fa2012-12-18 10:08:08 -080090// U16 Attribute.
91
repo sync12cca802012-12-19 17:34:22 -080092bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080093 Nl80211Attribute *attribute = GetAttribute(id);
94 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080095 return false;
repo sync1538d442012-12-20 15:24:35 -080096 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080097}
98
repo sync12cca802012-12-19 17:34:22 -080099bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
100 if (ContainsKey(attributes_, id)) {
101 LOG(ERROR) << "Trying to re-add attribute: " << id;
102 return false;
103 }
repo sync1538d442012-12-20 15:24:35 -0800104 attributes_[id] = AttributePointer(
105 new Nl80211U16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800106 return true;
107}
108
109bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800110 Nl80211Attribute *attribute = GetAttribute(id);
111 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800112 return false;
repo sync1538d442012-12-20 15:24:35 -0800113 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800114}
115
repo sync90ee0fa2012-12-18 10:08:08 -0800116// U32 Attribute.
117
repo sync12cca802012-12-19 17:34:22 -0800118bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800119 Nl80211Attribute *attribute = GetAttribute(id);
120 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800121 return false;
repo sync1538d442012-12-20 15:24:35 -0800122 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800123}
124
repo sync12cca802012-12-19 17:34:22 -0800125bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
126 if (ContainsKey(attributes_, id)) {
127 LOG(ERROR) << "Trying to re-add attribute: " << id;
128 return false;
129 }
repo sync1538d442012-12-20 15:24:35 -0800130 attributes_[id] = AttributePointer(
131 new Nl80211U32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800132 return true;
133}
134
135bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800136 Nl80211Attribute *attribute = GetAttribute(id);
137 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800138 return false;
repo sync1538d442012-12-20 15:24:35 -0800139 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800140}
141
repo sync90ee0fa2012-12-18 10:08:08 -0800142// U64 Attribute.
143
repo sync12cca802012-12-19 17:34:22 -0800144bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800145 Nl80211Attribute *attribute = GetAttribute(id);
146 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800147 return false;
repo sync1538d442012-12-20 15:24:35 -0800148 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800149}
150
repo sync12cca802012-12-19 17:34:22 -0800151bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
152 if (ContainsKey(attributes_, id)) {
153 LOG(ERROR) << "Trying to re-add attribute: " << id;
154 return false;
155 }
repo sync1538d442012-12-20 15:24:35 -0800156 attributes_[id] = AttributePointer(
157 new Nl80211U64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800158 return true;
159}
160
161bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800162 Nl80211Attribute *attribute = GetAttribute(id);
163 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800164 return false;
repo sync1538d442012-12-20 15:24:35 -0800165 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800166}
167
repo sync90ee0fa2012-12-18 10:08:08 -0800168// Flag Attribute.
169
repo sync12cca802012-12-19 17:34:22 -0800170bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
repo sync1538d442012-12-20 15:24:35 -0800171 Nl80211Attribute *attribute = GetAttribute(id);
172 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800173 return false;
repo sync1538d442012-12-20 15:24:35 -0800174 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800175}
176
repo sync12cca802012-12-19 17:34:22 -0800177bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
178 if (ContainsKey(attributes_, id)) {
179 LOG(ERROR) << "Trying to re-add attribute: " << id;
180 return false;
181 }
repo sync1538d442012-12-20 15:24:35 -0800182 attributes_[id] = AttributePointer(
183 new Nl80211FlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800184 return true;
185}
repo sync90ee0fa2012-12-18 10:08:08 -0800186
repo sync12cca802012-12-19 17:34:22 -0800187bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
repo sync1538d442012-12-20 15:24:35 -0800188 Nl80211Attribute *attribute = GetAttribute(id);
189 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800190 return false;
repo sync1538d442012-12-20 15:24:35 -0800191 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800192}
193
194bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800195 bool flag;
196 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800197 return false;
198 }
199 return flag;
200}
201
202// String Attribute.
203
repo sync12cca802012-12-19 17:34:22 -0800204bool AttributeList::GetStringAttributeValue(int id, string *value) const {
repo sync1538d442012-12-20 15:24:35 -0800205 Nl80211Attribute *attribute = GetAttribute(id);
206 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800207 return false;
repo sync1538d442012-12-20 15:24:35 -0800208 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800209}
210
repo sync12cca802012-12-19 17:34:22 -0800211bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
212 if (ContainsKey(attributes_, id)) {
213 LOG(ERROR) << "Trying to re-add attribute: " << id;
214 return false;
215 }
repo sync1538d442012-12-20 15:24:35 -0800216 attributes_[id] = AttributePointer(
217 new Nl80211StringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800218 return true;
219}
220
221bool AttributeList::SetStringAttributeValue(int id, string value) const {
repo sync1538d442012-12-20 15:24:35 -0800222 Nl80211Attribute *attribute = GetAttribute(id);
223 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800224 return false;
repo sync1538d442012-12-20 15:24:35 -0800225 return attribute->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800226}
227
228// Nested Attribute.
229
230bool AttributeList::GetNestedAttributeValue(
231 int id, WeakPtr<AttributeList> *value) const {
repo sync1538d442012-12-20 15:24:35 -0800232 Nl80211Attribute *attribute = GetAttribute(id);
233 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800234 return false;
repo sync1538d442012-12-20 15:24:35 -0800235 return attribute->GetNestedValue(value);
repo sync12cca802012-12-19 17:34:22 -0800236}
237
238bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
239 if (ContainsKey(attributes_, id)) {
240 LOG(ERROR) << "Trying to re-add attribute: " << id;
241 return false;
242 }
repo sync1538d442012-12-20 15:24:35 -0800243 attributes_[id] = AttributePointer(
244 new Nl80211NestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800245 return true;
246}
247
repo sync90ee0fa2012-12-18 10:08:08 -0800248// Raw Attribute.
249
repo sync1538d442012-12-20 15:24:35 -0800250bool AttributeList::GetRawAttributeValue(int id,
251 ByteString *output) const {
252 Nl80211Attribute *attribute = GetAttribute(id);
253 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800254 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800255
256 ByteString raw_value;
257
repo sync1538d442012-12-20 15:24:35 -0800258 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800259 return false;
260
261 if (output) {
262 const nlattr *const_data =
263 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
264 // nla_data and nla_len don't change their parameters but don't declare
265 // them to be const. Hence the cast.
266 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
267 *output = ByteString(
268 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
269 nla_len(data_nlattr));
270 }
271 return true;
272}
273
repo sync1538d442012-12-20 15:24:35 -0800274const Nl80211RawAttribute *AttributeList::GetRawAttribute(
275 int id) const {
276 if (!HasRawAttribute(id)) {
repo sync12cca802012-12-19 17:34:22 -0800277 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
278 return NULL;
279 }
repo sync90ee0fa2012-12-18 10:08:08 -0800280 const Nl80211RawAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800281 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800282 return attr;
283}
284
repo sync12cca802012-12-19 17:34:22 -0800285Nl80211Attribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800286 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800287 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800288 if (i == attributes_.end()) {
289 return NULL;
290 }
repo sync1538d442012-12-20 15:24:35 -0800291 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800292}
293
repo sync1538d442012-12-20 15:24:35 -0800294bool AttributeList::HasRawAttribute(int id) const {
295 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800296 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800297 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800298 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800299 return false;
300 }
repo sync1538d442012-12-20 15:24:35 -0800301 return (i->second->datatype() == Nl80211Attribute::kTypeRaw) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800302}
303
304
305} // namespace shill