blob: 50d403dac5554fbd7eedf18d0bfe226976e37901 [file] [log] [blame]
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -07001// Copyright (c) 2013 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#ifndef SHILL_NETLINK_MESSAGE_MATCHERS_H_
6#define SHILL_NETLINK_MESSAGE_MATCHERS_H_
7
8#include <gmock/gmock.h>
9
10#include "shill/logging.h"
11#include "shill/netlink_message.h"
12#include "shill/nl80211_message.h"
13
14namespace shill {
15
16// Given a netlink message, verifies that it is an Nl80211Message and verifies,
17// further that it is the specified command.
18MATCHER_P2(IsNl80211Command, nl80211_message_type, command, "") {
19 if (!arg) {
20 LOG(INFO) << "Null message";
21 return false;
22 }
23 if (arg->message_type() != nl80211_message_type) {
24 LOG(INFO) << "Not an nl80211 message";
25 return false;
26 }
27 const Nl80211Message *msg = dynamic_cast<const Nl80211Message *>(arg);
28 if (msg->command() != command) {
29 LOG(INFO) << "Not a message of type " << command
30 << " (it's a " << +msg->command() << ")";
31 return false;
32 }
33 return true;
34}
35
36// Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
37// contains exactly one SSID along with the requisite empty one.
38MATCHER_P(HasHiddenSSID, nl80211_message_type, "") {
39 if (!arg) {
40 LOG(INFO) << "Null message";
41 return false;
42 }
43 if (arg->message_type() != nl80211_message_type) {
44 LOG(INFO) << "Not an nl80211 message";
45 return false;
46 }
47 const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
48 if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
49 LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
50 return false;
51 }
52 AttributeListConstRefPtr ssids;
53 if (!msg->const_attributes()->ConstGetNestedAttributeList(
54 NL80211_ATTR_SCAN_SSIDS, &ssids)) {
55 LOG(INFO) << "No SSID list in message";
56 return false;
57 }
58 ByteString ssid;
59 AttributeIdIterator ssid_iter(*ssids);
60 if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &ssid)) {
61 LOG(INFO) << "SSID list contains no (hidden) SSIDs";
62 return false;
63 }
64
65 // A valid Scan containing a single hidden SSID should contain
66 // two SSID entries: one containing the SSID we are looking for,
67 // and an empty entry, signifying that we also want to do a
68 // broadcast probe request for all non-hidden APs as well.
69 ByteString empty_ssid;
70 if (ssid_iter.AtEnd()) {
71 LOG(INFO) << "SSID list doesn't contain an empty SSIDs (but should)";
72 return false;
73 }
74 ssid_iter.Advance();
75 if (!ssids->GetRawAttributeValue(ssid_iter.GetId(), &empty_ssid) ||
76 !empty_ssid.IsEmpty()) {
77 LOG(INFO) << "SSID list doesn't contain an empty SSID (but should)";
78 return false;
79 }
80
81 return true;
82}
83
84// Verifies that a NetlinkMessage is an NL80211_CMD_TRIGGER_SCAN message that
85// contains no SSIDs.
86MATCHER_P(HasNoHiddenSSID, nl80211_message_type, "") {
87 if (!arg) {
88 LOG(INFO) << "Null message";
89 return false;
90 }
91 if (arg->message_type() != nl80211_message_type) {
92 LOG(INFO) << "Not an nl80211 message";
93 return false;
94 }
95 const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
96 if (msg->command() != NL80211_CMD_TRIGGER_SCAN) {
97 LOG(INFO) << "Not a NL80211_CMD_TRIGGER_SCAN message";
98 return false;
99 }
100 AttributeListConstRefPtr ssids;
101 if (!msg->const_attributes()->ConstGetNestedAttributeList(
102 NL80211_ATTR_SCAN_SSIDS, &ssids)) {
103 return true;
104 }
105 AttributeIdIterator ssid_iter(*ssids);
106 if (ssid_iter.AtEnd()) {
107 return true;
108 }
109
110 LOG(INFO) << "SSID list contains at least one (hidden) SSID";
111 return false;
112}
113
114} // namespace shill
115
116#endif // SHILL_NETLINK_MESSAGE_MATCHERS_H_