blob: 2717a00f1698a19686b8a68c8cfd0163187a42e0 [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
Wade Guthrie8e278612013-02-26 10:32:34 -080047void AttributeList::Print(int log_level, int indent) const {
repo sync1538d442012-12-20 15:24:35 -080048 map<int, AttributePointer>::const_iterator i;
49
50 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
Wade Guthrie8e278612013-02-26 10:32:34 -080051 i->second->Print(log_level, indent);
repo sync1538d442012-12-20 15:24:35 -080052 }
repo sync1538d442012-12-20 15:24:35 -080053}
54
repo syncdc085c82012-12-28 08:54:41 -080055ByteString AttributeList::Encode() const {
56 ByteString result;
57 map<int, AttributePointer>::const_iterator i;
58
59 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
60 result.Append(i->second->Encode());
61 }
62 return result;
63}
64
repo sync90ee0fa2012-12-18 10:08:08 -080065// U8 Attribute.
66
repo sync12cca802012-12-19 17:34:22 -080067bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080068 Nl80211Attribute *attribute = GetAttribute(id);
69 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080070 return false;
repo sync1538d442012-12-20 15:24:35 -080071 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080072}
73
repo sync12cca802012-12-19 17:34:22 -080074bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
75 if (ContainsKey(attributes_, id)) {
76 LOG(ERROR) << "Trying to re-add attribute: " << id;
77 return false;
78 }
repo sync1538d442012-12-20 15:24:35 -080079 attributes_[id] = AttributePointer(
80 new Nl80211U8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080081 return true;
82}
83
84bool AttributeList::SetU8AttributeValue(int id, uint8_t value) const {
repo sync1538d442012-12-20 15:24:35 -080085 Nl80211Attribute *attribute = GetAttribute(id);
86 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080087 return false;
repo sync1538d442012-12-20 15:24:35 -080088 return attribute->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080089}
90
91
repo sync90ee0fa2012-12-18 10:08:08 -080092// U16 Attribute.
93
repo sync12cca802012-12-19 17:34:22 -080094bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080095 Nl80211Attribute *attribute = GetAttribute(id);
96 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080097 return false;
repo sync1538d442012-12-20 15:24:35 -080098 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080099}
100
repo sync12cca802012-12-19 17:34:22 -0800101bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
102 if (ContainsKey(attributes_, id)) {
103 LOG(ERROR) << "Trying to re-add attribute: " << id;
104 return false;
105 }
repo sync1538d442012-12-20 15:24:35 -0800106 attributes_[id] = AttributePointer(
107 new Nl80211U16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800108 return true;
109}
110
111bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800112 Nl80211Attribute *attribute = GetAttribute(id);
113 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800114 return false;
repo sync1538d442012-12-20 15:24:35 -0800115 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800116}
117
repo sync90ee0fa2012-12-18 10:08:08 -0800118// U32 Attribute.
119
repo sync12cca802012-12-19 17:34:22 -0800120bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800121 Nl80211Attribute *attribute = GetAttribute(id);
122 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800123 return false;
repo sync1538d442012-12-20 15:24:35 -0800124 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800125}
126
repo sync12cca802012-12-19 17:34:22 -0800127bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
128 if (ContainsKey(attributes_, id)) {
129 LOG(ERROR) << "Trying to re-add attribute: " << id;
130 return false;
131 }
repo sync1538d442012-12-20 15:24:35 -0800132 attributes_[id] = AttributePointer(
133 new Nl80211U32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800134 return true;
135}
136
137bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800138 Nl80211Attribute *attribute = GetAttribute(id);
139 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800140 return false;
repo sync1538d442012-12-20 15:24:35 -0800141 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800142}
143
repo sync90ee0fa2012-12-18 10:08:08 -0800144// U64 Attribute.
145
repo sync12cca802012-12-19 17:34:22 -0800146bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800147 Nl80211Attribute *attribute = GetAttribute(id);
148 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800149 return false;
repo sync1538d442012-12-20 15:24:35 -0800150 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800151}
152
repo sync12cca802012-12-19 17:34:22 -0800153bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
154 if (ContainsKey(attributes_, id)) {
155 LOG(ERROR) << "Trying to re-add attribute: " << id;
156 return false;
157 }
repo sync1538d442012-12-20 15:24:35 -0800158 attributes_[id] = AttributePointer(
159 new Nl80211U64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800160 return true;
161}
162
163bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800164 Nl80211Attribute *attribute = GetAttribute(id);
165 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800166 return false;
repo sync1538d442012-12-20 15:24:35 -0800167 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800168}
169
repo sync90ee0fa2012-12-18 10:08:08 -0800170// Flag Attribute.
171
repo sync12cca802012-12-19 17:34:22 -0800172bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
repo sync1538d442012-12-20 15:24:35 -0800173 Nl80211Attribute *attribute = GetAttribute(id);
174 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800175 return false;
repo sync1538d442012-12-20 15:24:35 -0800176 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800177}
178
repo sync12cca802012-12-19 17:34:22 -0800179bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
180 if (ContainsKey(attributes_, id)) {
181 LOG(ERROR) << "Trying to re-add attribute: " << id;
182 return false;
183 }
repo sync1538d442012-12-20 15:24:35 -0800184 attributes_[id] = AttributePointer(
185 new Nl80211FlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800186 return true;
187}
repo sync90ee0fa2012-12-18 10:08:08 -0800188
repo sync12cca802012-12-19 17:34:22 -0800189bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
repo sync1538d442012-12-20 15:24:35 -0800190 Nl80211Attribute *attribute = GetAttribute(id);
191 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800192 return false;
repo sync1538d442012-12-20 15:24:35 -0800193 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800194}
195
196bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800197 bool flag;
198 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800199 return false;
200 }
201 return flag;
202}
203
204// String Attribute.
205
repo sync12cca802012-12-19 17:34:22 -0800206bool AttributeList::GetStringAttributeValue(int id, string *value) const {
repo sync1538d442012-12-20 15:24:35 -0800207 Nl80211Attribute *attribute = GetAttribute(id);
208 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800209 return false;
repo sync1538d442012-12-20 15:24:35 -0800210 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800211}
212
repo sync12cca802012-12-19 17:34:22 -0800213bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
214 if (ContainsKey(attributes_, id)) {
215 LOG(ERROR) << "Trying to re-add attribute: " << id;
216 return false;
217 }
repo sync1538d442012-12-20 15:24:35 -0800218 attributes_[id] = AttributePointer(
219 new Nl80211StringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800220 return true;
221}
222
223bool AttributeList::SetStringAttributeValue(int id, string value) const {
repo sync1538d442012-12-20 15:24:35 -0800224 Nl80211Attribute *attribute = GetAttribute(id);
225 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800226 return false;
repo sync1538d442012-12-20 15:24:35 -0800227 return attribute->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800228}
229
230// Nested Attribute.
231
232bool AttributeList::GetNestedAttributeValue(
233 int id, WeakPtr<AttributeList> *value) const {
repo sync1538d442012-12-20 15:24:35 -0800234 Nl80211Attribute *attribute = GetAttribute(id);
235 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800236 return false;
repo sync1538d442012-12-20 15:24:35 -0800237 return attribute->GetNestedValue(value);
repo sync12cca802012-12-19 17:34:22 -0800238}
239
240bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
241 if (ContainsKey(attributes_, id)) {
242 LOG(ERROR) << "Trying to re-add attribute: " << id;
243 return false;
244 }
repo sync1538d442012-12-20 15:24:35 -0800245 attributes_[id] = AttributePointer(
246 new Nl80211NestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800247 return true;
248}
249
repo sync90ee0fa2012-12-18 10:08:08 -0800250// Raw Attribute.
251
repo sync1538d442012-12-20 15:24:35 -0800252bool AttributeList::GetRawAttributeValue(int id,
253 ByteString *output) const {
254 Nl80211Attribute *attribute = GetAttribute(id);
255 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800256 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800257
258 ByteString raw_value;
259
repo sync1538d442012-12-20 15:24:35 -0800260 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800261 return false;
262
263 if (output) {
264 const nlattr *const_data =
265 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
266 // nla_data and nla_len don't change their parameters but don't declare
267 // them to be const. Hence the cast.
268 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
269 *output = ByteString(
270 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
271 nla_len(data_nlattr));
272 }
273 return true;
274}
275
repo sync1538d442012-12-20 15:24:35 -0800276const Nl80211RawAttribute *AttributeList::GetRawAttribute(
277 int id) const {
278 if (!HasRawAttribute(id)) {
repo sync12cca802012-12-19 17:34:22 -0800279 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
280 return NULL;
281 }
repo sync90ee0fa2012-12-18 10:08:08 -0800282 const Nl80211RawAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800283 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800284 return attr;
285}
286
repo sync12cca802012-12-19 17:34:22 -0800287Nl80211Attribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800288 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800289 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800290 if (i == attributes_.end()) {
291 return NULL;
292 }
repo sync1538d442012-12-20 15:24:35 -0800293 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800294}
295
repo sync1538d442012-12-20 15:24:35 -0800296bool AttributeList::HasRawAttribute(int id) const {
297 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800298 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800299 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800300 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800301 return false;
302 }
repo sync1538d442012-12-20 15:24:35 -0800303 return (i->second->datatype() == Nl80211Attribute::kTypeRaw) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800304}
305
306
307} // namespace shill