blob: 59e226e95dc1fd2b1053bf02f62602ba9a35400c [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
22using std::string;
23using std::map;
24
25namespace shill {
26
27AttributeList::~AttributeList() {
28 map<int, Nl80211Attribute *>::iterator i;
29 for (i = attributes_.begin(); i != attributes_.end(); ++i) {
30 delete i->second;
31 }
32}
33
34bool AttributeList::CreateAttribute(nl80211_attrs name) {
35 if (ContainsKey(attributes_, name)) {
36 LOG(ERROR) << "Trying to re-add attribute: " << name;
37 return false;
38 }
39 attributes_[name] = Nl80211Attribute::NewFromName(name);
40 return true;
41}
42
43bool AttributeList::CreateAndInitFromNlAttr(nl80211_attrs name,
44 const nlattr *data) {
45 if (!CreateAttribute(name)) {
46 return false;
47 }
48 return attributes_[name]->InitFromNlAttr(data);
49}
50
51// U8 Attribute.
52
53bool AttributeList::GetU8AttributeValue(nl80211_attrs name,
54 uint8_t *value) const {
55 CHECK(HasAttribute(name, Nl80211Attribute::kTypeU8));
56 const Nl80211U8Attribute *attr =
57 reinterpret_cast<const Nl80211U8Attribute *>(GetAttribute(name));
58 return attr->GetU8Value(value);
59}
60
61// U16 Attribute.
62
63bool AttributeList::GetU16AttributeValue(nl80211_attrs name,
64 uint16_t *value) const {
65 CHECK(HasAttribute(name, Nl80211Attribute::kTypeU16));
66 const Nl80211U16Attribute *attr =
67 reinterpret_cast<const Nl80211U16Attribute *>(GetAttribute(name));
68 return attr->GetU16Value(value);
69}
70
71// U32 Attribute.
72
73bool AttributeList::GetU32AttributeValue(nl80211_attrs name,
74 uint32_t *value) const {
75 CHECK(HasAttribute(name, Nl80211Attribute::kTypeU32));
76 const Nl80211U32Attribute *attr =
77 reinterpret_cast<const Nl80211U32Attribute *>(GetAttribute(name));
78 return attr->GetU32Value(value);
79}
80
81// U64 Attribute.
82
83bool AttributeList::GetU64AttributeValue(nl80211_attrs name,
84 uint64_t *value) const {
85 CHECK(HasAttribute(name, Nl80211Attribute::kTypeU64));
86 const Nl80211U64Attribute *attr =
87 reinterpret_cast<const Nl80211U64Attribute *>(GetAttribute(name));
88 return attr->GetU64Value(value);
89}
90
91// Flag Attribute.
92
93bool AttributeList::GetFlagAttributeValue(nl80211_attrs name,
94 bool *value) const {
95 CHECK(HasAttribute(name, Nl80211Attribute::kTypeFlag));
96 const Nl80211FlagAttribute *attr =
97 reinterpret_cast<const Nl80211FlagAttribute *>(GetAttribute(name));
98 return attr->GetFlagValue(value);
99}
100
101bool AttributeList::IsFlagAttributeTrue(nl80211_attrs name) const {
102 bool flag;
103
104 // TODO(wdg): After message constructors add attributes, remove the following
105 // lines.
106 if (!HasAttribute(name, Nl80211Attribute::kTypeFlag)) {
107 return false;
108 }
109
110 if (!GetFlagAttributeValue(name, &flag)) {
111 return false;
112 }
113 return flag;
114}
115
116// String Attribute.
117
118bool AttributeList::GetStringAttributeValue(nl80211_attrs name,
119 string *value) const {
120 CHECK(HasAttribute(name, Nl80211Attribute::kTypeString));
121 const Nl80211StringAttribute *attr =
122 reinterpret_cast<const Nl80211StringAttribute *>(GetAttribute(name));
123 return attr->GetStringValue(value);
124}
125
126// Raw Attribute.
127
128bool AttributeList::GetRawAttributeValue(nl80211_attrs name,
129 ByteString *output) const {
130 CHECK(HasAttribute(name, Nl80211Attribute::kTypeRaw));
131 const Nl80211RawAttribute *attr =
132 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(name));
133
134 ByteString raw_value;
135
136 if (!attr->GetRawValue(&raw_value))
137 return false;
138
139 if (output) {
140 const nlattr *const_data =
141 reinterpret_cast<const nlattr *>(raw_value.GetConstData());
142 // nla_data and nla_len don't change their parameters but don't declare
143 // them to be const. Hence the cast.
144 nlattr *data_nlattr = const_cast<nlattr *>(const_data);
145 *output = ByteString(
146 reinterpret_cast<unsigned char *>(nla_data(data_nlattr)),
147 nla_len(data_nlattr));
148 }
149 return true;
150}
151
152const Nl80211RawAttribute *AttributeList::GetRawAttribute(
153 nl80211_attrs name) const {
154 CHECK(HasAttribute(name, Nl80211Attribute::kTypeRaw));
155 const Nl80211RawAttribute *attr =
156 reinterpret_cast<const Nl80211RawAttribute *>(GetAttribute(name));
157 return attr;
158}
159
160Nl80211Attribute *AttributeList::GetAttribute(nl80211_attrs name) const {
161 map<int, Nl80211Attribute *>::const_iterator i;
162 i = attributes_.find(name);
163 if (i == attributes_.end()) {
164 return NULL;
165 }
166 return i->second;
167}
168
169bool AttributeList::HasAttribute(nl80211_attrs name,
170 Nl80211Attribute::Type type) const {
171 map<int, Nl80211Attribute *>::const_iterator i;
172 i = attributes_.find(name);
173 if (i == attributes_.end()) {
174 LOG(ERROR) << "FALSE - Didn't find name " << name;
175 return false;
176 }
177 return (i->second->type() == type) ? true : false;
178}
179
180
181} // namespace shill