shill: Add type-specific children of Nl80211Attribute type.
This checkin adds all the type-specific children of the Nl80211Attribute
type without actually changing any of the code that's called (that's
planned for a later checkin).
The next checkin includes all the attributes necessary to use
Nl80211Attribute. After that, we'll go for the functionality changes
(which, BTW, passes unittests).
BUG=chromium-os:36637
TEST=unittests.
Change-Id: Ib3944e3b18faeec322ea93cd989daa9bbeb0c0c7
Reviewed-on: https://gerrit.chromium.org/gerrit/39319
Commit-Ready: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/callback80211_metrics.cc b/callback80211_metrics.cc
index 27b5bc3..fb5d0f1 100644
--- a/callback80211_metrics.cc
+++ b/callback80211_metrics.cc
@@ -29,12 +29,9 @@
Metrics::kDisconnectedByAp : Metrics::kDisconnectedNotByAp;
uint16_t reason = static_cast<uint16_t>(
IEEE_80211::kReasonCodeInvalid);
- void *rawdata = NULL;
- int frame_byte_count = 0;
- if (message.GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
- &frame_byte_count)) {
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
- Nl80211Frame frame(frame_data, frame_byte_count);
+ ByteString rawdata;
+ if (message.GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata)) {
+ Nl80211Frame frame(rawdata);
reason = frame.reason();
}
IEEE_80211::WiFiReasonCode reason_enum =
diff --git a/callback80211_object.h b/callback80211_object.h
index 68152c2..120cb1c 100644
--- a/callback80211_object.h
+++ b/callback80211_object.h
@@ -8,12 +8,7 @@
#ifndef SHILL_CALLBACK80211_OBJECT_H
#define SHILL_CALLBACK80211_OBJECT_H
-#include <iomanip>
-#include <map>
-#include <string>
-
#include <base/basictypes.h>
-#include <base/bind.h>
#include <base/memory/weak_ptr.h>
#include "shill/config80211.h"
diff --git a/config80211_unittest.cc b/config80211_unittest.cc
index d6faf00..d9e93c8 100644
--- a/config80211_unittest.cc
+++ b/config80211_unittest.cc
@@ -11,6 +11,12 @@
#include "shill/config80211.h"
+#include <net/if.h>
+#include <netlink/attr.h>
+#include <netlink/genl/genl.h>
+#include <netlink/msg.h>
+#include <netlink/netlink.h>
+
#include <list>
#include <string>
#include <vector>
@@ -18,15 +24,11 @@
#include <base/bind.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include <net/if.h>
-#include <netlink/attr.h>
-#include <netlink/genl/genl.h>
-#include <netlink/msg.h>
-#include <netlink/netlink.h>
#include "shill/kernel_bound_nlmessage.h"
#include "shill/mock_callback80211_object.h"
#include "shill/mock_nl80211_socket.h"
+#include "shill/nl80211_attribute.h"
#include "shill/nl80211_socket.h"
#include "shill/user_bound_nlmessage.h"
@@ -706,16 +708,12 @@
}
{
- void *rawdata = NULL;
- int frame_byte_count = 0;
- EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
- &frame_byte_count));
- EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
- Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame));
-
+ ByteString rawdata;
+ EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata));
+ EXPECT_FALSE(rawdata.IsEmpty());
+ Nl80211Frame frame(rawdata);
+ Nl80211Frame expected_frame(ByteString(kAuthenticateFrame,
+ sizeof(kAuthenticateFrame)));
EXPECT_TRUE(frame.IsEqual(expected_frame));
}
}
@@ -741,16 +739,12 @@
}
{
- void *rawdata = NULL;
- int frame_byte_count = 0;
- EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
- &frame_byte_count));
- EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
- Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame));
-
+ ByteString rawdata;
+ EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata));
+ EXPECT_FALSE(rawdata.IsEmpty());
+ Nl80211Frame frame(rawdata);
+ Nl80211Frame expected_frame(ByteString(kAssociateFrame,
+ sizeof(kAssociateFrame)));
EXPECT_TRUE(frame.IsEqual(expected_frame));
}
}
@@ -812,17 +806,12 @@
}
{
- void *rawdata = NULL;
- int frame_byte_count = 0;
- EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
- &frame_byte_count));
- EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
- Nl80211Frame expected_frame(kDeauthenticateFrame,
- sizeof(kDeauthenticateFrame));
-
+ ByteString rawdata;
+ EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata));
+ EXPECT_FALSE(rawdata.IsEmpty());
+ Nl80211Frame frame(rawdata);
+ Nl80211Frame expected_frame(ByteString(kDeauthenticateFrame,
+ sizeof(kDeauthenticateFrame)));
EXPECT_TRUE(frame.IsEqual(expected_frame));
}
}
@@ -905,7 +894,7 @@
EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
- EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
+ EXPECT_EQ(Nl80211Attribute::NlaGetU32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
kExpectedCqmNotAcked);
}
}
@@ -932,16 +921,12 @@
}
{
- void *rawdata = NULL;
- int frame_byte_count = 0;
- EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
- &frame_byte_count));
- EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
- Nl80211Frame expected_frame(kDisassociateFrame, sizeof(kDisassociateFrame));
-
+ ByteString rawdata;
+ EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata));
+ EXPECT_FALSE(rawdata.IsEmpty());
+ Nl80211Frame frame(rawdata);
+ Nl80211Frame expected_frame(ByteString(kDisassociateFrame,
+ sizeof(kDisassociateFrame)));
EXPECT_TRUE(frame.IsEqual(expected_frame));
}
}
diff --git a/kernel_bound_nlmessage.h b/kernel_bound_nlmessage.h
index e4595c4..6a55986 100644
--- a/kernel_bound_nlmessage.h
+++ b/kernel_bound_nlmessage.h
@@ -41,7 +41,7 @@
// CTRL_CMD_GETFAMILY.
explicit KernelBoundNlMessage(uint8 command)
: command_(command),
- message_(NULL) {};
+ message_(NULL) {}
virtual ~KernelBoundNlMessage();
// Non-trivial initialization.
diff --git a/nl80211_attribute.cc b/nl80211_attribute.cc
index d54b524..44753bc 100644
--- a/nl80211_attribute.cc
+++ b/nl80211_attribute.cc
@@ -64,7 +64,7 @@
return true;
}
-// Retrieves a pointer to the raw attribute data but not the header.
+// Copies raw attribute data but not the header.
bool Nl80211Attribute::GetRawData(ByteString *output) const {
if (!output) {
LOG(ERROR) << "Null |output| parameter";
@@ -92,21 +92,108 @@
return output;
}
+// Nl80211U8Attribute
+
+const char Nl80211U8Attribute::kMyTypeString[] = "uint8_t";
+const Nl80211Attribute::Type Nl80211U8Attribute::kType =
+ Nl80211Attribute::kTypeU8;
+
+bool Nl80211U8Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint8_t data = NlaGetU8(input);
+ SetU8Value(data);
+ return Nl80211Attribute::InitFromNlAttr(input);
+}
+
+bool Nl80211U8Attribute::GetU8Value(uint8_t *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ *output = value_;
+ return true;
+}
+
+bool Nl80211U8Attribute::SetU8Value(uint8_t new_value) {
+ value_ = new_value;
+ return true;
+}
+
+bool Nl80211U8Attribute::AsString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint8_t value;
+ if (!GetU8Value(&value))
+ return false;
+ *output = StringPrintf("%u", value);
+ return true;
+}
+
+
+// Nl80211U16Attribute
+
+const char Nl80211U16Attribute::kMyTypeString[] = "uint16_t";
+const Nl80211Attribute::Type Nl80211U16Attribute::kType =
+ Nl80211Attribute::kTypeU16;
+
+bool Nl80211U16Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint16_t data = NlaGetU16(input);
+ SetU16Value(data);
+ return Nl80211Attribute::InitFromNlAttr(input);
+}
+
+bool Nl80211U16Attribute::GetU16Value(uint16_t *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ *output = value_;
+ return true;
+}
+
+bool Nl80211U16Attribute::SetU16Value(uint16_t new_value) {
+ value_ = new_value;
+ return true;
+}
+
+bool Nl80211U16Attribute::AsString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint16_t value;
+ if (!GetU16Value(&value))
+ return false;
+ *output = StringPrintf("%u", value);
+ return true;
+}
+
// Nl80211U32Attribute::
const char Nl80211U32Attribute::kMyTypeString[] = "uint32_t";
const Nl80211Attribute::Type Nl80211U32Attribute::kType =
Nl80211Attribute::kTypeU32;
-bool Nl80211U32Attribute::InitFromNlAttr(const nlattr *param) {
- if (!param) {
- LOG(ERROR) << "Null |param| parameter";
+bool Nl80211U32Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
return false;
}
- uint32_t data = nla_get_u32(const_cast<nlattr *>(param));
+ uint32_t data = NlaGetU32(input);
SetU32Value(data);
- return Nl80211Attribute::InitFromNlAttr(param);
+ return Nl80211Attribute::InitFromNlAttr(input);
}
bool Nl80211U32Attribute::GetU32Value(uint32_t *output) const {
@@ -135,19 +222,145 @@
return true;
}
+// Nl80211U64Attribute
+
+const char Nl80211U64Attribute::kMyTypeString[] = "uint64_t";
+const Nl80211Attribute::Type Nl80211U64Attribute::kType =
+ Nl80211Attribute::kTypeU64;
+
+bool Nl80211U64Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint64_t data = NlaGetU64(input);
+ SetU64Value(data);
+ return Nl80211Attribute::InitFromNlAttr(input);
+}
+
+bool Nl80211U64Attribute::GetU64Value(uint64_t *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ *output = value_;
+ return true;
+}
+
+bool Nl80211U64Attribute::SetU64Value(uint64_t new_value) {
+ value_ = new_value;
+ return true;
+}
+
+bool Nl80211U64Attribute::AsString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint64_t value;
+ if (!GetU64Value(&value))
+ return false;
+ *output = StringPrintf("%" PRIu64, value);
+ return true;
+}
+
+// Nl80211FlagAttribute
+
+const char Nl80211FlagAttribute::kMyTypeString[] = "flag";
+const Nl80211Attribute::Type Nl80211FlagAttribute::kType =
+ Nl80211Attribute::kTypeFlag;
+
+bool Nl80211FlagAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ // The existence of the parameter means it's true
+ SetFlagValue(true);
+ return Nl80211Attribute::InitFromNlAttr(input);
+}
+
+
+bool Nl80211FlagAttribute::GetFlagValue(bool *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ *output = value_;
+ return true;
+}
+
+bool Nl80211FlagAttribute::SetFlagValue(bool new_value) {
+ value_ = new_value;
+ return true;
+}
+
+bool Nl80211FlagAttribute::AsString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ bool value;
+ if (!GetFlagValue(&value))
+ return false;
+ *output = StringPrintf("%s", value ? "true" : "false");
+ return true;
+}
+
+// Nl80211StringAttribute
+
+const char Nl80211StringAttribute::kMyTypeString[] = "string";
+const Nl80211Attribute::Type Nl80211StringAttribute::kType =
+ Nl80211Attribute::kTypeString;
+
+bool Nl80211StringAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ SetStringValue(NlaGetString(input));
+ return Nl80211Attribute::InitFromNlAttr(input);
+}
+
+bool Nl80211StringAttribute::GetStringValue(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ *output = value_;
+ return true;
+}
+
+bool Nl80211StringAttribute::SetStringValue(const string new_value) {
+ value_ = new_value;
+ return true;
+}
+
+bool Nl80211StringAttribute::AsString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ return GetStringValue(output);
+}
+
+
// Nl80211RawAttribute
const char Nl80211RawAttribute::kMyTypeString[] = "<raw>";
const Nl80211Attribute::Type Nl80211RawAttribute::kType =
Nl80211Attribute::kTypeRaw;
-bool Nl80211RawAttribute::InitFromNlAttr(const nlattr *param) {
- if (!param) {
- LOG(ERROR) << "Null |param| parameter";
+bool Nl80211RawAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
return false;
}
- return Nl80211Attribute::InitFromNlAttr(param);
+ return Nl80211Attribute::InitFromNlAttr(input);
}
bool Nl80211RawAttribute::GetRawValue(const ByteString **output) const {
@@ -164,6 +377,7 @@
LOG(ERROR) << "Null |output| parameter";
return false;
}
+ // TODO(wdg): Make sure that 'data' is valid.
const uint8_t *raw_data = reinterpret_cast<const uint8_t *>(data());
int total_bytes = nla_len(data());
*output = StringPrintf("%d bytes:", total_bytes);
diff --git a/nl80211_attribute.h b/nl80211_attribute.h
index 9ead8ee..d5916ab 100644
--- a/nl80211_attribute.h
+++ b/nl80211_attribute.h
@@ -6,6 +6,7 @@
#define SHILL_NLATTRIBUTE_H_
#include <linux/nl80211.h>
+#include <netlink/attr.h>
#include <netlink/netlink.h>
#include <map>
@@ -78,7 +79,7 @@
// If successful, returns 'true' and sets *|value| to the raw attribute data
// (after the header) for this attribute. Otherwise, returns 'false' and
// leaves |value| unchanged.
- bool GetRawData(ByteString *value) const;
+ bool GetRawData(ByteString *output) const;
// Fill a string with characters that represents the value of the attribute.
// If no attribute is found or if the type isn't trivially stringizable,
@@ -88,6 +89,24 @@
// Writes the raw attribute data to a string. For debug.
std::string RawToString() const;
+ // Note that |nla_get_*| don't change their arguments but don't declare
+ // themselves as 'const', either. These methods wrap the const castness.
+ static char *NlaGetString(const nlattr *input) {
+ return nla_get_string(const_cast<nlattr *>(input));
+ }
+ static uint8_t NlaGetU8(const nlattr *input) {
+ return nla_get_u8(const_cast<nlattr *>(input));
+ }
+ static uint16_t NlaGetU16(const nlattr *input) {
+ return nla_get_u16(const_cast<nlattr *>(input));
+ }
+ static uint32_t NlaGetU32(const nlattr *input) {
+ return nla_get_u32(const_cast<nlattr *>(input));
+ }
+ static uint64_t NlaGetU64(const nlattr *input) {
+ return nla_get_u64(const_cast<nlattr *>(input));
+ }
+
protected:
// Raw data corresponding to the value in any of the child classes.
// TODO(wdg): When 'data()' is removed, move this to the Nl80211RawAttribute
@@ -104,6 +123,36 @@
// Type-specific sub-classes. These provide their own type-specific data get
// and set functions.
+class Nl80211U8Attribute : public Nl80211Attribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ Nl80211U8Attribute(nl80211_attrs name, const char *name_string)
+ : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
+ bool InitFromNlAttr(const nlattr *data);
+ bool GetU8Value(uint8_t *value) const;
+ bool SetU8Value(uint8_t new_value);
+ bool AsString(std::string *value) const;
+
+ private:
+ uint8_t value_;
+};
+
+class Nl80211U16Attribute : public Nl80211Attribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ Nl80211U16Attribute(nl80211_attrs name, const char *name_string)
+ : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
+ bool InitFromNlAttr(const nlattr *data);
+ bool GetU16Value(uint16_t *value) const;
+ bool SetU16Value(uint16_t new_value);
+ bool AsString(std::string *value) const;
+
+ private:
+ uint16_t value_;
+};
+
class Nl80211U32Attribute : public Nl80211Attribute {
public:
static const char kMyTypeString[];
@@ -119,7 +168,50 @@
uint32_t value_;
};
-// TODO(wdg): Add more data types.
+class Nl80211U64Attribute : public Nl80211Attribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ Nl80211U64Attribute(nl80211_attrs name, const char *name_string)
+ : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
+ bool InitFromNlAttr(const nlattr *data);
+ bool GetU64Value(uint64_t *value) const;
+ bool SetU64Value(uint64_t new_value);
+ bool AsString(std::string *value) const;
+
+ private:
+ uint64_t value_;
+};
+
+class Nl80211FlagAttribute : public Nl80211Attribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ Nl80211FlagAttribute(nl80211_attrs name, const char *name_string)
+ : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
+ bool InitFromNlAttr(const nlattr *data);
+ bool GetFlagValue(bool *value) const;
+ bool SetFlagValue(bool new_value);
+ bool AsString(std::string *value) const;
+
+ private:
+ bool value_;
+};
+
+class Nl80211StringAttribute : public Nl80211Attribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ Nl80211StringAttribute(nl80211_attrs name, const char *name_string)
+ : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
+ bool InitFromNlAttr(const nlattr *data);
+ bool GetStringValue(std::string *value) const;
+ bool SetStringValue(const std::string new_value);
+ bool AsString(std::string *value) const;
+
+ private:
+ std::string value_;
+};
class Nl80211RawAttribute : public Nl80211Attribute {
public:
diff --git a/user_bound_nlmessage.cc b/user_bound_nlmessage.cc
index 9fce829..e822316 100644
--- a/user_bound_nlmessage.cc
+++ b/user_bound_nlmessage.cc
@@ -28,9 +28,9 @@
#include <endian.h>
#include <errno.h>
-#include <netinet/in.h>
#include <linux/nl80211.h>
#include <net/if.h>
+#include <netinet/in.h>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
@@ -47,6 +47,7 @@
#include "shill/ieee80211.h"
#include "shill/logging.h"
+#include "shill/nl80211_attribute.h"
#include "shill/scope_logger.h"
using base::LazyInstance;
@@ -69,7 +70,7 @@
const uint8_t Nl80211Frame::kFrameTypeMask = 0xfc;
const uint32_t UserBoundNlMessage::kIllegalMessage = 0xFFFFFFFF;
-const int UserBoundNlMessage::kEthernetAddressBytes = 6;
+const unsigned int UserBoundNlMessage::kEthernetAddressBytes = 6;
map<uint16_t, string> *UserBoundNlMessage::reason_code_string_ = NULL;
map<uint16_t, string> *UserBoundNlMessage::status_code_string_ = NULL;
@@ -383,23 +384,18 @@
// Returns the raw attribute data but not the header.
bool UserBoundNlMessage::GetRawAttributeData(enum nl80211_attrs name,
- void **value,
- int *length) const {
+ ByteString *value) const {
if (!value) {
LOG(ERROR) << "Null |value| parameter";
return false;
}
-
const nlattr *attr = GetAttribute(name);
if (!attr) {
- *value = NULL;
+ value->Clear();
return false;
}
-
- if (length) {
- *length = nla_len(attr);
- }
- *value = nla_data(attr);
+ *value = ByteString(reinterpret_cast<unsigned char *>(nla_data(attr)),
+ nla_len(attr));
return true;
}
@@ -415,7 +411,7 @@
return false;
}
- value->assign(nla_get_string(const_cast<nlattr *>(attr)));
+ value->assign(Nl80211Attribute::NlaGetString(attr));
return true;
}
@@ -431,7 +427,7 @@
return false;
}
- *value = nla_get_u8(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU8(attr);
return true;
}
@@ -447,7 +443,7 @@
return false;
}
- *value = nla_get_u16(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU16(attr);
return true;
}
@@ -463,7 +459,7 @@
return false;
}
- *value = nla_get_u32(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU32(attr);
return true;
}
@@ -479,7 +475,7 @@
return false;
}
- *value = nla_get_u64(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU64(attr);
return true;
}
@@ -491,13 +487,12 @@
return false;
}
- void *rawdata_void = NULL;
- if (!GetRawAttributeData(name, &rawdata_void, NULL)) {
+ ByteString data;
+ if (!GetRawAttributeData(name, &data)) {
value->assign(kBogusMacAddress);
return false;
}
- const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(rawdata_void);
- value->assign(StringFromMacAddress(rawdata));
+ value->assign(StringFromMacAddress(data.GetConstData()));
return true;
}
@@ -512,20 +507,21 @@
value->clear();
if (AttributeExists(name)) {
- void *rawdata = NULL;
- int len = 0;
- if (GetRawAttributeData(name, &rawdata, &len) && rawdata) {
+ ByteString rawdata;
+ if (GetRawAttributeData(name, &rawdata) && !rawdata.IsEmpty()) {
nlattr *nst = NULL;
- nlattr *attr_data = reinterpret_cast<nlattr *>(rawdata);
+ // |nla_for_each_attr| requires a non-const parameter even though it
+ // doesn't change the data.
+ nlattr *attr_data = reinterpret_cast<nlattr *>(rawdata.GetData());
int rem_nst;
+ int len = rawdata.GetLength();
nla_for_each_attr(nst, attr_data, len, rem_nst) {
- value->push_back(nla_get_u32(nst));
+ value->push_back(Nl80211Attribute::NlaGetU32(nst));
}
}
return true;
}
-
return false;
}
@@ -538,12 +534,14 @@
}
if (AttributeExists(name)) {
- void *rawdata = NULL;
- int len = 0;
- if (GetRawAttributeData(name, &rawdata, &len) && rawdata) {
+ ByteString rawdata;
+ if (GetRawAttributeData(name, &rawdata) && !rawdata.IsEmpty()) {
nlattr *nst = NULL;
- nlattr *data = reinterpret_cast<nlattr *>(rawdata);
+ // |nla_for_each_attr| requires a non-const parameter even though it
+ // doesn't change the data.
+ nlattr *data = reinterpret_cast<nlattr *>(rawdata.GetData());
int rem_nst;
+ int len = rawdata.GetLength();
nla_for_each_attr(nst, data, len, rem_nst) {
value->push_back(StringFromSsid(nla_len(nst),
@@ -553,7 +551,6 @@
}
return true;
}
-
return false;
}
@@ -980,7 +977,7 @@
const nlattr *UserBoundNlMessage::GetAttribute(enum nl80211_attrs name)
const {
- map<enum nl80211_attrs, nlattr *>::const_iterator match;
+ map<nl80211_attrs, nlattr *>::const_iterator match;
match = attributes_.find(name);
// This method may be called to explore the existence of the attribute so
// we'll not emit an error if it's not found.
@@ -1015,13 +1012,9 @@
string UserBoundNlMessage::StringFromFrame(enum nl80211_attrs attr_name) const {
string output;
-
- void *rawdata = NULL;
- int frame_byte_count = 0;
- if (GetRawAttributeData(attr_name, &rawdata, &frame_byte_count) && rawdata) {
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
+ ByteString frame_data;
+ if (GetRawAttributeData(attr_name, &frame_data) && !frame_data.IsEmpty()) {
+ Nl80211Frame frame(frame_data);
frame.ToString(&output);
} else {
output.append(" [no frame]");
@@ -1054,7 +1047,7 @@
} else {
StringAppendF(&output, "%02x", arg[0]);
- for (int i = 1; i < kEthernetAddressBytes ; ++i) {
+ for (unsigned int i = 1; i < kEthernetAddressBytes ; ++i) {
StringAppendF(&output, ":%02x", arg[i]);
}
}
@@ -1131,20 +1124,15 @@
return match->second;
}
-Nl80211Frame::Nl80211Frame(const uint8_t *raw_frame, int frame_byte_count)
+Nl80211Frame::Nl80211Frame(const ByteString &raw_frame)
: frame_type_(kIllegalFrameType), reason_(UINT16_MAX), status_(UINT16_MAX),
- frame_(0), byte_count_(0) {
- if (raw_frame == NULL)
- return;
-
- frame_ = new uint8_t[frame_byte_count];
- memcpy(frame_, raw_frame, frame_byte_count);
- byte_count_ = frame_byte_count;
+ frame_(raw_frame) {
const IEEE_80211::ieee80211_frame *frame =
- reinterpret_cast<const IEEE_80211::ieee80211_frame *>(frame_);
+ reinterpret_cast<const IEEE_80211::ieee80211_frame *>(
+ frame_.GetConstData());
// Now, let's populate the other stuff.
- if (frame_byte_count >= kMinimumFrameByteCount) {
+ if (frame_.GetLength() >= kMinimumFrameByteCount) {
mac_from_ =
UserBoundNlMessage::StringFromMacAddress(&frame->destination_mac[0]);
mac_to_ = UserBoundNlMessage::StringFromMacAddress(&frame->source_mac[0]);
@@ -1171,28 +1159,23 @@
}
}
-Nl80211Frame::~Nl80211Frame() {
- delete [] frame_;
- frame_ = NULL;
-}
-
bool Nl80211Frame::ToString(string *output) const {
if (!output) {
LOG(ERROR) << "NULL |output|";
return false;
}
- if ((byte_count_ == 0) || (frame_ == reinterpret_cast<uint8_t *>(NULL))) {
+ if (frame_.IsEmpty()) {
output->append(" [no frame]");
return true;
}
- if (byte_count_ < kMinimumFrameByteCount) {
+ if (frame_.GetLength() < kMinimumFrameByteCount) {
output->append(" [invalid frame: ");
} else {
StringAppendF(output, " %s -> %s", mac_from_.c_str(), mac_to_.c_str());
- switch (frame_[0] & kFrameTypeMask) {
+ switch (frame_.GetConstData()[0] & kFrameTypeMask) {
case kAssocResponseFrameType:
StringAppendF(output, "; AssocResponse status: %u: %s",
status_,
@@ -1226,8 +1209,9 @@
output->append(" [frame: ");
}
- for (int i = 0; i < byte_count_; ++i) {
- StringAppendF(output, "%02x, ", frame_[i]);
+ const unsigned char *frame = frame_.GetConstData();
+ for (size_t i = 0; i < frame_.GetLength(); ++i) {
+ StringAppendF(output, "%02x, ", frame[i]);
}
output->append("]");
@@ -1235,17 +1219,7 @@
}
bool Nl80211Frame::IsEqual(const Nl80211Frame &other) const {
- if (byte_count_ != other.byte_count_) {
- return false;
- }
-
- for (int i = 0; i < byte_count_; ++i) {
- if (frame_[i] != other.frame_[i]) {
- return false;
- }
- }
-
- return true;
+ return frame_.Equals(other.frame_);
}
@@ -1418,12 +1392,10 @@
}
if (AttributeExists(NL80211_ATTR_KEY_SEQ)) {
- void *rawdata = NULL;
- int length = 0;
- if (GetRawAttributeData(NL80211_ATTR_KEY_SEQ, &rawdata, &length) &&
- rawdata && length == 6) {
- const unsigned char *seq = reinterpret_cast<const unsigned char *>(
- rawdata);
+ ByteString rawdata;
+ if (GetRawAttributeData(NL80211_ATTR_KEY_SEQ, &rawdata) &&
+ rawdata.GetLength() == UserBoundNlMessage::kEthernetAddressBytes) {
+ const unsigned char *seq = rawdata.GetConstData();
StringAppendF(&output, " seq=%02x%02x%02x%02x%02x%02x",
seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]);
}
@@ -1518,6 +1490,8 @@
output.append("connection quality monitor event: ");
const nlattr *const_data = GetAttribute(NL80211_ATTR_CQM);
+ // Note that |nla_parse_nested| doesn't change |const_data| but doesn't
+ // declare itself as 'const', either. Hence the cast.
nlattr *cqm_attr = const_cast<nlattr *>(const_data);
nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
@@ -1530,7 +1504,8 @@
if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]) {
enum nl80211_cqm_rssi_threshold_event rssi_event =
static_cast<enum nl80211_cqm_rssi_threshold_event>(
- nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]));
+ Nl80211Attribute::NlaGetU32(
+ cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]));
if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)
output.append("RSSI went above threshold");
else
@@ -1541,11 +1516,11 @@
GetMacAttributeString(NL80211_ATTR_MAC, &mac);
StringAppendF(&output, "peer %s didn't ACK %" PRIu32 " packets",
mac.c_str(),
- nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]));
+ Nl80211Attribute::NlaGetU32(
+ cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]));
} else {
output.append("unknown event");
}
-
return output;
}
@@ -1620,13 +1595,16 @@
nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
+ // Note that |nla_parse_nested| doesn't change its parameters but doesn't
+ // declare itself as 'const', either. Hence the cast.
if (nla_parse_nested(tb_freq,
NL80211_FREQUENCY_ATTR_MAX,
const_cast<nlattr *>(tb),
const_cast<nla_policy *>(kBeaconFreqPolicy)))
return -EINVAL;
- chan->center_freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
+ chan->center_freq = Nl80211Attribute::NlaGetU32(
+ tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
chan->passive_scan = true;
@@ -1922,7 +1900,7 @@
// Parse the attributes from the nl message payload (which starts at the
// header) into the 'tb' array.
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0), NULL);
+ genlmsg_attrlen(gnlh, 0), NULL);
if (!message->Init(tb, msg)) {
LOG(ERROR) << "Message did not initialize properly";
diff --git a/user_bound_nlmessage.h b/user_bound_nlmessage.h
index f11c90b..43d6089 100644
--- a/user_bound_nlmessage.h
+++ b/user_bound_nlmessage.h
@@ -5,18 +5,18 @@
#ifndef SHILL_USER_BOUND_NLMESSAGE_H_
#define SHILL_USER_BOUND_NLMESSAGE_H_
+#include <linux/nl80211.h>
+
#include <iomanip>
#include <map>
-#include <vector>
#include <string>
+#include <vector>
#include <base/basictypes.h>
#include <base/bind.h>
#include <base/lazy_instance.h>
#include <gtest/gtest.h>
-#include <linux/nl80211.h>
-
#include "shill/nl80211_attribute.h"
struct nlattr;
@@ -27,8 +27,7 @@
// Class for messages received from libnl.
class UserBoundNlMessage {
public:
- // TODO(wdg): break 'Attribute' into its own class to handle
- // nested attributes better.
+ static const unsigned int kEthernetAddressBytes;
// A const iterator to the attribute names in the attributes_ map of a
// UserBoundNlMessage. The purpose, here, is to hide the way that the
@@ -73,8 +72,6 @@
// attributes inside a message object.
AttributeNameIterator *GetAttributeNameIterator() const;
- bool HasAttributes() const { return !attributes_.empty(); }
- uint32_t GetAttributeCount() const { return attributes_.size(); }
// Other ways to see the internals of the object.
@@ -91,13 +88,11 @@
// Returns a string describing the data type of a given attribute.
std::string GetAttributeTypeString(nl80211_attrs name) const;
- // If successful, returns 'true' and sets *|value| to the raw attribute data
- // (after the header) for this attribute and, if |length| is not
- // null, *|length| to the number of bytes of data available. If no
- // attribute by this name exists in this message, sets *|value| to NULL and
- // returns 'false'. If otherwise unsuccessful, returns 'false' and leaves
- // |value| and |length| unchanged.
- bool GetRawAttributeData(nl80211_attrs name, void **value, int *length) const;
+ // If successful, returns 'true' and the raw attribute data (after the
+ // header) into |value| for this attribute. If no attribute by this name
+ // exists in this message, clears |value| and returns 'false'. If otherwise
+ // unsuccessful, returns 'false' and leaves |value| unchanged.
+ bool GetRawAttributeData(nl80211_attrs name, ByteString *value) const;
// Each of these methods set |value| with the value of the specified
// attribute (if the attribute is not found, |value| remains unchanged).
@@ -182,7 +177,6 @@
FRIEND_TEST(Config80211Test, NL80211_CMD_NOTIFY_CQM);
static const uint32_t kIllegalMessage;
- static const int kEthernetAddressBytes;
nlmsghdr *message_;
const uint8 message_type_;
@@ -207,8 +201,7 @@
kIllegalFrameType = 0xff
};
- Nl80211Frame(const uint8_t *frame, int frame_byte_count);
- ~Nl80211Frame();
+ Nl80211Frame(const ByteString &init);
bool ToString(std::string *output) const;
bool IsEqual(const Nl80211Frame &other) const;
uint16_t reason() const { return reason_; }
@@ -223,8 +216,7 @@
uint8_t frame_type_;
uint16_t reason_;
uint16_t status_;
- uint8_t *frame_;
- int byte_count_;
+ ByteString frame_;
DISALLOW_COPY_AND_ASSIGN(Nl80211Frame);
};