shill: Make nl80211 broadcast callback a list of callbacks.
This will allow multiple callbacks to be called when an nl80211 message
is received. This allows a user to add a callback without displacing
others (e.g. disconnect metrics).
BUG=chromium-os:35468
TEST=unit tests, manual tests
Change-Id: I19d6cfac5754ea1d2a699de80d4465c49fec888c
Reviewed-on: https://gerrit.chromium.org/gerrit/36061
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: Wade Guthrie <wdg@google.com>
Tested-by: Wade Guthrie <wdg@google.com>
diff --git a/config80211_unittest.cc b/config80211_unittest.cc
index 153542e..4bcf6f2 100644
--- a/config80211_unittest.cc
+++ b/config80211_unittest.cc
@@ -11,22 +11,24 @@
#include "shill/config80211.h"
+#include <list>
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <netlink/attr.h>
#include <netlink/netlink.h>
-#include <string>
-#include <vector>
-
-#include <base/bind.h>
-
+#include "shill/mock_callback80211_object.h"
#include "shill/mock_nl80211_socket.h"
#include "shill/nl80211_socket.h"
#include "shill/user_bound_nlmessage.h"
using base::Bind;
using base::Unretained;
+using std::list;
using std::string;
using std::vector;
using testing::_;
@@ -261,10 +263,10 @@
// ff ff c0 3f 0e 77 e8 7f c0 3f 0e 77 e8 7f c0 0e 02 00]
const unsigned char kDeauthenticateFrame[] = {
- 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
- 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
- 0x02, 0x00
+ 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
+ 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
+ 0x02, 0x00
};
const unsigned char kNL80211_CMD_DEAUTHENTICATE[] = {
@@ -335,7 +337,7 @@
0x03, 0x00, 0x00, 0x00,
};
-} // namespace {}
+} // namespace
class Config80211Test : public Test {
public:
@@ -363,33 +365,34 @@
Config80211::Callback callback_;
};
-MATCHER_P(IsEqualToCallback, callback, "") {
- const Config80211::Callback *arg_cb =
- reinterpret_cast<const Config80211::Callback *>(arg);
- const Config80211::Callback *callback_cb =
- reinterpret_cast<const Config80211::Callback *>(callback);
- if (arg_cb == callback_cb)
- return true;
- if (arg_cb == reinterpret_cast<const Config80211::Callback *>(NULL))
+// Checks a config80211 parameter to make sure it contains |callback_arg|
+// in its list of broadcast callbacks.
+MATCHER_P(ContainsCallback, callback_arg, "") {
+ if (arg == reinterpret_cast<void *>(NULL)) {
+ LOG(WARNING) << "NULL parameter";
return false;
- if (callback_cb == reinterpret_cast<const Config80211::Callback *>(NULL))
- return arg_cb->is_null();
- return arg_cb->Equals(*callback_cb);
+ }
+ const Config80211 *config80211 = static_cast<Config80211 *>(arg);
+ const Config80211::Callback callback =
+ static_cast<const Config80211::Callback>(callback_arg);
+
+ return config80211->FindBroadcastCallback(callback);
}
TEST_F(Config80211Test, AddLinkTest) {
SetupConfig80211Object();
- // Create a default callback.
+ // Create a broadcast callback.
TestCallbackObject callback_object;
// Install the callback and subscribe to events using it, wifi down
- // (shouldn't actually send the subscription request).
+ // (shouldn't actually send the subscription request until wifi comes up).
EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
- EXPECT_CALL(socket_, SetNetlinkCallback(_,_)).Times(0);
+ EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
- config80211_->SetDefaultCallback(callback_object.GetCallback());
+ EXPECT_TRUE(config80211_->AddBroadcastCallback(
+ callback_object.GetCallback()));
Config80211::EventType scan_event = Config80211::kEventTypeScan;
string scan_event_string;
EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string));
@@ -401,14 +404,14 @@
EXPECT_CALL(socket_, DisableSequenceChecking())
.WillOnce(Return(true));
EXPECT_CALL(socket_, SetNetlinkCallback(
- _, IsEqualToCallback(&callback_object.GetCallback())))
+ _, ContainsCallback(callback_object.GetCallback())))
.WillOnce(Return(true));
config80211_->SetWifiState(Config80211::kWifiUp);
// Second subscribe, same event (should do nothing).
EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
- EXPECT_CALL(socket_, SetNetlinkCallback(_,_)).Times(0);
+ EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
// Bring the wifi back down.
@@ -430,7 +433,7 @@
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(socket_, SetNetlinkCallback(
- _, IsEqualToCallback(&callback_object.GetCallback())))
+ _, ContainsCallback(callback_object.GetCallback())))
.Times(2)
.WillRepeatedly(Return(true));
config80211_->SetWifiState(Config80211::kWifiUp);