blob: 793f83e30208b3022faafd0289d558b205c1ac5a [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;
Wade Guthrie3af8b4d2013-01-10 08:39:30 -080053 if (i->second->has_a_value()) {
54 i->second->ToString(&attribute_string);
55 StringAppendF(&output, " Attr: %s(%d) Type: %s = %s\n",
56 i->second->id_string(),
57 i->second->id(),
58 i->second->datatype_string(),
59 attribute_string.c_str());
60 }
repo sync1538d442012-12-20 15:24:35 -080061 }
62 return output;
63}
64
repo syncdc085c82012-12-28 08:54:41 -080065ByteString AttributeList::Encode() const {
66 ByteString result;
67 map<int, AttributePointer>::const_iterator i;
68
69 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
70 result.Append(i->second->Encode());
71 }
72 return result;
73}
74
repo sync90ee0fa2012-12-18 10:08:08 -080075// U8 Attribute.
76
repo sync12cca802012-12-19 17:34:22 -080077bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
repo sync1538d442012-12-20 15:24:35 -080078 Nl80211Attribute *attribute = GetAttribute(id);
79 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080080 return false;
repo sync1538d442012-12-20 15:24:35 -080081 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080082}
83
repo sync12cca802012-12-19 17:34:22 -080084bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
85 if (ContainsKey(attributes_, id)) {
86 LOG(ERROR) << "Trying to re-add attribute: " << id;
87 return false;
88 }
repo sync1538d442012-12-20 15:24:35 -080089 attributes_[id] = AttributePointer(
90 new Nl80211U8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080091 return true;
92}
93
94bool AttributeList::SetU8AttributeValue(int id, uint8_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->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080099}
100
101
repo sync90ee0fa2012-12-18 10:08:08 -0800102// U16 Attribute.
103
repo sync12cca802012-12-19 17:34:22 -0800104bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800105 Nl80211Attribute *attribute = GetAttribute(id);
106 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800107 return false;
repo sync1538d442012-12-20 15:24:35 -0800108 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800109}
110
repo sync12cca802012-12-19 17:34:22 -0800111bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
112 if (ContainsKey(attributes_, id)) {
113 LOG(ERROR) << "Trying to re-add attribute: " << id;
114 return false;
115 }
repo sync1538d442012-12-20 15:24:35 -0800116 attributes_[id] = AttributePointer(
117 new Nl80211U16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800118 return true;
119}
120
121bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800122 Nl80211Attribute *attribute = GetAttribute(id);
123 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800124 return false;
repo sync1538d442012-12-20 15:24:35 -0800125 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800126}
127
repo sync90ee0fa2012-12-18 10:08:08 -0800128// U32 Attribute.
129
repo sync12cca802012-12-19 17:34:22 -0800130bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800131 Nl80211Attribute *attribute = GetAttribute(id);
132 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800133 return false;
repo sync1538d442012-12-20 15:24:35 -0800134 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800135}
136
repo sync12cca802012-12-19 17:34:22 -0800137bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
138 if (ContainsKey(attributes_, id)) {
139 LOG(ERROR) << "Trying to re-add attribute: " << id;
140 return false;
141 }
repo sync1538d442012-12-20 15:24:35 -0800142 attributes_[id] = AttributePointer(
143 new Nl80211U32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800144 return true;
145}
146
147bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800148 Nl80211Attribute *attribute = GetAttribute(id);
149 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800150 return false;
repo sync1538d442012-12-20 15:24:35 -0800151 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800152}
153
repo sync90ee0fa2012-12-18 10:08:08 -0800154// U64 Attribute.
155
repo sync12cca802012-12-19 17:34:22 -0800156bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
repo sync1538d442012-12-20 15:24:35 -0800157 Nl80211Attribute *attribute = GetAttribute(id);
158 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800159 return false;
repo sync1538d442012-12-20 15:24:35 -0800160 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800161}
162
repo sync12cca802012-12-19 17:34:22 -0800163bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
164 if (ContainsKey(attributes_, id)) {
165 LOG(ERROR) << "Trying to re-add attribute: " << id;
166 return false;
167 }
repo sync1538d442012-12-20 15:24:35 -0800168 attributes_[id] = AttributePointer(
169 new Nl80211U64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800170 return true;
171}
172
173bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
repo sync1538d442012-12-20 15:24:35 -0800174 Nl80211Attribute *attribute = GetAttribute(id);
175 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800176 return false;
repo sync1538d442012-12-20 15:24:35 -0800177 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800178}
179
repo sync90ee0fa2012-12-18 10:08:08 -0800180// Flag Attribute.
181
repo sync12cca802012-12-19 17:34:22 -0800182bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
repo sync1538d442012-12-20 15:24:35 -0800183 Nl80211Attribute *attribute = GetAttribute(id);
184 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800185 return false;
repo sync1538d442012-12-20 15:24:35 -0800186 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800187}
188
repo sync12cca802012-12-19 17:34:22 -0800189bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
190 if (ContainsKey(attributes_, id)) {
191 LOG(ERROR) << "Trying to re-add attribute: " << id;
192 return false;
193 }
repo sync1538d442012-12-20 15:24:35 -0800194 attributes_[id] = AttributePointer(
195 new Nl80211FlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800196 return true;
197}
repo sync90ee0fa2012-12-18 10:08:08 -0800198
repo sync12cca802012-12-19 17:34:22 -0800199bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
repo sync1538d442012-12-20 15:24:35 -0800200 Nl80211Attribute *attribute = GetAttribute(id);
201 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800202 return false;
repo sync1538d442012-12-20 15:24:35 -0800203 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800204}
205
206bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800207 bool flag;
208 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800209 return false;
210 }
211 return flag;
212}
213
214// String Attribute.
215
repo sync12cca802012-12-19 17:34:22 -0800216bool AttributeList::GetStringAttributeValue(int id, string *value) const {
repo sync1538d442012-12-20 15:24:35 -0800217 Nl80211Attribute *attribute = GetAttribute(id);
218 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800219 return false;
repo sync1538d442012-12-20 15:24:35 -0800220 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800221}
222
repo sync12cca802012-12-19 17:34:22 -0800223bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
224 if (ContainsKey(attributes_, id)) {
225 LOG(ERROR) << "Trying to re-add attribute: " << id;
226 return false;
227 }
repo sync1538d442012-12-20 15:24:35 -0800228 attributes_[id] = AttributePointer(
229 new Nl80211StringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800230 return true;
231}
232
233bool AttributeList::SetStringAttributeValue(int id, string 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->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800238}
239
240// Nested Attribute.
241
242bool AttributeList::GetNestedAttributeValue(
243 int id, WeakPtr<AttributeList> *value) const {
repo sync1538d442012-12-20 15:24:35 -0800244 Nl80211Attribute *attribute = GetAttribute(id);
245 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800246 return false;
repo sync1538d442012-12-20 15:24:35 -0800247 return attribute->GetNestedValue(value);
repo sync12cca802012-12-19 17:34:22 -0800248}
249
250bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
251 if (ContainsKey(attributes_, id)) {
252 LOG(ERROR) << "Trying to re-add attribute: " << id;
253 return false;
254 }
repo sync1538d442012-12-20 15:24:35 -0800255 attributes_[id] = AttributePointer(
256 new Nl80211NestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800257 return true;
258}
259
repo sync90ee0fa2012-12-18 10:08:08 -0800260// Raw Attribute.
261
repo sync1538d442012-12-20 15:24:35 -0800262bool AttributeList::GetRawAttributeValue(int id,
263 ByteString *output) const {
264 Nl80211Attribute *attribute = GetAttribute(id);
265 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800266 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800267
268 ByteString raw_value;
269
repo sync1538d442012-12-20 15:24:35 -0800270 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800271 return false;
272
273 if (output) {
274 const nlattr *const_data =
275 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
276 // nla_data and nla_len don't change their parameters but don't declare
277 // them to be const. Hence the cast.
278 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
279 *output = ByteString(
280 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
281 nla_len(data_nlattr));
282 }
283 return true;
284}
285
repo sync1538d442012-12-20 15:24:35 -0800286const Nl80211RawAttribute *AttributeList::GetRawAttribute(
287 int id) const {
288 if (!HasRawAttribute(id)) {
repo sync12cca802012-12-19 17:34:22 -0800289 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
290 return NULL;
291 }
repo sync90ee0fa2012-12-18 10:08:08 -0800292 const Nl80211RawAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800293 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800294 return attr;
295}
296
repo sync12cca802012-12-19 17:34:22 -0800297Nl80211Attribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800298 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800299 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800300 if (i == attributes_.end()) {
301 return NULL;
302 }
repo sync1538d442012-12-20 15:24:35 -0800303 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800304}
305
repo sync1538d442012-12-20 15:24:35 -0800306bool AttributeList::HasRawAttribute(int id) const {
307 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800308 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800309 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800310 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800311 return false;
312 }
repo sync1538d442012-12-20 15:24:35 -0800313 return (i->second->datatype() == Nl80211Attribute::kTypeRaw) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800314}
315
316
317} // namespace shill