blob: 50d403dac5554fbd7eedf18d0bfe226976e37901 [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_NETLINK_MESSAGE_MATCHERS_H_
#define SHILL_NETLINK_MESSAGE_MATCHERS_H_
#include <gmock/gmock.h>
#include "shill/logging.h"
#include "shill/netlink_message.h"
#include "shill/nl80211_message.h"
namespace shill {
// Given a netlink message, verifies that it is an Nl80211Message and verifies,
// further that it is the specified command.
MATCHER_P2(IsNl80211Command, nl80211_message_type, command, "") {
if (!arg) {
LOG(INFO) << "Null message";
return false;
}
if (arg->message_type() != nl80211_message_type) {
LOG(INFO) << "Not an nl80211 message";
return false;
}
const Nl80211Message *msg = dynamic_cast<const Nl80211Message *>(arg);
if (msg->command() != command) {
LOG(INFO) << "Not a message of type " << command
<< " (it's a " << +msg->command() << ")";
return false;
}
return true;
}
// Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
// contains exactly one SSID along with the requisite empty one.
MATCHER_P(HasHiddenSSID, nl80211_message_type, "") {
if (!arg) {
LOG(INFO) << "Null message";
return false;
}
if (arg->message_type() != nl80211_message_type) {
LOG(INFO) << "Not an nl80211 message";
return false;
}
const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
return false;
}
AttributeListConstRefPtr ssids;
if (!msg->const_attributes()->ConstGetNestedAttributeList(
NL80211_ATTR_SCAN_SSIDS, &ssids)) {
LOG(INFO) << "No SSID list in message";
return false;
}
ByteString ssid;
AttributeIdIterator ssid_iter(*ssids);
if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &ssid)) {
LOG(INFO) << "SSID list contains no (hidden) SSIDs";
return false;
}
// A valid Scan containing a single hidden SSID should contain
// two SSID entries: one containing the SSID we are looking for,
// and an empty entry, signifying that we also want to do a
// broadcast probe request for all non-hidden APs as well.
ByteString empty_ssid;
if (ssid_iter.AtEnd()) {
LOG(INFO) << "SSID list doesn't contain an empty SSIDs (but should)";
return false;
}
ssid_iter.Advance();
if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &empty_ssid) ||
!empty_ssid.IsEmpty()) {
LOG(INFO) << "SSID list doesn't contain an empty SSID (but should)";
return false;
}
return true;
}
// Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
// contains no SSIDs.
MATCHER_P(HasNoHiddenSSID, nl80211_message_type, "") {
if (!arg) {
LOG(INFO) << "Null message";
return false;
}
if (arg->message_type() != nl80211_message_type) {
LOG(INFO) << "Not an nl80211 message";
return false;
}
const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
return false;
}
AttributeListConstRefPtr ssids;
if (!msg->const_attributes()->ConstGetNestedAttributeList(
NL80211_ATTR_SCAN_SSIDS, &ssids)) {
return true;
}
AttributeIdIterator ssid_iter(*ssids);
if (ssid_iter.AtEnd()) {
return true;
}
LOG(INFO) << "SSID list contains at least one (hidden) SSID";
return false;
}
} // namespace shill
#endif // SHILL_NETLINK_MESSAGE_MATCHERS_H_