blob: dd61ff8f576842f6e8f0cff55db903b31b676765 [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>
17
18#include "shill/logging.h"
19#include "shill/nl80211_attribute.h"
20#include "shill/scope_logger.h"
21
repo sync12cca802012-12-19 17:34:22 -080022using base::WeakPtr;
repo sync90ee0fa2012-12-18 10:08:08 -080023using std::map;
repo sync12cca802012-12-19 17:34:22 -080024using std::string;
repo sync90ee0fa2012-12-18 10:08:08 -080025
26namespace shill {
27
28AttributeList::~AttributeList() {
29 map<int, Nl80211Attribute *>::iterator i;
30 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
31 delete i->second;
32 }
33}
34
repo sync12cca802012-12-19 17:34:22 -080035bool AttributeList::CreateAttribute(nl80211_attrs id) {
36 if (ContainsKey(attributes_, id)) {
37 LOG(ERROR) << "Trying to re-add attribute: " << id;
repo sync90ee0fa2012-12-18 10:08:08 -080038 return false;
39 }
repo sync12cca802012-12-19 17:34:22 -080040 attributes_[id] = Nl80211Attribute::NewFromName(id);
repo sync90ee0fa2012-12-18 10:08:08 -080041 return true;
42}
43
repo sync12cca802012-12-19 17:34:22 -080044bool AttributeList::CreateAndInitFromNlAttr(nl80211_attrs id,
repo sync90ee0fa2012-12-18 10:08:08 -080045 const nlattr *data) {
repo sync12cca802012-12-19 17:34:22 -080046 if (!CreateAttribute(id)) {
repo sync90ee0fa2012-12-18 10:08:08 -080047 return false;
48 }
repo sync12cca802012-12-19 17:34:22 -080049 return attributes_[id]->InitFromNlAttr(data);
repo sync90ee0fa2012-12-18 10:08:08 -080050}
51
52// U8 Attribute.
53
repo sync12cca802012-12-19 17:34:22 -080054bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
55 if (!HasAttribute(id, Nl80211Attribute::kTypeU8)) {
56 LOG(ERROR) << "No attribute " << id << " of type kTypeU8 exists.";
57 return false;
58 }
repo sync90ee0fa2012-12-18 10:08:08 -080059 const Nl80211U8Attribute *attr =
repo sync12cca802012-12-19 17:34:22 -080060 reinterpret_cast<const Nl80211U8Attribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -080061 return attr->GetU8Value(value);
62}
63
repo sync12cca802012-12-19 17:34:22 -080064bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
65 if (ContainsKey(attributes_, id)) {
66 LOG(ERROR) << "Trying to re-add attribute: " << id;
67 return false;
68 }
69 attributes_[id] = new Nl80211U8Attribute(id, id_string);
70 return true;
71}
72
73bool AttributeList::SetU8AttributeValue(int id, uint8_t value) const {
74 if (!HasAttribute(id, Nl80211Attribute::kTypeU8)) {
75 LOG(ERROR) << "No attribute " << id << " of type kTypeU8 exists.";
76 return false;
77 }
78 Nl80211U8Attribute *attr =
79 reinterpret_cast<Nl80211U8Attribute *>(GetAttribute(id));
80 return attr->SetU8Value(value);
81}
82
83
repo sync90ee0fa2012-12-18 10:08:08 -080084// U16 Attribute.
85
repo sync12cca802012-12-19 17:34:22 -080086bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
87 if (!HasAttribute(id, Nl80211Attribute::kTypeU16)) {
88 LOG(ERROR) << "No attribute " << id << " of type kTypeU16 exists.";
89 return false;
90 }
repo sync90ee0fa2012-12-18 10:08:08 -080091 const Nl80211U16Attribute *attr =
repo sync12cca802012-12-19 17:34:22 -080092 reinterpret_cast<const Nl80211U16Attribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -080093 return attr->GetU16Value(value);
94}
95
repo sync12cca802012-12-19 17:34:22 -080096bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
97 if (ContainsKey(attributes_, id)) {
98 LOG(ERROR) << "Trying to re-add attribute: " << id;
99 return false;
100 }
101 attributes_[id] = new Nl80211U16Attribute(id, id_string);
102 return true;
103}
104
105bool AttributeList::SetU16AttributeValue(int id, uint16_t value) const {
106 if (!HasAttribute(id, Nl80211Attribute::kTypeU16)) {
107 LOG(ERROR) << "No attribute " << id << " of type kTypeU16 exists.";
108 return false;
109 }
110 Nl80211U16Attribute *attr =
111 reinterpret_cast<Nl80211U16Attribute *>(GetAttribute(id));
112 return attr->SetU16Value(value);
113}
114
repo sync90ee0fa2012-12-18 10:08:08 -0800115// U32 Attribute.
116
repo sync12cca802012-12-19 17:34:22 -0800117bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
118 if (!HasAttribute(id, Nl80211Attribute::kTypeU32)) {
119 LOG(ERROR) << "No attribute " << id << " of type kTypeU32 exists.";
120 return false;
121 }
repo sync90ee0fa2012-12-18 10:08:08 -0800122 const Nl80211U32Attribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800123 reinterpret_cast<const Nl80211U32Attribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800124 return attr->GetU32Value(value);
125}
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 }
132 attributes_[id] = new Nl80211U32Attribute(id, id_string);
133 return true;
134}
135
136bool AttributeList::SetU32AttributeValue(int id, uint32_t value) const {
137 if (!HasAttribute(id, Nl80211Attribute::kTypeU32)) {
138 LOG(ERROR) << "No attribute " << id << " of type kTypeU32 exists.";
139 return false;
140 }
141 Nl80211U32Attribute *attr =
142 reinterpret_cast<Nl80211U32Attribute *>(GetAttribute(id));
143 return attr->SetU32Value(value);
144}
145
repo sync90ee0fa2012-12-18 10:08:08 -0800146// U64 Attribute.
147
repo sync12cca802012-12-19 17:34:22 -0800148bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
149 if (!HasAttribute(id, Nl80211Attribute::kTypeU64)) {
150 LOG(ERROR) << "No attribute " << id << " of type kTypeU64 exists.";
151 return false;
152 }
repo sync90ee0fa2012-12-18 10:08:08 -0800153 const Nl80211U64Attribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800154 reinterpret_cast<const Nl80211U64Attribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800155 return attr->GetU64Value(value);
156}
157
repo sync12cca802012-12-19 17:34:22 -0800158bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
159 if (ContainsKey(attributes_, id)) {
160 LOG(ERROR) << "Trying to re-add attribute: " << id;
161 return false;
162 }
163 attributes_[id] = new Nl80211U64Attribute(id, id_string);
164 return true;
165}
166
167bool AttributeList::SetU64AttributeValue(int id, uint64_t value) const {
168 if (!HasAttribute(id, Nl80211Attribute::kTypeU64)) {
169 LOG(ERROR) << "No attribute " << id << " of type kTypeU64 exists.";
170 return false;
171 }
172 Nl80211U64Attribute *attr =
173 reinterpret_cast<Nl80211U64Attribute *>(GetAttribute(id));
174 return attr->SetU64Value(value);
175}
176
repo sync90ee0fa2012-12-18 10:08:08 -0800177// Flag Attribute.
178
repo sync12cca802012-12-19 17:34:22 -0800179bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
180 if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
181 LOG(ERROR) << "No attribute " << id << " of type kTypeFlag exists.";
182 return false;
183 }
repo sync90ee0fa2012-12-18 10:08:08 -0800184 const Nl80211FlagAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800185 reinterpret_cast<const Nl80211FlagAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800186 return attr->GetFlagValue(value);
187}
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 }
194 attributes_[id] = new Nl80211FlagAttribute(id, id_string);
195 return true;
196}
repo sync90ee0fa2012-12-18 10:08:08 -0800197
repo sync12cca802012-12-19 17:34:22 -0800198bool AttributeList::SetFlagAttributeValue(int id, bool value) const {
199 if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
200 LOG(ERROR) << "No attribute " << id << " of type kTypeFlag exists.";
201 return false;
202 }
203 Nl80211FlagAttribute *attr =
204 reinterpret_cast<Nl80211FlagAttribute *>(GetAttribute(id));
205 return attr->SetFlagValue(value);
206}
207
208bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync90ee0fa2012-12-18 10:08:08 -0800209 // TODO(wdg): After message constructors add attributes, remove the following
210 // lines.
repo sync12cca802012-12-19 17:34:22 -0800211 if (!HasAttribute(id, Nl80211Attribute::kTypeFlag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800212 return false;
213 }
214
repo sync12cca802012-12-19 17:34:22 -0800215 bool flag;
216 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800217 return false;
218 }
219 return flag;
220}
221
222// String Attribute.
223
repo sync12cca802012-12-19 17:34:22 -0800224bool AttributeList::GetStringAttributeValue(int id, string *value) const {
225 if (!HasAttribute(id, Nl80211Attribute::kTypeString)) {
226 LOG(ERROR) << "No attribute " << id << " of type kTypeString exists.";
227 return false;
228 }
repo sync90ee0fa2012-12-18 10:08:08 -0800229 const Nl80211StringAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800230 reinterpret_cast<const Nl80211StringAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800231 return attr->GetStringValue(value);
232}
233
repo sync12cca802012-12-19 17:34:22 -0800234bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
235 if (ContainsKey(attributes_, id)) {
236 LOG(ERROR) << "Trying to re-add attribute: " << id;
237 return false;
238 }
239 attributes_[id] = new Nl80211StringAttribute(id, id_string);
240 return true;
241}
242
243bool AttributeList::SetStringAttributeValue(int id, string value) const {
244 if (!HasAttribute(id, Nl80211Attribute::kTypeString)) {
245 LOG(ERROR) << "No attribute " << id << " of type kTypeString exists.";
246 return false;
247 }
248 Nl80211StringAttribute *attr =
249 reinterpret_cast<Nl80211StringAttribute *>(GetAttribute(id));
250 return attr->SetStringValue(value);
251}
252
253// Nested Attribute.
254
255bool AttributeList::GetNestedAttributeValue(
256 int id, WeakPtr<AttributeList> *value) const {
257 if (!HasAttribute(id, Nl80211Attribute::kTypeNested)) {
258 LOG(ERROR) << "No attribute " << id << " of type kTypeNested exists.";
259 return false;
260 }
261 Nl80211NestedAttribute *attr =
262 reinterpret_cast<Nl80211NestedAttribute *>(GetAttribute(id));
263 return attr->GetNestedValue(value);
264}
265
266bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
267 if (ContainsKey(attributes_, id)) {
268 LOG(ERROR) << "Trying to re-add attribute: " << id;
269 return false;
270 }
271 attributes_[id] = new Nl80211NestedAttribute(id, id_string);
272 return true;
273}
274
repo sync90ee0fa2012-12-18 10:08:08 -0800275// Raw Attribute.
276
repo sync12cca802012-12-19 17:34:22 -0800277bool AttributeList::GetRawAttributeValue(int id, ByteString *output) const {
278 if (!HasAttribute(id, Nl80211Attribute::kTypeRaw)) {
279 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
280 return false;
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
285 ByteString raw_value;
286
287 if (!attr->GetRawValue(&raw_value))
288 return false;
289
290 if (output) {
291 const nlattr *const_data =
292 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
293 // nla_data and nla_len don't change their parameters but don't declare
294 // them to be const. Hence the cast.
295 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
296 *output = ByteString(
297 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
298 nla_len(data_nlattr));
299 }
300 return true;
301}
302
repo sync12cca802012-12-19 17:34:22 -0800303const Nl80211RawAttribute *AttributeList::GetRawAttribute(int id) const {
304 if (!HasAttribute(id, Nl80211Attribute::kTypeRaw)) {
305 LOG(ERROR) << "No attribute " << id << " of type kTypeRaw exists.";
306 return NULL;
307 }
repo sync90ee0fa2012-12-18 10:08:08 -0800308 const Nl80211RawAttribute *attr =
repo sync12cca802012-12-19 17:34:22 -0800309 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(id));
repo sync90ee0fa2012-12-18 10:08:08 -0800310 return attr;
311}
312
repo sync12cca802012-12-19 17:34:22 -0800313Nl80211Attribute *AttributeList::GetAttribute(int id) const {
repo sync90ee0fa2012-12-18 10:08:08 -0800314 map<int, Nl80211Attribute *>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800315 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800316 if (i == attributes_.end()) {
317 return NULL;
318 }
319 return i->second;
320}
321
repo sync12cca802012-12-19 17:34:22 -0800322bool AttributeList::HasAttribute(int id,
323 Nl80211Attribute::Type datatype) const {
repo sync90ee0fa2012-12-18 10:08:08 -0800324 map<int, Nl80211Attribute *>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800325 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800326 if (i == attributes_.end()) {
repo sync12cca802012-12-19 17:34:22 -0800327 LOG(ERROR) << "FALSE - Didn't find id " << id;
repo sync90ee0fa2012-12-18 10:08:08 -0800328 return false;
329 }
repo sync12cca802012-12-19 17:34:22 -0800330 return (i->second->datatype() == datatype) ? true : false;
repo sync90ee0fa2012-12-18 10:08:08 -0800331}
332
333
334} // namespace shill