blob: c6ad1d128ef680cdda8d1f1bcd820d7a71f1d151 [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"
Wade Guthrief162f8b2013-02-27 14:13:55 -080020#include "shill/netlink_attribute.h"
repo sync90ee0fa2012-12-18 10:08:08 -080021#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
Wade Guthrie68da97c2013-02-26 13:09:35 -080030bool AttributeList::CreateAttribute(
31 int id, AttributeList::NewFromIdMethod factory) {
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -070032 if (ContainsKey(attributes_, id)) {
Wade Guthrief788a0a2013-06-10 09:50:26 -070033 SLOG(WiFi, 7) << "Trying to re-add attribute " << id << ", not overwriting";
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -070034 return true;
35 }
Wade Guthrie68da97c2013-02-26 13:09:35 -080036 attributes_[id] = AttributePointer(factory.Run(id));
repo sync90ee0fa2012-12-18 10:08:08 -080037 return true;
38}
39
Wade Guthrie68da97c2013-02-26 13:09:35 -080040bool AttributeList::CreateAndInitAttribute(
41 int id, const nlattr *data, AttributeList::NewFromIdMethod factory) {
42 if (!CreateAttribute(id, factory)) {
repo sync90ee0fa2012-12-18 10:08:08 -080043 return false;
44 }
repo sync12cca802012-12-19 17:34:22 -080045 return attributes_[id]->InitFromNlAttr(data);
repo sync90ee0fa2012-12-18 10:08:08 -080046}
47
Wade Guthrie8e278612013-02-26 10:32:34 -080048void AttributeList::Print(int log_level, int indent) const {
repo sync1538d442012-12-20 15:24:35 -080049 map<int, AttributePointer>::const_iterator i;
50
51 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
Wade Guthrie8e278612013-02-26 10:32:34 -080052 i->second->Print(log_level, indent);
repo sync1538d442012-12-20 15:24:35 -080053 }
repo sync1538d442012-12-20 15:24:35 -080054}
55
repo syncdc085c82012-12-28 08:54:41 -080056ByteString AttributeList::Encode() const {
57 ByteString result;
58 map<int, AttributePointer>::const_iterator i;
59
60 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
61 result.Append(i->second->Encode());
62 }
63 return result;
64}
65
repo sync90ee0fa2012-12-18 10:08:08 -080066// U8 Attribute.
67
repo sync12cca802012-12-19 17:34:22 -080068bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080069 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080070 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080071 return false;
repo sync1538d442012-12-20 15:24:35 -080072 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080073}
74
repo sync12cca802012-12-19 17:34:22 -080075bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
76 if (ContainsKey(attributes_, id)) {
77 LOG(ERROR) << "Trying to re-add attribute: " << id;
78 return false;
79 }
repo sync1538d442012-12-20 15:24:35 -080080 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -080081 new NetlinkU8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080082 return true;
83}
84
Wade Guthrieefe1f0c2013-02-26 17:42:01 -080085bool AttributeList::SetU8AttributeValue(int id, uint8_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -080086 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080087 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080088 return false;
repo sync1538d442012-12-20 15:24:35 -080089 return attribute->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080090}
91
92
repo sync90ee0fa2012-12-18 10:08:08 -080093// U16 Attribute.
94
repo sync12cca802012-12-19 17:34:22 -080095bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080096 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080097 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080098 return false;
repo sync1538d442012-12-20 15:24:35 -080099 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800100}
101
repo sync12cca802012-12-19 17:34:22 -0800102bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
103 if (ContainsKey(attributes_, id)) {
104 LOG(ERROR) << "Trying to re-add attribute: " << id;
105 return false;
106 }
repo sync1538d442012-12-20 15:24:35 -0800107 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800108 new NetlinkU16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800109 return true;
110}
111
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800112bool AttributeList::SetU16AttributeValue(int id, uint16_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800113 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800114 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800115 return false;
repo sync1538d442012-12-20 15:24:35 -0800116 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800117}
118
repo sync90ee0fa2012-12-18 10:08:08 -0800119// U32 Attribute.
120
repo sync12cca802012-12-19 17:34:22 -0800121bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800122 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800123 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800124 return false;
repo sync1538d442012-12-20 15:24:35 -0800125 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800126}
127
repo sync12cca802012-12-19 17:34:22 -0800128bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
129 if (ContainsKey(attributes_, id)) {
130 LOG(ERROR) << "Trying to re-add attribute: " << id;
131 return false;
132 }
repo sync1538d442012-12-20 15:24:35 -0800133 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800134 new NetlinkU32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800135 return true;
136}
137
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800138bool AttributeList::SetU32AttributeValue(int id, uint32_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800139 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800140 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800141 return false;
repo sync1538d442012-12-20 15:24:35 -0800142 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800143}
144
repo sync90ee0fa2012-12-18 10:08:08 -0800145// U64 Attribute.
146
repo sync12cca802012-12-19 17:34:22 -0800147bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800148 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800149 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800150 return false;
repo sync1538d442012-12-20 15:24:35 -0800151 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800152}
153
repo sync12cca802012-12-19 17:34:22 -0800154bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
155 if (ContainsKey(attributes_, id)) {
156 LOG(ERROR) << "Trying to re-add attribute: " << id;
157 return false;
158 }
repo sync1538d442012-12-20 15:24:35 -0800159 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800160 new NetlinkU64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800161 return true;
162}
163
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800164bool AttributeList::SetU64AttributeValue(int id, uint64_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800165 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800166 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800167 return false;
repo sync1538d442012-12-20 15:24:35 -0800168 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800169}
170
repo sync90ee0fa2012-12-18 10:08:08 -0800171// Flag Attribute.
172
repo sync12cca802012-12-19 17:34:22 -0800173bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800174 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800175 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800176 return false;
repo sync1538d442012-12-20 15:24:35 -0800177 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800178}
179
repo sync12cca802012-12-19 17:34:22 -0800180bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
181 if (ContainsKey(attributes_, id)) {
182 LOG(ERROR) << "Trying to re-add attribute: " << id;
183 return false;
184 }
repo sync1538d442012-12-20 15:24:35 -0800185 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800186 new NetlinkFlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800187 return true;
188}
repo sync90ee0fa2012-12-18 10:08:08 -0800189
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800190bool AttributeList::SetFlagAttributeValue(int id, bool value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800191 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800192 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800193 return false;
repo sync1538d442012-12-20 15:24:35 -0800194 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800195}
196
197bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800198 bool flag;
199 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800200 return false;
201 }
202 return flag;
203}
204
205// String Attribute.
206
repo sync12cca802012-12-19 17:34:22 -0800207bool AttributeList::GetStringAttributeValue(int id, string *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800208 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800209 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800210 return false;
repo sync1538d442012-12-20 15:24:35 -0800211 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800212}
213
repo sync12cca802012-12-19 17:34:22 -0800214bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
215 if (ContainsKey(attributes_, id)) {
216 LOG(ERROR) << "Trying to re-add attribute: " << id;
217 return false;
218 }
repo sync1538d442012-12-20 15:24:35 -0800219 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800220 new NetlinkStringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800221 return true;
222}
223
Wade Guthrief54872f2013-04-11 15:11:50 -0700224bool AttributeList::CreateSsidAttribute(int id, const char *id_string) {
225 if (ContainsKey(attributes_, id)) {
226 LOG(ERROR) << "Trying to re-add attribute: " << id;
227 return false;
228 }
229 attributes_[id] = AttributePointer(
230 new NetlinkSsidAttribute(id, id_string));
231 return true;
232}
233
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800234bool AttributeList::SetStringAttributeValue(int id, string value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800235 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800236 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800237 return false;
repo sync1538d442012-12-20 15:24:35 -0800238 return attribute->SetStringValue(value);
repo sync12cca802012-12-19 17:34:22 -0800239}
240
241// Nested Attribute.
242
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800243bool AttributeList::GetNestedAttributeList(int id,
244 AttributeListRefPtr *value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800245 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800246 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800247 return false;
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800248 return attribute->GetNestedAttributeList(value);
249}
250
251bool AttributeList::ConstGetNestedAttributeList(
252 int id, AttributeListConstRefPtr *value) const {
253 NetlinkAttribute *attribute = GetAttribute(id);
254 if (!attribute)
255 return false;
256 return attribute->ConstGetNestedAttributeList(value);
257}
258
259bool AttributeList::SetNestedAttributeHasAValue(int id) {
260 NetlinkAttribute *attribute = GetAttribute(id);
261 if (!attribute)
262 return false;
263 return attribute->SetNestedHasAValue();
repo sync12cca802012-12-19 17:34:22 -0800264}
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 }
repo sync1538d442012-12-20 15:24:35 -0800271 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800272 new NetlinkNestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800273 return true;
274}
275
repo sync90ee0fa2012-12-18 10:08:08 -0800276// Raw Attribute.
277
repo sync1538d442012-12-20 15:24:35 -0800278bool AttributeList::GetRawAttributeValue(int id,
279 ByteString *output) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800280 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800281 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800282 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800283
284 ByteString raw_value;
285
repo sync1538d442012-12-20 15:24:35 -0800286 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800287 return false;
288
289 if (output) {
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800290 *output = raw_value;
repo sync90ee0fa2012-12-18 10:08:08 -0800291 }
292 return true;
293}
294
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800295bool AttributeList::SetRawAttributeValue(int id, ByteString value) {
296 NetlinkAttribute *attribute = GetAttribute(id);
297 if (!attribute)
298 return false;
299 return attribute->SetRawValue(value);
300}
301
302bool AttributeList::CreateRawAttribute(int id, const char *id_string) {
303 if (ContainsKey(attributes_, id)) {
304 LOG(ERROR) << "Trying to re-add attribute: " << id;
305 return false;
repo sync12cca802012-12-19 17:34:22 -0800306 }
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800307 attributes_[id] = AttributePointer(new NetlinkRawAttribute(id, id_string));
308 return true;
repo sync90ee0fa2012-12-18 10:08:08 -0800309}
310
Wade Guthrie2193b232013-06-05 17:09:07 -0700311bool AttributeList::GetAttributeAsString(int id, std::string *value) const {
312 NetlinkAttribute *attribute = GetAttribute(id);
313 if (!attribute)
314 return false;
315
316 return attribute->ToString(value);
317}
318
Wade Guthrie68da97c2013-02-26 13:09:35 -0800319NetlinkAttribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800320 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800321 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800322 if (i == attributes_.end()) {
323 return NULL;
324 }
repo sync1538d442012-12-20 15:24:35 -0800325 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800326}
327
repo sync90ee0fa2012-12-18 10:08:08 -0800328} // namespace shill