blob: 849259d2e6ea0dabb0a3978e174b7a631d7cd3f3 [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 Guthrieb9c3feb2013-04-25 16:31:19 -070032 LOG_IF(INFO, ContainsKey(attributes_, id)) << "Re-adding attribute: " << id;
Wade Guthrie68da97c2013-02-26 13:09:35 -080033 attributes_[id] = AttributePointer(factory.Run(id));
repo sync90ee0fa2012-12-18 10:08:08 -080034 return true;
35}
36
Wade Guthrie68da97c2013-02-26 13:09:35 -080037bool AttributeList::CreateAndInitAttribute(
38 int id, const nlattr *data, AttributeList::NewFromIdMethod factory) {
39 if (!CreateAttribute(id, factory)) {
repo sync90ee0fa2012-12-18 10:08:08 -080040 return false;
41 }
repo sync12cca802012-12-19 17:34:22 -080042 return attributes_[id]->InitFromNlAttr(data);
repo sync90ee0fa2012-12-18 10:08:08 -080043}
44
Wade Guthrie8e278612013-02-26 10:32:34 -080045void AttributeList::Print(int log_level, int indent) const {
repo sync1538d442012-12-20 15:24:35 -080046 map<int, AttributePointer>::const_iterator i;
47
48 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
Wade Guthrie8e278612013-02-26 10:32:34 -080049 i->second->Print(log_level, indent);
repo sync1538d442012-12-20 15:24:35 -080050 }
repo sync1538d442012-12-20 15:24:35 -080051}
52
repo syncdc085c82012-12-28 08:54:41 -080053ByteString AttributeList::Encode() const {
54 ByteString result;
55 map<int, AttributePointer>::const_iterator i;
56
57 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
58 result.Append(i->second->Encode());
59 }
60 return result;
61}
62
repo sync90ee0fa2012-12-18 10:08:08 -080063// U8 Attribute.
64
repo sync12cca802012-12-19 17:34:22 -080065bool AttributeList::GetU8AttributeValue(int id, uint8_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080066 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080067 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080068 return false;
repo sync1538d442012-12-20 15:24:35 -080069 return attribute->GetU8Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080070}
71
repo sync12cca802012-12-19 17:34:22 -080072bool AttributeList::CreateU8Attribute(int id, const char *id_string) {
73 if (ContainsKey(attributes_, id)) {
74 LOG(ERROR) << "Trying to re-add attribute: " << id;
75 return false;
76 }
repo sync1538d442012-12-20 15:24:35 -080077 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -080078 new NetlinkU8Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -080079 return true;
80}
81
Wade Guthrieefe1f0c2013-02-26 17:42:01 -080082bool AttributeList::SetU8AttributeValue(int id, uint8_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -080083 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080084 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080085 return false;
repo sync1538d442012-12-20 15:24:35 -080086 return attribute->SetU8Value(value);
repo sync12cca802012-12-19 17:34:22 -080087}
88
89
repo sync90ee0fa2012-12-18 10:08:08 -080090// U16 Attribute.
91
repo sync12cca802012-12-19 17:34:22 -080092bool AttributeList::GetU16AttributeValue(int id, uint16_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -080093 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -080094 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -080095 return false;
repo sync1538d442012-12-20 15:24:35 -080096 return attribute->GetU16Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -080097}
98
repo sync12cca802012-12-19 17:34:22 -080099bool AttributeList::CreateU16Attribute(int id, const char *id_string) {
100 if (ContainsKey(attributes_, id)) {
101 LOG(ERROR) << "Trying to re-add attribute: " << id;
102 return false;
103 }
repo sync1538d442012-12-20 15:24:35 -0800104 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800105 new NetlinkU16Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800106 return true;
107}
108
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800109bool AttributeList::SetU16AttributeValue(int id, uint16_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800110 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800111 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800112 return false;
repo sync1538d442012-12-20 15:24:35 -0800113 return attribute->SetU16Value(value);
repo sync12cca802012-12-19 17:34:22 -0800114}
115
repo sync90ee0fa2012-12-18 10:08:08 -0800116// U32 Attribute.
117
repo sync12cca802012-12-19 17:34:22 -0800118bool AttributeList::GetU32AttributeValue(int id, uint32_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800119 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800120 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800121 return false;
repo sync1538d442012-12-20 15:24:35 -0800122 return attribute->GetU32Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800123}
124
repo sync12cca802012-12-19 17:34:22 -0800125bool AttributeList::CreateU32Attribute(int id, const char *id_string) {
126 if (ContainsKey(attributes_, id)) {
127 LOG(ERROR) << "Trying to re-add attribute: " << id;
128 return false;
129 }
repo sync1538d442012-12-20 15:24:35 -0800130 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800131 new NetlinkU32Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800132 return true;
133}
134
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800135bool AttributeList::SetU32AttributeValue(int id, uint32_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800136 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800137 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800138 return false;
repo sync1538d442012-12-20 15:24:35 -0800139 return attribute->SetU32Value(value);
repo sync12cca802012-12-19 17:34:22 -0800140}
141
repo sync90ee0fa2012-12-18 10:08:08 -0800142// U64 Attribute.
143
repo sync12cca802012-12-19 17:34:22 -0800144bool AttributeList::GetU64AttributeValue(int id, uint64_t *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800145 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800146 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800147 return false;
repo sync1538d442012-12-20 15:24:35 -0800148 return attribute->GetU64Value(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800149}
150
repo sync12cca802012-12-19 17:34:22 -0800151bool AttributeList::CreateU64Attribute(int id, const char *id_string) {
152 if (ContainsKey(attributes_, id)) {
153 LOG(ERROR) << "Trying to re-add attribute: " << id;
154 return false;
155 }
repo sync1538d442012-12-20 15:24:35 -0800156 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800157 new NetlinkU64Attribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800158 return true;
159}
160
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800161bool AttributeList::SetU64AttributeValue(int id, uint64_t value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800162 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800163 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800164 return false;
repo sync1538d442012-12-20 15:24:35 -0800165 return attribute->SetU64Value(value);
repo sync12cca802012-12-19 17:34:22 -0800166}
167
repo sync90ee0fa2012-12-18 10:08:08 -0800168// Flag Attribute.
169
repo sync12cca802012-12-19 17:34:22 -0800170bool AttributeList::GetFlagAttributeValue(int id, bool *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800171 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800172 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800173 return false;
repo sync1538d442012-12-20 15:24:35 -0800174 return attribute->GetFlagValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800175}
176
repo sync12cca802012-12-19 17:34:22 -0800177bool AttributeList::CreateFlagAttribute(int id, const char *id_string) {
178 if (ContainsKey(attributes_, id)) {
179 LOG(ERROR) << "Trying to re-add attribute: " << id;
180 return false;
181 }
repo sync1538d442012-12-20 15:24:35 -0800182 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800183 new NetlinkFlagAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800184 return true;
185}
repo sync90ee0fa2012-12-18 10:08:08 -0800186
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800187bool AttributeList::SetFlagAttributeValue(int id, bool value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800188 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800189 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800190 return false;
repo sync1538d442012-12-20 15:24:35 -0800191 return attribute->SetFlagValue(value);
repo sync12cca802012-12-19 17:34:22 -0800192}
193
194bool AttributeList::IsFlagAttributeTrue(int id) const {
repo sync12cca802012-12-19 17:34:22 -0800195 bool flag;
196 if (!GetFlagAttributeValue(id, &flag)) {
repo sync90ee0fa2012-12-18 10:08:08 -0800197 return false;
198 }
199 return flag;
200}
201
202// String Attribute.
203
repo sync12cca802012-12-19 17:34:22 -0800204bool AttributeList::GetStringAttributeValue(int id, string *value) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800205 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800206 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800207 return false;
repo sync1538d442012-12-20 15:24:35 -0800208 return attribute->GetStringValue(value);
repo sync90ee0fa2012-12-18 10:08:08 -0800209}
210
repo sync12cca802012-12-19 17:34:22 -0800211bool AttributeList::CreateStringAttribute(int id, const char *id_string) {
212 if (ContainsKey(attributes_, id)) {
213 LOG(ERROR) << "Trying to re-add attribute: " << id;
214 return false;
215 }
repo sync1538d442012-12-20 15:24:35 -0800216 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800217 new NetlinkStringAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800218 return true;
219}
220
Wade Guthrief54872f2013-04-11 15:11:50 -0700221bool AttributeList::CreateSsidAttribute(int id, const char *id_string) {
222 if (ContainsKey(attributes_, id)) {
223 LOG(ERROR) << "Trying to re-add attribute: " << id;
224 return false;
225 }
226 attributes_[id] = AttributePointer(
227 new NetlinkSsidAttribute(id, id_string));
228 return true;
229}
230
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800231bool AttributeList::SetStringAttributeValue(int id, string value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800232 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800233 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
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800240bool AttributeList::GetNestedAttributeList(int id,
241 AttributeListRefPtr *value) {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800242 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800243 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800244 return false;
Wade Guthrieefe1f0c2013-02-26 17:42:01 -0800245 return attribute->GetNestedAttributeList(value);
246}
247
248bool AttributeList::ConstGetNestedAttributeList(
249 int id, AttributeListConstRefPtr *value) const {
250 NetlinkAttribute *attribute = GetAttribute(id);
251 if (!attribute)
252 return false;
253 return attribute->ConstGetNestedAttributeList(value);
254}
255
256bool AttributeList::SetNestedAttributeHasAValue(int id) {
257 NetlinkAttribute *attribute = GetAttribute(id);
258 if (!attribute)
259 return false;
260 return attribute->SetNestedHasAValue();
repo sync12cca802012-12-19 17:34:22 -0800261}
262
263bool AttributeList::CreateNestedAttribute(int id, const char *id_string) {
264 if (ContainsKey(attributes_, id)) {
265 LOG(ERROR) << "Trying to re-add attribute: " << id;
266 return false;
267 }
repo sync1538d442012-12-20 15:24:35 -0800268 attributes_[id] = AttributePointer(
Wade Guthrie68da97c2013-02-26 13:09:35 -0800269 new NetlinkNestedAttribute(id, id_string));
repo sync12cca802012-12-19 17:34:22 -0800270 return true;
271}
272
repo sync90ee0fa2012-12-18 10:08:08 -0800273// Raw Attribute.
274
repo sync1538d442012-12-20 15:24:35 -0800275bool AttributeList::GetRawAttributeValue(int id,
276 ByteString *output) const {
Wade Guthrie68da97c2013-02-26 13:09:35 -0800277 NetlinkAttribute *attribute = GetAttribute(id);
repo sync1538d442012-12-20 15:24:35 -0800278 if (!attribute)
repo sync12cca802012-12-19 17:34:22 -0800279 return false;
repo sync90ee0fa2012-12-18 10:08:08 -0800280
281 ByteString raw_value;
282
repo sync1538d442012-12-20 15:24:35 -0800283 if (!attribute->GetRawValue(&raw_value))
repo sync90ee0fa2012-12-18 10:08:08 -0800284 return false;
285
286 if (output) {
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800287 *output = raw_value;
repo sync90ee0fa2012-12-18 10:08:08 -0800288 }
289 return true;
290}
291
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800292bool AttributeList::SetRawAttributeValue(int id, ByteString value) {
293 NetlinkAttribute *attribute = GetAttribute(id);
294 if (!attribute)
295 return false;
296 return attribute->SetRawValue(value);
297}
298
299bool AttributeList::CreateRawAttribute(int id, const char *id_string) {
300 if (ContainsKey(attributes_, id)) {
301 LOG(ERROR) << "Trying to re-add attribute: " << id;
302 return false;
repo sync12cca802012-12-19 17:34:22 -0800303 }
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800304 attributes_[id] = AttributePointer(new NetlinkRawAttribute(id, id_string));
305 return true;
repo sync90ee0fa2012-12-18 10:08:08 -0800306}
307
Wade Guthrie68da97c2013-02-26 13:09:35 -0800308NetlinkAttribute *AttributeList::GetAttribute(int id) const {
repo sync1538d442012-12-20 15:24:35 -0800309 map<int, AttributePointer>::const_iterator i;
repo sync12cca802012-12-19 17:34:22 -0800310 i = attributes_.find(id);
repo sync90ee0fa2012-12-18 10:08:08 -0800311 if (i == attributes_.end()) {
312 return NULL;
313 }
repo sync1538d442012-12-20 15:24:35 -0800314 return i->second.get();
repo sync90ee0fa2012-12-18 10:08:08 -0800315}
316
repo sync90ee0fa2012-12-18 10:08:08 -0800317} // namespace shill