• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/net/nl80211_attribute.h"
18 
19 #include <string>
20 #include <utility>
21 
22 #include <base/bind.h>
23 #include <base/format_macros.h>
24 #include <base/logging.h>
25 #include <base/strings/stringprintf.h>
26 
27 #include "shill/net/ieee80211.h"
28 #include "shill/net/netlink_message.h"
29 
30 using base::Bind;
31 using base::StringAppendF;
32 using base::StringPrintf;
33 using std::string;
34 
35 namespace shill {
36 
37 const int Nl80211AttributeCookie::kName = NL80211_ATTR_COOKIE;
38 const char Nl80211AttributeCookie::kNameString[] = "NL80211_ATTR_COOKIE";
39 
40 const int Nl80211AttributeBss::kName = NL80211_ATTR_BSS;
41 const char Nl80211AttributeBss::kNameString[] = "NL80211_ATTR_BSS";
42 const int Nl80211AttributeBss::kChannelsAttributeId =
43     IEEE_80211::kElemIdChannels;
44 const int Nl80211AttributeBss::kChallengeTextAttributeId =
45     IEEE_80211::kElemIdChallengeText;
46 const int Nl80211AttributeBss::kCountryInfoAttributeId =
47     IEEE_80211::kElemIdCountry;
48 const int Nl80211AttributeBss::kDSParameterSetAttributeId =
49     IEEE_80211::kElemIdDSParameterSet;
50 const int Nl80211AttributeBss::kErpAttributeId =
51     IEEE_80211::kElemIdErp;
52 const int Nl80211AttributeBss::kExtendedRatesAttributeId =
53     IEEE_80211::kElemIdExtendedRates;
54 const int Nl80211AttributeBss::kHtCapAttributeId =
55     IEEE_80211::kElemIdHTCap;
56 const int Nl80211AttributeBss::kHtInfoAttributeId =
57     IEEE_80211::kElemIdHTInfo;
58 const int Nl80211AttributeBss::kPowerCapabilityAttributeId =
59     IEEE_80211::kElemIdPowerCapability;
60 const int Nl80211AttributeBss::kPowerConstraintAttributeId =
61     IEEE_80211::kElemIdPowerConstraint;
62 const int Nl80211AttributeBss::kRequestAttributeId =
63     IEEE_80211::kElemIdRequest;
64 const int Nl80211AttributeBss::kRsnAttributeId =
65     IEEE_80211::kElemIdRSN;
66 const int Nl80211AttributeBss::kSsidAttributeId =
67     IEEE_80211::kElemIdSsid;
68 const int Nl80211AttributeBss::kSupportedRatesAttributeId =
69     IEEE_80211::kElemIdSupportedRates;
70 const int Nl80211AttributeBss::kTpcReportAttributeId =
71     IEEE_80211::kElemIdTpcReport;
72 const int Nl80211AttributeBss::kVendorSpecificAttributeId =
73     IEEE_80211::kElemIdVendor;
74 const int Nl80211AttributeBss::kVhtCapAttributeId =
75     IEEE_80211::kElemIdVHTCap;
76 const int Nl80211AttributeBss::kVhtInfoAttributeId =
77     IEEE_80211::kElemIdVHTOperation;
78 
79 static const char kSsidString[] = "SSID";
80 static const char kRatesString[] = "Rates";
81 static const char kHtCapString[] = "HTCapabilities";
82 static const char kHtOperString[] = "HTOperation";
83 static const char kVhtCapString[] = "VHTCapabilities";
84 static const char kVhtOperString[] = "VHTOperation";
85 
Nl80211AttributeBss()86 Nl80211AttributeBss::Nl80211AttributeBss()
87     : NetlinkNestedAttribute(kName, kNameString) {
88   nested_template_.insert(
89       AttrDataPair(__NL80211_BSS_INVALID,
90                    NestedData(kTypeU32, "__NL80211_BSS_INVALID", false)));
91   nested_template_.insert(AttrDataPair(
92       NL80211_BSS_BSSID, NestedData(kTypeRaw, "NL80211_BSS_BSSID", false)));
93   nested_template_.insert(
94       AttrDataPair(NL80211_BSS_FREQUENCY,
95                    NestedData(kTypeU32, "NL80211_BSS_FREQUENCY", false)));
96   nested_template_.insert(AttrDataPair(
97       NL80211_BSS_TSF, NestedData(kTypeU64, "NL80211_BSS_TSF", false)));
98   nested_template_.insert(
99       AttrDataPair(NL80211_BSS_BEACON_INTERVAL,
100                    NestedData(kTypeU16, "NL80211_BSS_BEACON_INTERVAL", false)));
101   nested_template_.insert(
102       AttrDataPair(NL80211_BSS_CAPABILITY,
103                    NestedData(kTypeU16, "NL80211_BSS_CAPABILITY", false)));
104   nested_template_.insert(AttrDataPair(
105       NL80211_BSS_INFORMATION_ELEMENTS,
106       NestedData(kTypeRaw, "NL80211_BSS_INFORMATION_ELEMENTS", false,
107                  Bind(&Nl80211AttributeBss::ParseInformationElements))));
108   nested_template_.insert(
109       AttrDataPair(NL80211_BSS_SIGNAL_MBM,
110                    NestedData(kTypeU32, "NL80211_BSS_SIGNAL_MBM", false)));
111   nested_template_.insert(
112       AttrDataPair(NL80211_BSS_SIGNAL_UNSPEC,
113                    NestedData(kTypeU8, "NL80211_BSS_SIGNAL_UNSPEC", false)));
114   nested_template_.insert(AttrDataPair(
115       NL80211_BSS_STATUS, NestedData(kTypeU32, "NL80211_BSS_STATUS", false)));
116   nested_template_.insert(
117       AttrDataPair(NL80211_BSS_SEEN_MS_AGO,
118                    NestedData(kTypeU32, "NL80211_BSS_SEEN_MS_AGO", false)));
119 }
120 
ParseInformationElements(AttributeList * attribute_list,size_t id,const string & attribute_name,ByteString data)121 bool Nl80211AttributeBss::ParseInformationElements(
122     AttributeList* attribute_list, size_t id, const string& attribute_name,
123     ByteString data) {
124   if (!attribute_list) {
125     LOG(ERROR) << "NULL |attribute_list| parameter";
126     return false;
127   }
128   attribute_list->CreateNestedAttribute(id, attribute_name.c_str());
129 
130   // Now, handle the nested data.
131   AttributeListRefPtr ie_attribute;
132   if (!attribute_list->GetNestedAttributeList(id, &ie_attribute) ||
133       !ie_attribute) {
134     LOG(ERROR) << "Couldn't get attribute " << attribute_name
135                << " which we just created.";
136     return false;
137   }
138   const uint8_t* sub_attribute = data.GetConstData();
139   const uint8_t* end = sub_attribute + data.GetLength();
140   const int kHeaderBytes = 2;
141   while (end - sub_attribute > kHeaderBytes) {
142     uint8_t type = sub_attribute[0];
143     uint8_t payload_bytes = sub_attribute[1];
144     const uint8_t* payload = &sub_attribute[kHeaderBytes];
145     if (payload + payload_bytes > end) {
146       LOG(ERROR) << "Found malformed IE data.";
147       return false;
148     }
149     // See http://dox.ipxe.org/ieee80211_8h_source.html for more info on types
150     // and data inside information elements.
151     switch (type) {
152       case kSsidAttributeId: {
153         ie_attribute->CreateSsidAttribute(type, kSsidString);
154         if (payload_bytes == 0) {
155           ie_attribute->SetStringAttributeValue(type, "");
156         } else {
157           ie_attribute->SetStringAttributeValue(
158               type,
159               string(reinterpret_cast<const char*>(payload), payload_bytes));
160         }
161         break;
162       }
163       case kSupportedRatesAttributeId:
164       case kExtendedRatesAttributeId: {
165         ie_attribute->CreateNestedAttribute(type, kRatesString);
166         AttributeListRefPtr rates_attribute;
167         if (!ie_attribute->GetNestedAttributeList(type, &rates_attribute) ||
168             !rates_attribute) {
169           LOG(ERROR) << "Couldn't get attribute " << attribute_name
170                      << " which we just created.";
171           break;
172         }
173         // Extract each rate, add it to the list.
174         for (size_t i = 0; i < payload_bytes; ++i) {
175           string rate_name = StringPrintf("Rate-%zu", i);
176           rates_attribute->CreateU8Attribute(i, rate_name.c_str());
177           rates_attribute->SetU8AttributeValue(i, payload[i]);
178         }
179         ie_attribute->SetNestedAttributeHasAValue(type);
180         break;
181       }
182       case kHtCapAttributeId: {
183         ie_attribute->CreateRawAttribute(type, kHtCapString);
184         ie_attribute->SetRawAttributeValue(
185             type,
186             ByteString(
187                 reinterpret_cast<const char*>(payload), payload_bytes));
188         break;
189       }
190       case kHtInfoAttributeId: {
191         ie_attribute->CreateRawAttribute(type, kHtOperString);
192         ie_attribute->SetRawAttributeValue(
193             type,
194             ByteString(
195                 reinterpret_cast<const char*>(payload), payload_bytes));
196         break;
197       }
198       case kVhtCapAttributeId: {
199         ie_attribute->CreateRawAttribute(type, kVhtCapString);
200         ie_attribute->SetRawAttributeValue(
201             type,
202             ByteString(
203                 reinterpret_cast<const char*>(payload), payload_bytes));
204         break;
205       }
206       case kVhtInfoAttributeId: {
207         ie_attribute->CreateRawAttribute(type, kVhtOperString);
208         ie_attribute->SetRawAttributeValue(
209             type,
210             ByteString(
211                 reinterpret_cast<const char*>(payload), payload_bytes));
212         break;
213       }
214       case kDSParameterSetAttributeId:
215       case kCountryInfoAttributeId:
216       case kRequestAttributeId:
217       case kChallengeTextAttributeId:
218       case kPowerConstraintAttributeId:
219       case kPowerCapabilityAttributeId:
220       case kTpcReportAttributeId:
221       case kChannelsAttributeId:
222       case kErpAttributeId:
223       case kRsnAttributeId:
224       case kVendorSpecificAttributeId:
225       default:
226         break;
227     }
228     sub_attribute += kHeaderBytes + payload_bytes;
229   }
230   attribute_list->SetNestedAttributeHasAValue(id);
231   return true;
232 }
233 
234 const int Nl80211AttributeWiphyBands::kName = NL80211_ATTR_WIPHY_BANDS;
235 const char Nl80211AttributeWiphyBands::kNameString[] =
236     "NL80211_ATTR_WIPHY_BANDS";
237 
Nl80211AttributeWiphyBands()238 Nl80211AttributeWiphyBands::Nl80211AttributeWiphyBands()
239     : NetlinkNestedAttribute(kName, kNameString) {
240   // Frequencies
241   NestedData freq(kTypeNested, "NL80211_BAND_ATTR_FREQ", true);
242   freq.deeper_nesting.insert(AttrDataPair(
243       __NL80211_FREQUENCY_ATTR_INVALID,
244       NestedData(kTypeU32, "__NL80211_FREQUENCY_ATTR_INVALID", false)));
245   freq.deeper_nesting.insert(
246       AttrDataPair(NL80211_FREQUENCY_ATTR_FREQ,
247                    NestedData(kTypeU32, "NL80211_FREQUENCY_ATTR_FREQ", false)));
248   freq.deeper_nesting.insert(AttrDataPair(
249       NL80211_FREQUENCY_ATTR_DISABLED,
250       NestedData(kTypeFlag, "NL80211_FREQUENCY_ATTR_DISABLED", false)));
251   freq.deeper_nesting.insert(AttrDataPair(
252       NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
253       NestedData(kTypeFlag, "NL80211_FREQUENCY_ATTR_PASSIVE_SCAN", false)));
254   freq.deeper_nesting.insert(AttrDataPair(
255       NL80211_FREQUENCY_ATTR_NO_IBSS,
256       NestedData(kTypeFlag, "NL80211_FREQUENCY_ATTR_NO_IBSS", false)));
257   freq.deeper_nesting.insert(AttrDataPair(
258       NL80211_FREQUENCY_ATTR_RADAR,
259       NestedData(kTypeFlag, "NL80211_FREQUENCY_ATTR_RADAR", false)));
260   freq.deeper_nesting.insert(AttrDataPair(
261       NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
262       NestedData(kTypeU32, "NL80211_FREQUENCY_ATTR_MAX_TX_POWER", false)));
263 
264   NestedData freqs(kTypeNested, "NL80211_BAND_ATTR_FREQS", false);
265   freqs.deeper_nesting.insert(AttrDataPair(kArrayAttrEnumVal, freq));
266 
267   // Rates
268   NestedData rate(kTypeNested, "NL80211_BAND_ATTR_RATE", true);
269   rate.deeper_nesting.insert(AttrDataPair(
270       __NL80211_BITRATE_ATTR_INVALID,
271       NestedData(kTypeU32, "__NL80211_BITRATE_ATTR_INVALID", false)));
272   rate.deeper_nesting.insert(
273       AttrDataPair(NL80211_BITRATE_ATTR_RATE,
274                    NestedData(kTypeU32, "NL80211_BITRATE_ATTR_RATE", false)));
275   rate.deeper_nesting.insert(AttrDataPair(
276       NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
277       NestedData(kTypeFlag, "NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE", false)));
278 
279   NestedData rates(kTypeNested, "NL80211_BAND_ATTR_RATES", true);
280   rates.deeper_nesting.insert(AttrDataPair(kArrayAttrEnumVal, rate));
281 
282   // Main body of attribute
283   NestedData bands(kTypeNested, "NL80211_ATTR_BANDS", true);
284   bands.deeper_nesting.insert(
285       AttrDataPair(
286           __NL80211_BAND_ATTR_INVALID,
287           NestedData(kTypeU32, "__NL80211_BAND_ATTR_INVALID,", false)));
288   bands.deeper_nesting.insert(AttrDataPair(NL80211_BAND_ATTR_FREQS, freqs));
289   bands.deeper_nesting.insert(AttrDataPair(NL80211_BAND_ATTR_RATES, rates));
290   bands.deeper_nesting.insert(AttrDataPair(
291       NL80211_BAND_ATTR_HT_MCS_SET,
292       NestedData(kTypeRaw, "NL80211_BAND_ATTR_HT_MCS_SET", false)));
293   bands.deeper_nesting.insert(
294       AttrDataPair(NL80211_BAND_ATTR_HT_CAPA,
295                    NestedData(kTypeU16, "NL80211_BAND_ATTR_HT_CAPA", false)));
296   bands.deeper_nesting.insert(AttrDataPair(
297       NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
298       NestedData(kTypeU8, "NL80211_BAND_ATTR_HT_AMPDU_FACTOR", false)));
299   bands.deeper_nesting.insert(AttrDataPair(
300       NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
301       NestedData(kTypeU8, "NL80211_BAND_ATTR_HT_AMPDU_DENSITY", false)));
302 
303   nested_template_.insert(AttrDataPair(kArrayAttrEnumVal, bands));
304 }
305 
306 #if !defined(DISABLE_WAKE_ON_WIFI)
307 const int Nl80211AttributeWowlanTriggers::kName = NL80211_ATTR_WOWLAN_TRIGGERS;
308 const char Nl80211AttributeWowlanTriggers::kNameString[] =
309     "NL80211_ATTR_WOWLAN_TRIGGERS";
310 
Nl80211AttributeWowlanTriggers(NetlinkMessage::MessageContext context)311 Nl80211AttributeWowlanTriggers::Nl80211AttributeWowlanTriggers(
312     NetlinkMessage::MessageContext context)
313     : NetlinkNestedAttribute(kName, kNameString) {
314   // Pattern matching trigger attribute.
315   if (context.nl80211_cmd == NL80211_CMD_SET_WOWLAN && context.is_broadcast) {
316     // If this attribute occurs in a wakeup report, parse
317     // NL80211_WOWLAN_TRIG_PKT_PATTERN as a U32 reporting the index of the
318     // pattern that caused the wake.
319     nested_template_.insert(AttrDataPair(
320         NL80211_WOWLAN_TRIG_PKT_PATTERN,
321         NestedData(kTypeU32, "NL80211_WOWLAN_TRIG_PKT_PATTERN", false)));
322   } else {
323     // Otherwise, this attribute is meant to program the NIC, so parse it as
324     // a nested attribute.
325     NestedData patterns(kTypeNested, "NL80211_WOWLAN_TRIG_PKT_PATTERN", false);
326     NestedData individual_pattern(kTypeNested, "Pattern Match Info", true);
327     individual_pattern.deeper_nesting.insert(
328         AttrDataPair(NL80211_PKTPAT_MASK,
329                      NestedData(kTypeRaw, "NL80211_PKTPAT_MASK", false)));
330     individual_pattern.deeper_nesting.insert(
331         AttrDataPair(NL80211_PKTPAT_PATTERN,
332                      NestedData(kTypeRaw, "NL80211_PKTPAT_PATTERN", false)));
333     individual_pattern.deeper_nesting.insert(
334         AttrDataPair(NL80211_PKTPAT_OFFSET,
335                      NestedData(kTypeU32, "NL80211_PKTPAT_OFFSET", false)));
336     patterns.deeper_nesting.insert(
337         AttrDataPair(kArrayAttrEnumVal, individual_pattern));
338     nested_template_.insert(
339         AttrDataPair(NL80211_WOWLAN_TRIG_PKT_PATTERN, patterns));
340   }
341 
342   // Net detect SSID matching trigger attribute.
343   NestedData net_detect(kTypeNested, "NL80211_WOWLAN_TRIG_NET_DETECT", false);
344   NestedData scan_freqs(kTypeNested, "NL80211_ATTR_SCAN_FREQUENCIES", true);
345   scan_freqs.deeper_nesting.insert(
346       AttrDataPair(kArrayAttrEnumVal,
347                    NestedData(kTypeU32, "Frequency match", false)));
348   net_detect.deeper_nesting.insert(
349       AttrDataPair(NL80211_ATTR_SCAN_FREQUENCIES, scan_freqs));
350   net_detect.deeper_nesting.insert(AttrDataPair(
351       NL80211_ATTR_SCHED_SCAN_INTERVAL,
352       NestedData(kTypeU32, "NL80211_ATTR_SCHED_SCAN_INTERVAL", false)));
353   NestedData scan_matches(kTypeNested, "NL80211_ATTR_SCHED_SCAN_MATCH", false);
354   NestedData individual_scan_match(
355       kTypeNested, "NL80211_ATTR_SCHED_SCAN_MATCH_SINGLE", true);
356   individual_scan_match.deeper_nesting.insert(AttrDataPair(
357       NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
358       NestedData(kTypeRaw, "NL80211_SCHED_SCAN_MATCH_ATTR_SSID", false)));
359   scan_matches.deeper_nesting.insert(
360       AttrDataPair(kArrayAttrEnumVal, individual_scan_match));
361   net_detect.deeper_nesting.insert(
362       AttrDataPair(NL80211_ATTR_SCHED_SCAN_MATCH, scan_matches));
363 
364   // Net detect results attribute
365   NestedData net_detect_results(
366       kTypeNested, "NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS", false);
367   NestedData single_result(kTypeNested, "NL80211_WOWLAN_TRIG_NET_DETECT_RESULT",
368                            true);
369   NestedData freq_list(kTypeNested, "NL80211_ATTR_SCAN_FREQUENCIES", false);
370   freq_list.deeper_nesting.insert(
371       AttrDataPair(kArrayAttrEnumVal,
372                    NestedData(kTypeU32, "Frequency match", true)));
373   single_result.deeper_nesting.insert(
374       AttrDataPair(NL80211_ATTR_SCAN_FREQUENCIES, freq_list));
375   single_result.deeper_nesting.insert(AttrDataPair(
376       NL80211_ATTR_SSID, NestedData(kTypeRaw, "NL80211_ATTR_SSID", false)));
377   net_detect_results.deeper_nesting.insert(
378       AttrDataPair(kArrayAttrEnumVal, single_result));
379 
380   // Main body of the triggers attribute.
381   nested_template_.insert(AttrDataPair(
382       NL80211_WOWLAN_TRIG_DISCONNECT,
383       NestedData(kTypeFlag, "NL80211_WOWLAN_TRIG_DISCONNECT", false)));
384   nested_template_.insert(
385       AttrDataPair(NL80211_WOWLAN_TRIG_NET_DETECT, net_detect));
386   nested_template_.insert(
387       AttrDataPair(NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, net_detect_results));
388 }
389 
390 const int Nl80211AttributeWowlanTriggersSupported::kName =
391     NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED;
392 const char Nl80211AttributeWowlanTriggersSupported::kNameString[] =
393     "NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED";
394 
395 Nl80211AttributeWowlanTriggersSupported::
Nl80211AttributeWowlanTriggersSupported()396     Nl80211AttributeWowlanTriggersSupported()
397     : NetlinkNestedAttribute(kName, kNameString) {
398   nested_template_.insert(AttrDataPair(
399       NL80211_WOWLAN_TRIG_DISCONNECT,
400       NestedData(kTypeFlag, "NL80211_WOWLAN_TRIG_DISCONNECT", false)));
401   nested_template_.insert(AttrDataPair(
402       NL80211_WOWLAN_TRIG_PKT_PATTERN,
403       NestedData(kTypeRaw, "NL80211_WOWLAN_TRIG_PKT_PATTERN", false)));
404   nested_template_.insert(AttrDataPair(
405       NL80211_WOWLAN_TRIG_NET_DETECT,
406       NestedData(kTypeU32, "NL80211_WOWLAN_TRIG_NET_DETECT", false)));
407 }
408 #endif  // DISABLE_WAKE_ON_WIFI
409 
410 const int Nl80211AttributeCipherSuites::kName = NL80211_ATTR_CIPHER_SUITES;
411 const char Nl80211AttributeCipherSuites::kNameString[] =
412     "NL80211_ATTR_CIPHER_SUITES";
413 
414 const int Nl80211AttributeControlPortEthertype::kName =
415     NL80211_ATTR_CONTROL_PORT_ETHERTYPE;
416 const char Nl80211AttributeControlPortEthertype::kNameString[] =
417     "NL80211_ATTR_CONTROL_PORT_ETHERTYPE";
418 
419 const int Nl80211AttributeCqm::kName = NL80211_ATTR_CQM;
420 const char Nl80211AttributeCqm::kNameString[] = "NL80211_ATTR_CQM";
421 
Nl80211AttributeCqm()422 Nl80211AttributeCqm::Nl80211AttributeCqm()
423     : NetlinkNestedAttribute(kName, kNameString) {
424   nested_template_.insert(
425       AttrDataPair(__NL80211_ATTR_CQM_INVALID,
426                    NestedData(kTypeU32, "__NL80211_ATTR_CQM_INVALID", false)));
427   nested_template_.insert(
428       AttrDataPair(NL80211_ATTR_CQM_RSSI_THOLD,
429                    NestedData(kTypeU32, "NL80211_ATTR_CQM_RSSI_THOLD", false)));
430   nested_template_.insert(
431       AttrDataPair(NL80211_ATTR_CQM_RSSI_HYST,
432                    NestedData(kTypeU32, "NL80211_ATTR_CQM_RSSI_HYST", false)));
433   nested_template_.insert(AttrDataPair(
434       NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
435       NestedData(kTypeU32, "NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT", false)));
436   nested_template_.insert(AttrDataPair(
437       NL80211_ATTR_CQM_PKT_LOSS_EVENT,
438       NestedData(kTypeU32, "NL80211_ATTR_CQM_PKT_LOSS_EVENT", false)));
439 }
440 
441 const int Nl80211AttributeDeviceApSme::kName = NL80211_ATTR_DEVICE_AP_SME;
442 const char Nl80211AttributeDeviceApSme::kNameString[] =
443     "NL80211_ATTR_DEVICE_AP_SME";
444 
445 const int Nl80211AttributeDfsRegion::kName = NL80211_ATTR_DFS_REGION;
446 const char Nl80211AttributeDfsRegion::kNameString[] = "NL80211_ATTR_DFS_REGION";
447 
448 const int Nl80211AttributeDisconnectedByAp::kName =
449     NL80211_ATTR_DISCONNECTED_BY_AP;
450 const char Nl80211AttributeDisconnectedByAp::kNameString[] =
451     "NL80211_ATTR_DISCONNECTED_BY_AP";
452 
453 const int Nl80211AttributeDuration::kName = NL80211_ATTR_DURATION;
454 const char Nl80211AttributeDuration::kNameString[] = "NL80211_ATTR_DURATION";
455 
456 const int Nl80211AttributeFeatureFlags::kName = NL80211_ATTR_FEATURE_FLAGS;
457 const char Nl80211AttributeFeatureFlags::kNameString[] =
458     "NL80211_ATTR_FEATURE_FLAGS";
459 
460 const int Nl80211AttributeFrame::kName = NL80211_ATTR_FRAME;
461 const char Nl80211AttributeFrame::kNameString[] = "NL80211_ATTR_FRAME";
462 
463 const int Nl80211AttributeGeneration::kName = NL80211_ATTR_GENERATION;
464 const char Nl80211AttributeGeneration::kNameString[] =
465     "NL80211_ATTR_GENERATION";
466 
467 const int Nl80211AttributeHtCapabilityMask::kName =
468     NL80211_ATTR_HT_CAPABILITY_MASK;
469 const char Nl80211AttributeHtCapabilityMask::kNameString[] =
470     "NL80211_ATTR_HT_CAPABILITY_MASK";
471 
472 const int Nl80211AttributeIfindex::kName = NL80211_ATTR_IFINDEX;
473 const char Nl80211AttributeIfindex::kNameString[] = "NL80211_ATTR_IFINDEX";
474 
475 const int Nl80211AttributeIftype::kName = NL80211_ATTR_IFTYPE;
476 const char Nl80211AttributeIftype::kNameString[] = "NL80211_ATTR_IFTYPE";
477 
478 const int Nl80211AttributeKeyIdx::kName = NL80211_ATTR_KEY_IDX;
479 const char Nl80211AttributeKeyIdx::kNameString[] = "NL80211_ATTR_KEY_IDX";
480 
481 const int Nl80211AttributeKeySeq::kName = NL80211_ATTR_KEY_SEQ;
482 const char Nl80211AttributeKeySeq::kNameString[] = "NL80211_ATTR_KEY_SEQ";
483 
484 const int Nl80211AttributeKeyType::kName = NL80211_ATTR_KEY_TYPE;
485 const char Nl80211AttributeKeyType::kNameString[] = "NL80211_ATTR_KEY_TYPE";
486 
487 const int Nl80211AttributeMac::kName = NL80211_ATTR_MAC;
488 const char Nl80211AttributeMac::kNameString[] = "NL80211_ATTR_MAC";
489 
ToString(std::string * value) const490 bool Nl80211AttributeMac::ToString(std::string* value) const {
491   if (!value) {
492     LOG(ERROR) << "Null |value| parameter";
493     return false;
494   }
495   *value = StringFromMacAddress(data_.GetConstData());
496   return true;
497 }
498 
499 // static
StringFromMacAddress(const uint8_t * arg)500 string Nl80211AttributeMac::StringFromMacAddress(const uint8_t* arg) {
501   string output;
502 
503   if (!arg) {
504     static const char kBogusMacAddress[] = "XX:XX:XX:XX:XX:XX";
505     output = kBogusMacAddress;
506     LOG(ERROR) << "|arg| parameter is NULL.";
507   } else {
508     output = StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x", arg[0], arg[1],
509                           arg[2], arg[3], arg[4], arg[5]);
510   }
511   return output;
512 }
513 
514 const int Nl80211AttributeMaxMatchSets::kName = NL80211_ATTR_MAX_MATCH_SETS;
515 const char Nl80211AttributeMaxMatchSets::kNameString[] =
516     "NL80211_ATTR_MAX_MATCH_SETS";
517 
518 const int Nl80211AttributeMaxNumPmkids::kName = NL80211_ATTR_MAX_NUM_PMKIDS;
519 const char Nl80211AttributeMaxNumPmkids::kNameString[] =
520     "NL80211_ATTR_MAX_NUM_PMKIDS";
521 
522 const int Nl80211AttributeMaxNumScanSsids::kName =
523     NL80211_ATTR_MAX_NUM_SCAN_SSIDS;
524 const char Nl80211AttributeMaxNumScanSsids::kNameString[] =
525     "NL80211_ATTR_MAX_NUM_SCAN_SSIDS";
526 
527 const int Nl80211AttributeMaxNumSchedScanSsids::kName =
528     NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS;
529 const char Nl80211AttributeMaxNumSchedScanSsids::kNameString[] =
530     "NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS";
531 
532 const int Nl80211AttributeMaxRemainOnChannelDuration::kName =
533     NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION;
534 const char Nl80211AttributeMaxRemainOnChannelDuration::kNameString[] =
535     "NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION";
536 
537 const int Nl80211AttributeMaxScanIeLen::kName = NL80211_ATTR_MAX_SCAN_IE_LEN;
538 const char Nl80211AttributeMaxScanIeLen::kNameString[] =
539     "NL80211_ATTR_MAX_SCAN_IE_LEN";
540 
541 const int Nl80211AttributeMaxSchedScanIeLen::kName =
542     NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN;
543 const char Nl80211AttributeMaxSchedScanIeLen::kNameString[] =
544     "NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN";
545 
546 const int Nl80211AttributeOffchannelTxOk::kName = NL80211_ATTR_OFFCHANNEL_TX_OK;
547 const char Nl80211AttributeOffchannelTxOk::kNameString[] =
548     "NL80211_ATTR_OFFCHANNEL_TX_OK";
549 
550 const int Nl80211AttributeProbeRespOffload::kName =
551     NL80211_ATTR_PROBE_RESP_OFFLOAD;
552 const char Nl80211AttributeProbeRespOffload::kNameString[] =
553     "NL80211_ATTR_PROBE_RESP_OFFLOAD";
554 
555 const int Nl80211AttributeReasonCode::kName = NL80211_ATTR_REASON_CODE;
556 const char Nl80211AttributeReasonCode::kNameString[] =
557     "NL80211_ATTR_REASON_CODE";
558 
559 const int Nl80211AttributeRegAlpha2::kName = NL80211_ATTR_REG_ALPHA2;
560 const char Nl80211AttributeRegAlpha2::kNameString[] = "NL80211_ATTR_REG_ALPHA2";
561 
562 const int Nl80211AttributeRegInitiator::kName = NL80211_ATTR_REG_INITIATOR;
563 const char Nl80211AttributeRegInitiator::kNameString[] =
564     "NL80211_ATTR_REG_INITIATOR";
565 
566 // The RegInitiator type can be interpreted as either a U8 or U32 depending
567 // on context.  Override the default InitFromValue implementation to be
568 // flexible to either encoding.
InitFromValue(const ByteString & input)569 bool Nl80211AttributeRegInitiator::InitFromValue(const ByteString& input) {
570   uint8_t u8_data;
571   if (input.GetLength() != sizeof(u8_data))
572     return NetlinkU32Attribute::InitFromValue(input);
573 
574   if (!input.CopyData(sizeof(u8_data), &u8_data)) {
575     LOG(ERROR) << "Invalid |input| parameter.";
576     return false;
577   }
578 
579   SetU32Value(static_cast<uint32_t>(u8_data));
580   return NetlinkAttribute::InitFromValue(input);
581 }
582 
583 const int Nl80211AttributeRegRules::kName = NL80211_ATTR_REG_RULES;
584 const char Nl80211AttributeRegRules::kNameString[] = "NL80211_ATTR_REG_RULES";
585 
Nl80211AttributeRegRules()586 Nl80211AttributeRegRules::Nl80211AttributeRegRules()
587     : NetlinkNestedAttribute(kName, kNameString) {
588   NestedData reg_rules(kTypeNested, "NL80211_REG_RULES", true);
589   reg_rules.deeper_nesting.insert(
590       AttrDataPair(__NL80211_REG_RULE_ATTR_INVALID,
591                    NestedData(kTypeU32, "__NL80211_ATTR_REG_RULE_INVALID",
592                               false)));
593   reg_rules.deeper_nesting.insert(
594       AttrDataPair(NL80211_ATTR_REG_RULE_FLAGS,
595                    NestedData(kTypeU32, "NL80211_ATTR_REG_RULE_FLAGS",
596                               false)));
597   reg_rules.deeper_nesting.insert(
598       AttrDataPair(NL80211_ATTR_FREQ_RANGE_START,
599                    NestedData(kTypeU32, "NL80211_ATTR_FREQ_RANGE_START",
600                               false)));
601   reg_rules.deeper_nesting.insert(
602       AttrDataPair(NL80211_ATTR_FREQ_RANGE_END,
603                    NestedData(kTypeU32, "NL80211_ATTR_FREQ_RANGE_END",
604                               false)));
605   reg_rules.deeper_nesting.insert(
606       AttrDataPair(NL80211_ATTR_FREQ_RANGE_MAX_BW,
607                    NestedData(kTypeU32, "NL80211_ATTR_FREQ_RANGE_MAX_BW",
608                               false)));
609   reg_rules.deeper_nesting.insert(
610       AttrDataPair(NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
611                    NestedData(kTypeU32, "NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN",
612                               false)));
613   reg_rules.deeper_nesting.insert(
614       AttrDataPair(NL80211_ATTR_POWER_RULE_MAX_EIRP,
615                    NestedData(kTypeU32, "NL80211_ATTR_POWER_RULE_MAX_EIRP",
616                               false)));
617 
618   nested_template_.insert(AttrDataPair(kArrayAttrEnumVal, reg_rules));
619 }
620 
621 const int Nl80211AttributeRegType::kName = NL80211_ATTR_REG_TYPE;
622 const char Nl80211AttributeRegType::kNameString[] = "NL80211_ATTR_REG_TYPE";
623 
624 const int Nl80211AttributeRespIe::kName = NL80211_ATTR_RESP_IE;
625 const char Nl80211AttributeRespIe::kNameString[] = "NL80211_ATTR_RESP_IE";
626 
627 const int Nl80211AttributeRoamSupport::kName = NL80211_ATTR_ROAM_SUPPORT;
628 const char Nl80211AttributeRoamSupport::kNameString[] =
629     "NL80211_ATTR_ROAM_SUPPORT";
630 
631 const int Nl80211AttributeScanFrequencies::kName =
632     NL80211_ATTR_SCAN_FREQUENCIES;
633 const char Nl80211AttributeScanFrequencies::kNameString[] =
634     "NL80211_ATTR_SCAN_FREQUENCIES";
635 
Nl80211AttributeScanFrequencies()636 Nl80211AttributeScanFrequencies::Nl80211AttributeScanFrequencies()
637     : NetlinkNestedAttribute(kName, kNameString) {
638   nested_template_.insert(AttrDataPair(
639       kArrayAttrEnumVal, NestedData(kTypeU32, "NL80211_SCAN_FREQ", true)));
640 }
641 
642 const int Nl80211AttributeScanSsids::kName = NL80211_ATTR_SCAN_SSIDS;
643 const char Nl80211AttributeScanSsids::kNameString[] = "NL80211_ATTR_SCAN_SSIDS";
644 
Nl80211AttributeScanSsids()645 Nl80211AttributeScanSsids::Nl80211AttributeScanSsids()
646     : NetlinkNestedAttribute(kName, kNameString) {
647   nested_template_.insert(AttrDataPair(
648       kArrayAttrEnumVal, NestedData(kTypeString, "NL80211_SCAN_SSID", true)));
649 }
650 
651 const int Nl80211AttributeStaInfo::kName = NL80211_ATTR_STA_INFO;
652 const char Nl80211AttributeStaInfo::kNameString[] = "NL80211_ATTR_STA_INFO";
653 
Nl80211AttributeStaInfo()654 Nl80211AttributeStaInfo::Nl80211AttributeStaInfo()
655     : NetlinkNestedAttribute(kName, kNameString) {
656   NestedData tx_rates(kTypeNested, "NL80211_STA_INFO_TX_BITRATE", false);
657   tx_rates.deeper_nesting.insert(
658       AttrDataPair(__NL80211_RATE_INFO_INVALID,
659                    NestedData(kTypeU32, "__NL80211_RATE_INFO_INVALID", false)));
660   tx_rates.deeper_nesting.insert(
661       AttrDataPair(NL80211_RATE_INFO_BITRATE,
662                    NestedData(kTypeU16, "NL80211_RATE_INFO_BITRATE", false)));
663   tx_rates.deeper_nesting.insert(
664       AttrDataPair(NL80211_RATE_INFO_MCS,
665                    NestedData(kTypeU8, "NL80211_RATE_INFO_MCS", false)));
666   tx_rates.deeper_nesting.insert(AttrDataPair(
667       NL80211_RATE_INFO_40_MHZ_WIDTH,
668       NestedData(kTypeFlag, "NL80211_RATE_INFO_40_MHZ_WIDTH", false)));
669   tx_rates.deeper_nesting.insert(
670       AttrDataPair(NL80211_RATE_INFO_SHORT_GI,
671                    NestedData(kTypeFlag, "NL80211_RATE_INFO_SHORT_GI", false)));
672   tx_rates.deeper_nesting.insert(
673       AttrDataPair(NL80211_RATE_INFO_BITRATE32,
674                    NestedData(kTypeU32, "NL80211_RATE_INFO_BITRATE32", false)));
675   tx_rates.deeper_nesting.insert(
676       AttrDataPair(NL80211_RATE_INFO_VHT_MCS,
677                    NestedData(kTypeU8, "NL80211_RATE_INFO_VHT_MCS", false)));
678   tx_rates.deeper_nesting.insert(
679       AttrDataPair(NL80211_RATE_INFO_VHT_NSS,
680                    NestedData(kTypeU8, "NL80211_RATE_INFO_VHT_NSS", false)));
681   tx_rates.deeper_nesting.insert(AttrDataPair(
682       NL80211_RATE_INFO_80_MHZ_WIDTH,
683       NestedData(kTypeFlag, "NL80211_RATE_INFO_80_MHZ_WIDTH", false)));
684   tx_rates.deeper_nesting.insert(AttrDataPair(
685       NL80211_RATE_INFO_80P80_MHZ_WIDTH,
686       NestedData(kTypeFlag, "NL80211_RATE_INFO_80P80_MHZ_WIDTH", false)));
687   tx_rates.deeper_nesting.insert(AttrDataPair(
688       NL80211_RATE_INFO_160_MHZ_WIDTH,
689       NestedData(kTypeFlag, "NL80211_RATE_INFO_160_MHZ_WIDTH", false)));
690 
691   NestedData rx_rates(kTypeNested, "NL80211_STA_INFO_RX_BITRATE", false);
692   rx_rates.deeper_nesting = tx_rates.deeper_nesting;
693 
694   NestedData bss(kTypeNested, "NL80211_STA_INFO_BSS_PARAM", false);
695   bss.deeper_nesting.insert(AttrDataPair(
696       __NL80211_STA_BSS_PARAM_INVALID,
697       NestedData(kTypeU32, "__NL80211_STA_BSS_PARAM_INVALID", false)));
698   bss.deeper_nesting.insert(AttrDataPair(
699       NL80211_STA_BSS_PARAM_CTS_PROT,
700       NestedData(kTypeFlag, "NL80211_STA_BSS_PARAM_CTS_PROT", false)));
701   bss.deeper_nesting.insert(AttrDataPair(
702       NL80211_STA_BSS_PARAM_SHORT_PREAMBLE,
703       NestedData(kTypeFlag, "NL80211_STA_BSS_PARAM_SHORT_PREAMBLE", false)));
704   bss.deeper_nesting.insert(AttrDataPair(
705       NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME,
706       NestedData(kTypeFlag, "NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME", false)));
707   bss.deeper_nesting.insert(AttrDataPair(
708       NL80211_STA_BSS_PARAM_DTIM_PERIOD,
709       NestedData(kTypeU8, "NL80211_STA_BSS_PARAM_DTIM_PERIOD", false)));
710   bss.deeper_nesting.insert(AttrDataPair(
711       NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
712       NestedData(kTypeU16, "NL80211_STA_BSS_PARAM_BEACON_INTERVAL", false)));
713 
714   nested_template_.insert(
715       AttrDataPair(__NL80211_STA_INFO_INVALID,
716                    NestedData(kTypeU32, "__NL80211_STA_INFO_INVALID", false)));
717   nested_template_.insert(AttrDataPair(
718       NL80211_STA_INFO_INACTIVE_TIME,
719       NestedData(kTypeU32, "NL80211_STA_INFO_INACTIVE_TIME", false)));
720   nested_template_.insert(
721       AttrDataPair(NL80211_STA_INFO_RX_BYTES,
722                    NestedData(kTypeU32, "NL80211_STA_INFO_RX_BYTES", false)));
723   nested_template_.insert(
724       AttrDataPair(NL80211_STA_INFO_TX_BYTES,
725                    NestedData(kTypeU32, "NL80211_STA_INFO_TX_BYTES", false)));
726   nested_template_.insert(
727       AttrDataPair(NL80211_STA_INFO_RX_BYTES64,
728                    NestedData(kTypeU64, "NL80211_STA_INFO_RX_BYTES64", false)));
729   nested_template_.insert(
730       AttrDataPair(NL80211_STA_INFO_TX_BYTES64,
731                    NestedData(kTypeU64, "NL80211_STA_INFO_TX_BYTES64", false)));
732   nested_template_.insert(
733       AttrDataPair(NL80211_STA_INFO_LLID,
734                    NestedData(kTypeU16, "NL80211_STA_INFO_LLID", false)));
735   nested_template_.insert(
736       AttrDataPair(NL80211_STA_INFO_PLID,
737                    NestedData(kTypeU16, "NL80211_STA_INFO_PLID", false)));
738   nested_template_.insert(
739       AttrDataPair(NL80211_STA_INFO_PLINK_STATE,
740                    NestedData(kTypeU8, "NL80211_STA_INFO_PLINK_STATE", false)));
741   nested_template_.insert(
742       AttrDataPair(NL80211_STA_INFO_SIGNAL,
743                    NestedData(kTypeU8, "NL80211_STA_INFO_SIGNAL", false)));
744   nested_template_.insert(AttrDataPair(NL80211_STA_INFO_TX_BITRATE, tx_rates));
745   nested_template_.insert(
746       AttrDataPair(NL80211_STA_INFO_RX_PACKETS,
747                    NestedData(kTypeU32, "NL80211_STA_INFO_RX_PACKETS", false)));
748   nested_template_.insert(
749       AttrDataPair(NL80211_STA_INFO_TX_PACKETS,
750                    NestedData(kTypeU32, "NL80211_STA_INFO_TX_PACKETS", false)));
751   nested_template_.insert(
752       AttrDataPair(NL80211_STA_INFO_TX_RETRIES,
753                    NestedData(kTypeU32, "NL80211_STA_INFO_TX_RETRIES", false)));
754   nested_template_.insert(
755       AttrDataPair(NL80211_STA_INFO_TX_FAILED,
756                    NestedData(kTypeU32, "NL80211_STA_INFO_TX_FAILED", false)));
757   nested_template_.insert(
758       AttrDataPair(NL80211_STA_INFO_SIGNAL_AVG,
759                    NestedData(kTypeU8, "NL80211_STA_INFO_SIGNAL_AVG", false)));
760   nested_template_.insert(AttrDataPair(NL80211_STA_INFO_RX_BITRATE, rx_rates));
761   nested_template_.insert(AttrDataPair(NL80211_STA_INFO_BSS_PARAM, bss));
762   nested_template_.insert(AttrDataPair(
763       NL80211_STA_INFO_CONNECTED_TIME,
764       NestedData(kTypeU32, "NL80211_STA_INFO_CONNECTED_TIME", false)));
765   nested_template_.insert(
766       AttrDataPair(NL80211_STA_INFO_STA_FLAGS,
767                    NestedData(kTypeU64, "NL80211_STA_INFO_STA_FLAGS", false)));
768   nested_template_.insert(
769       AttrDataPair(NL80211_STA_INFO_BEACON_LOSS,
770                    NestedData(kTypeU32, "NL80211_STA_INFO_BEACON_LOSS",
771                    false)));
772 }
773 
774 const int Nl80211AttributeSurveyInfo::kName = NL80211_ATTR_SURVEY_INFO;
775 const char Nl80211AttributeSurveyInfo::kNameString[] =
776                                  "NL80211_ATTR_SURVEY_INFO";
777 
Nl80211AttributeSurveyInfo()778 Nl80211AttributeSurveyInfo::Nl80211AttributeSurveyInfo()
779     : NetlinkNestedAttribute(kName, kNameString) {
780   nested_template_.insert(
781       AttrDataPair(NL80211_SURVEY_INFO_FREQUENCY,
782          NestedData(kTypeU32, "NL80211_SURVEY_INFO_FREQUENCY", false)));
783   nested_template_.insert(
784       AttrDataPair(NL80211_SURVEY_INFO_NOISE,
785          NestedData(kTypeU8, "NL80211_SURVEY_INFO_NOISE", false)));
786   nested_template_.insert(
787       AttrDataPair(NL80211_SURVEY_INFO_IN_USE,
788          NestedData(kTypeFlag, "NL80211_SURVEY_INFO_IN_USE", false)));
789   nested_template_.insert(
790       AttrDataPair(NL80211_SURVEY_INFO_CHANNEL_TIME,
791          NestedData(kTypeU64, "NL80211_SURVEY_INFO_CHANNEL_TIME", false)));
792   nested_template_.insert(
793       AttrDataPair(NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
794          NestedData(kTypeU64, "NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY", false)));
795   nested_template_.insert(
796       AttrDataPair(NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
797          NestedData(kTypeU64,
798              "NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY", false)));
799   nested_template_.insert(
800       AttrDataPair(NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
801          NestedData(kTypeU64, "NL80211_SURVEY_INFO_CHANNEL_TIME_RX", false)));
802   nested_template_.insert(
803       AttrDataPair(NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
804          NestedData(kTypeU64, "NL80211_SURVEY_INFO_CHANNEL_TIME_TX", false)));
805 }
806 
807 const int Nl80211AttributeSupportedIftypes::kName =
808     NL80211_ATTR_SUPPORTED_IFTYPES;
809 const char Nl80211AttributeSupportedIftypes::kNameString[] =
810     "NL80211_ATTR_SUPPORTED_IFTYPES";
Nl80211AttributeSupportedIftypes()811 Nl80211AttributeSupportedIftypes::Nl80211AttributeSupportedIftypes()
812     : NetlinkNestedAttribute(kName, kNameString) {
813   nested_template_.insert(AttrDataPair(
814       kArrayAttrEnumVal,
815       NestedData(kTypeFlag, "NL80211_SUPPORTED_IFTYPES_IFTYPE", true)));
816 }
817 
818 const int Nl80211AttributeStatusCode::kName = NL80211_ATTR_STATUS_CODE;
819 const char Nl80211AttributeStatusCode::kNameString[] =
820     "NL80211_ATTR_STATUS_CODE";
821 
822 const int Nl80211AttributeSupportApUapsd::kName = NL80211_ATTR_SUPPORT_AP_UAPSD;
823 const char Nl80211AttributeSupportApUapsd::kNameString[] =
824     "NL80211_ATTR_SUPPORT_AP_UAPSD";
825 
826 const int Nl80211AttributeSupportIbssRsn::kName = NL80211_ATTR_SUPPORT_IBSS_RSN;
827 const char Nl80211AttributeSupportIbssRsn::kNameString[] =
828     "NL80211_ATTR_SUPPORT_IBSS_RSN";
829 
830 const int Nl80211AttributeSupportMeshAuth::kName =
831     NL80211_ATTR_SUPPORT_MESH_AUTH;
832 const char Nl80211AttributeSupportMeshAuth::kNameString[] =
833     "NL80211_ATTR_SUPPORT_MESH_AUTH";
834 
835 const int Nl80211AttributeTdlsExternalSetup::kName =
836     NL80211_ATTR_TDLS_EXTERNAL_SETUP;
837 const char Nl80211AttributeTdlsExternalSetup::kNameString[] =
838     "NL80211_ATTR_TDLS_EXTERNAL_SETUP";
839 
840 const int Nl80211AttributeTdlsSupport::kName = NL80211_ATTR_TDLS_SUPPORT;
841 const char Nl80211AttributeTdlsSupport::kNameString[] =
842     "NL80211_ATTR_TDLS_SUPPORT";
843 
844 const int Nl80211AttributeTimedOut::kName = NL80211_ATTR_TIMED_OUT;
845 const char Nl80211AttributeTimedOut::kNameString[] = "NL80211_ATTR_TIMED_OUT";
846 
847 const int Nl80211AttributeWiphyAntennaAvailRx::kName =
848     NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX;
849 const char Nl80211AttributeWiphyAntennaAvailRx::kNameString[] =
850     "NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX";
851 
852 const int Nl80211AttributeWiphyAntennaAvailTx::kName =
853     NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX;
854 const char Nl80211AttributeWiphyAntennaAvailTx::kNameString[] =
855     "NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX";
856 
857 const int Nl80211AttributeWiphyAntennaRx::kName = NL80211_ATTR_WIPHY_ANTENNA_RX;
858 const char Nl80211AttributeWiphyAntennaRx::kNameString[] =
859     "NL80211_ATTR_WIPHY_ANTENNA_RX";
860 
861 const int Nl80211AttributeWiphyAntennaTx::kName = NL80211_ATTR_WIPHY_ANTENNA_TX;
862 const char Nl80211AttributeWiphyAntennaTx::kNameString[] =
863     "NL80211_ATTR_WIPHY_ANTENNA_TX";
864 
865 const int Nl80211AttributeWiphyCoverageClass::kName =
866     NL80211_ATTR_WIPHY_COVERAGE_CLASS;
867 const char Nl80211AttributeWiphyCoverageClass::kNameString[] =
868     "NL80211_ATTR_WIPHY_COVERAGE_CLASS";
869 
870 const int Nl80211AttributeWiphyFragThreshold::kName =
871     NL80211_ATTR_WIPHY_FRAG_THRESHOLD;
872 const char Nl80211AttributeWiphyFragThreshold::kNameString[] =
873     "NL80211_ATTR_WIPHY_FRAG_THRESHOLD";
874 
875 const int Nl80211AttributeWiphyFreq::kName = NL80211_ATTR_WIPHY_FREQ;
876 const char Nl80211AttributeWiphyFreq::kNameString[] = "NL80211_ATTR_WIPHY_FREQ";
877 
878 const int Nl80211AttributeChannelType::kName = NL80211_ATTR_WIPHY_CHANNEL_TYPE;
879 const char Nl80211AttributeChannelType::kNameString[] =
880     "NL80211_ATTR_WIPHY_CHANNEL_TYPE";
881 
882 const int Nl80211AttributeChannelWidth::kName = NL80211_ATTR_CHANNEL_WIDTH;
883 const char Nl80211AttributeChannelWidth::kNameString[] =
884     "NL80211_ATTR_CHANNEL_WIDTH";
885 
886 const int Nl80211AttributeCenterFreq1::kName = NL80211_ATTR_CENTER_FREQ1;
887 const char Nl80211AttributeCenterFreq1::kNameString[] =
888     "NL80211_ATTR_CENTER_FREQ1";
889 
890 const int Nl80211AttributeCenterFreq2::kName = NL80211_ATTR_CENTER_FREQ2;
891 const char Nl80211AttributeCenterFreq2::kNameString[] =
892     "NL80211_ATTR_CENTER_FREQ2";
893 
894 const int Nl80211AttributeWiphy::kName = NL80211_ATTR_WIPHY;
895 const char Nl80211AttributeWiphy::kNameString[] = "NL80211_ATTR_WIPHY";
896 
897 const int Nl80211AttributeWiphyName::kName = NL80211_ATTR_WIPHY_NAME;
898 const char Nl80211AttributeWiphyName::kNameString[] = "NL80211_ATTR_WIPHY_NAME";
899 
900 const int Nl80211AttributeWiphyRetryLong::kName = NL80211_ATTR_WIPHY_RETRY_LONG;
901 const char Nl80211AttributeWiphyRetryLong::kNameString[] =
902     "NL80211_ATTR_WIPHY_RETRY_LONG";
903 
904 const int Nl80211AttributeWiphyRetryShort::kName =
905     NL80211_ATTR_WIPHY_RETRY_SHORT;
906 const char Nl80211AttributeWiphyRetryShort::kNameString[] =
907     "NL80211_ATTR_WIPHY_RETRY_SHORT";
908 
909 const int Nl80211AttributeWiphyRtsThreshold::kName =
910     NL80211_ATTR_WIPHY_RTS_THRESHOLD;
911 const char Nl80211AttributeWiphyRtsThreshold::kNameString[] =
912     "NL80211_ATTR_WIPHY_RTS_THRESHOLD";
913 
914 }  // namespace shill
915