blob: e57f734ed703d95a07f52dd386da84747761e9e5 [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 syncdc085c82012-12-28 08:54:41 -080063ByteString AttributeList::Encode() const {
64 ByteString result;
65 map<int, AttributePointer>::const_iterator i;
66
67 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
68 result.Append(i->second->Encode());
69 }
70 return result;
71}
72
repo sync90ee0fa2012-12-18 10:08:08 -080073// U8 Attribute.
74
repo sync12cca802012-12-19 17:34:22 -080075bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080076 Nl80211Attribute *attribute = GetAttribute(id);
77 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080078 return false;
repo sync1538d442012-12-20 15:24:35 -080079 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080080}
81
repo sync12cca802012-12-19 17:34:22 -080082bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
83 if (ContainsKey(attributes_, id)) {
84 LOG(ERROR) << "Trying to re-add attribute: " << id;
85 return false;
86 }
repo sync1538d442012-12-20 15:24:35 -080087 attributes_[id] = AttributePointer(
88 new Nl80211U8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080089 return true;
90}
91
92bool AttributeList::SetU8AttributeValue(int id, uint8_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->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080097}
98
99
repo sync90ee0fa2012-12-18 10:08:08 -0800100// U16 Attribute.
101
repo sync12cca802012-12-19 17:34:22 -0800102bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800103 Nl80211Attribute *attribute = GetAttribute(id);
104 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800105 return false;
repo sync1538d442012-12-20 15:24:35 -0800106 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800107}
108
repo sync12cca802012-12-19 17:34:22 -0800109bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
110 if (ContainsKey(attributes_, id)) {
111 LOG(ERROR) << "Trying to re-add attribute: " << id;
112 return false;
113 }
repo sync1538d442012-12-20 15:24:35 -0800114 attributes_[id] = AttributePointer(
115 new Nl80211U16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800116 return true;
117}
118
119bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800120 Nl80211Attribute *attribute = GetAttribute(id);
121 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800122 return false;
repo sync1538d442012-12-20 15:24:35 -0800123 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800124}
125
repo sync90ee0fa2012-12-18 10:08:08 -0800126// U32 Attribute.
127
repo sync12cca802012-12-19 17:34:22 -0800128bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800129 Nl80211Attribute *attribute = GetAttribute(id);
130 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800131 return false;
repo sync1538d442012-12-20 15:24:35 -0800132 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800133}
134
repo sync12cca802012-12-19 17:34:22 -0800135bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
136 if (ContainsKey(attributes_, id)) {
137 LOG(ERROR) << "Trying to re-add attribute: " << id;
138 return false;
139 }
repo sync1538d442012-12-20 15:24:35 -0800140 attributes_[id] = AttributePointer(
141 new Nl80211U32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800142 return true;
143}
144
145bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800146 Nl80211Attribute *attribute = GetAttribute(id);
147 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800148 return false;
repo sync1538d442012-12-20 15:24:35 -0800149 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800150}
151
repo sync90ee0fa2012-12-18 10:08:08 -0800152// U64 Attribute.
153
repo sync12cca802012-12-19 17:34:22 -0800154bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800155 Nl80211Attribute *attribute = GetAttribute(id);
156 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800157 return false;
repo sync1538d442012-12-20 15:24:35 -0800158 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800159}
160
repo sync12cca802012-12-19 17:34:22 -0800161bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
162 if (ContainsKey(attributes_, id)) {
163 LOG(ERROR) << "Trying to re-add attribute: " << id;
164 return false;
165 }
repo sync1538d442012-12-20 15:24:35 -0800166 attributes_[id] = AttributePointer(
167 new Nl80211U64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800168 return true;
169}
170
171bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800172 Nl80211Attribute *attribute = GetAttribute(id);
173 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800174 return false;
repo sync1538d442012-12-20 15:24:35 -0800175 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800176}
177
repo sync90ee0fa2012-12-18 10:08:08 -0800178// Flag Attribute.
179
repo sync12cca802012-12-19 17:34:22 -0800180bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
repo sync1538d442012-12-20 15:24:35 -0800181 Nl80211Attribute *attribute = GetAttribute(id);
182 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800183 return false;
repo sync1538d442012-12-20 15:24:35 -0800184 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800185}
186
repo sync12cca802012-12-19 17:34:22 -0800187bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
188 if (ContainsKey(attributes_, id)) {
189 LOG(ERROR) << "Trying to re-add attribute: " << id;
190 return false;
191 }
repo sync1538d442012-12-20 15:24:35 -0800192 attributes_[id] = AttributePointer(
193 new Nl80211FlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800194 return true;
195}
repo sync90ee0fa2012-12-18 10:08:08 -0800196
repo sync12cca802012-12-19 17:34:22 -0800197bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
repo sync1538d442012-12-20 15:24:35 -0800198 Nl80211Attribute *attribute = GetAttribute(id);
199 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800200 return false;
repo sync1538d442012-12-20 15:24:35 -0800201 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800202}
203
204bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800205 bool flag;
206 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800207 return false;
208 }
209 return flag;
210}
211
212// String Attribute.
213
repo sync12cca802012-12-19 17:34:22 -0800214bool AttributeList::GetStringAttributeValue(int id, string *value) const {
repo sync1538d442012-12-20 15:24:35 -0800215 Nl80211Attribute *attribute = GetAttribute(id);
216 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800217 return false;
repo sync1538d442012-12-20 15:24:35 -0800218 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800219}
220
repo sync12cca802012-12-19 17:34:22 -0800221bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
222 if (ContainsKey(attributes_, id)) {
223 LOG(ERROR) << "Trying to re-add attribute: " << id;
224 return false;
225 }
repo sync1538d442012-12-20 15:24:35 -0800226 attributes_[id] = AttributePointer(
227 new Nl80211StringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800228 return true;
229}
230
231bool AttributeList::SetStringAttributeValue(int id, string 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->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800236}
237
238// Nested Attribute.
239
240bool AttributeList::GetNestedAttributeValue(
241 int id, WeakPtr<AttributeList> *value) const {
repo sync1538d442012-12-20 15:24:35 -0800242 Nl80211Attribute *attribute = GetAttribute(id);
243 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800244 return false;
repo sync1538d442012-12-20 15:24:35 -0800245 return attribute->GetNestedValue(value);
repo sync12cca802012-12-19 17:34:22 -0800246}
247
248bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
249 if (ContainsKey(attributes_, id)) {
250 LOG(ERROR) << "Trying to re-add attribute: " << id;
251 return false;
252 }
repo sync1538d442012-12-20 15:24:35 -0800253 attributes_[id] = AttributePointer(
254 new Nl80211NestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800255 return true;
256}
257
repo sync90ee0fa2012-12-18 10:08:08 -0800258// Raw Attribute.
259
repo sync1538d442012-12-20 15:24:35 -0800260bool AttributeList::GetRawAttributeValue(int id,
261 ByteString *output) const {
262 Nl80211Attribute *attribute = GetAttribute(id);
263 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800264 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800265
266 ByteString raw_value;
267
repo sync1538d442012-12-20 15:24:35 -0800268 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800269 return false;
270
271 if (output) {
272 const nlattr *const_data =
273 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
274 // nla_data and nla_len don't change their parameters but don't declare
275 // them to be const. Hence the cast.
276 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
277 *output = ByteString(
278 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
279 nla_len(data_nlattr));
280 }
281 return true;
282}
283
repo sync1538d442012-12-20 15:24:35 -0800284const Nl80211RawAttribute *AttributeList::GetRawAttribute(
285 int id) const {
286 if (!HasRawAttribute(id)) {
repo sync12cca802012-12-19 17:34:22 -0800287 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
288 return NULL;
289 }
repo sync90ee0fa2012-12-18 10:08:08 -0800290 const Nl80211RawAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800291 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800292 return attr;
293}
294
repo sync12cca802012-12-19 17:34:22 -0800295Nl80211Attribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800296 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800297 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800298 if (i == attributes_.end()) {
299 return NULL;
300 }
repo sync1538d442012-12-20 15:24:35 -0800301 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800302}
303
repo sync1538d442012-12-20 15:24:35 -0800304bool AttributeList::HasRawAttribute(int id) const {
305 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800306 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800307 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800308 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800309 return false;
310 }
repo sync1538d442012-12-20 15:24:35 -0800311 return (i->second->datatype() == Nl80211Attribute::kTypeRaw) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800312}
313
314
315} // namespace shill