blob: c1287934e8a0d30e591c49867637642a462d2acd [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 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// This file provides tests for individual messages. It tests
6// UserBoundNlMessageFactory's ability to create specific message types and it
7// tests the various UserBoundNlMessage types' ability to parse those
8// messages.
9
10// This file tests the public interface to Config80211.
11
12#include "shill/config80211.h"
13
Wade Guthrieb1ec8602012-10-18 17:26:14 -070014#include <list>
15#include <string>
16#include <vector>
17
18#include <base/bind.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070019#include <gmock/gmock.h>
20#include <gtest/gtest.h>
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070021#include <net/if.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070022#include <netlink/attr.h>
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070023#include <netlink/genl/genl.h>
24#include <netlink/msg.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070025#include <netlink/netlink.h>
26
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070027#include "shill/kernel_bound_nlmessage.h"
Wade Guthrieb1ec8602012-10-18 17:26:14 -070028#include "shill/mock_callback80211_object.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070029#include "shill/mock_nl80211_socket.h"
30#include "shill/nl80211_socket.h"
31#include "shill/user_bound_nlmessage.h"
32
33using base::Bind;
34using base::Unretained;
Wade Guthrieb1ec8602012-10-18 17:26:14 -070035using std::list;
Wade Guthrie0d438532012-05-18 14:18:50 -070036using std::string;
37using std::vector;
38using testing::_;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070039using testing::Invoke;
Wade Guthrie0d438532012-05-18 14:18:50 -070040using testing::Return;
41using testing::Test;
42
43namespace shill {
44
45namespace {
46
47// These data blocks have been collected by shill using Config80211 while,
48// simultaneously (and manually) comparing shill output with that of the 'iw'
49// code from which it was derived. The test strings represent the raw packet
50// data coming from the kernel. The comments above each of these strings is
51// the markup that "iw" outputs for ech of these packets.
52
53// These constants are consistent throughout the packets, below.
54
55const uint32_t kExpectedIfIndex = 4;
56const uint8_t kExpectedWifi = 0;
57const char kExpectedMacAddress[] = "c0:3f:0e:77:e8:7f";
58
59
60// wlan0 (phy #0): scan started
61
62const uint32_t kScanFrequencyTrigger[] = {
63 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
64 2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
65 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
66 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
67 5700, 5745, 5765, 5785, 5805, 5825
68};
69
70const unsigned char kNL80211_CMD_TRIGGER_SCAN[] = {
71 0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
75 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
76 0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
77 0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
78 0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
79 0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
80 0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
81 0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
82 0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
83 0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
84 0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
85 0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
86 0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
87 0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
88 0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
89 0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
90 0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
91 0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
92 0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
93 0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
94 0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
95 0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
96 0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
97 0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
98 0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
99 0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
100 0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
101 0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
102 0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
103 0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
104 0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
105 0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
106 0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
107 0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
108 0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
109 0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
110 0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
111 0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
112 0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
113 0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
114 0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
115 0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
116};
117
118
119// wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452
120// 2457 2462 2467 2472 2484 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520
121// 5540 5560 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825, ""
122
123const uint32_t kScanFrequencyResults[] = {
124 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
125 2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
126 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
127 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
128 5700, 5745, 5765, 5785, 5805, 5825
129};
130
131const unsigned char kNL80211_CMD_NEW_SCAN_RESULTS[] = {
132 0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x22, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
136 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
137 0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
138 0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
139 0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
140 0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
141 0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
142 0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
143 0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
144 0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
145 0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
146 0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
147 0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
148 0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
149 0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
150 0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
151 0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
152 0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
153 0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
154 0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
155 0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
156 0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
157 0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
158 0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
159 0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
160 0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
161 0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
162 0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
163 0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
164 0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
165 0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
166 0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
167 0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
168 0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
169 0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
170 0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
171 0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
172 0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
173 0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
174 0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
175 0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
176 0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
177};
178
179
180// wlan0: new station c0:3f:0e:77:e8:7f
181
182const uint32_t kNewStationExpectedGeneration = 275;
183
184const unsigned char kNL80211_CMD_NEW_STATION[] = {
185 0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x13, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
188 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
189 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
190 0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00,
191 0x04, 0x00, 0x15, 0x00,
192};
193
194
195// wlan0 (phy #0): auth c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
196// Successful [frame: b0 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0
197// 3f 0e 77 e8 7f 30 07 00 00 02 00 00 00]
198
199const unsigned char kAuthenticateFrame[] = {
200 0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
201 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
202 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
203 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
204};
205
206const unsigned char kNL80211_CMD_AUTHENTICATE[] = {
207 0x48, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x25, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
211 0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x33, 0x00,
212 0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
213 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
214 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
215 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
216};
217
218
219// wlan0 (phy #0): assoc c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
220// Successful [frame: 10 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0 3f 0e
221// 77 e8 7f 40 07 01 04 00 00 01 c0 01 08 82 84 8b 96 0c 12 18 24 32 04 30 48
222// 60 6c]
223
224const unsigned char kAssociateFrame[] = {
225 0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
226 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
227 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
228 0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
229 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
230 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c
231};
232
233const unsigned char kNL80211_CMD_ASSOCIATE[] = {
234 0x58, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x26, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
238 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x33, 0x00,
239 0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
240 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
241 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
242 0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
243 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
244 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00,
245};
246
247
248// wlan0 (phy #0): connected to c0:3f:0e:77:e8:7f
249
250const uint16_t kExpectedConnectStatus = 0;
251
252const unsigned char kNL80211_CMD_CONNECT[] = {
253 0x4c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x2e, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
257 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
258 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
259 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x14, 0x00, 0x4e, 0x00, 0x01, 0x08, 0x82, 0x84,
261 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x32, 0x04,
262 0x30, 0x48, 0x60, 0x6c,
263};
264
265
266// wlan0 (phy #0): deauth c0:3f:0e:77:e8:7f -> ff:ff:ff:ff:ff:ff reason 2:
267// Previous authentication no longer valid [frame: c0 00 00 00 ff ff ff ff
268// ff ff c0 3f 0e 77 e8 7f c0 3f 0e 77 e8 7f c0 0e 02 00]
269
270const unsigned char kDeauthenticateFrame[] = {
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700271 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
272 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
273 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
274 0x02, 0x00
Wade Guthrie0d438532012-05-18 14:18:50 -0700275};
276
277const unsigned char kNL80211_CMD_DEAUTHENTICATE[] = {
278 0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x27, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
282 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
283 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
284 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
285 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
286 0x02, 0x00, 0x00, 0x00,
287};
288
289
290// wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
291// longer valid
292
293const uint16_t kExpectedDisconnectReason = 2;
294
295const unsigned char kNL80211_CMD_DISCONNECT[] = {
296 0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
300 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00,
301 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00,
302};
303
304
305// wlan0 (phy #0): connection quality monitor event: peer c0:3f:0e:77:e8:7f
306// didn't ACK 50 packets
307
308const uint32_t kExpectedCqmNotAcked = 50;
309
310const unsigned char kNL80211_CMD_NOTIFY_CQM[] = {
311 0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
315 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
316 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
317 0x0c, 0x00, 0x5e, 0x00, 0x08, 0x00, 0x04, 0x00,
318 0x32, 0x00, 0x00, 0x00,
319};
320
321
322// wlan0 (phy #0): disassoc 48:5d:60:77:2d:cf -> c0:3f:0e:77:e8:7f reason 3:
323// Deauthenticated because sending station is [frame: a0 00 00 00 c0 3f 0e
324// 77 e8 7f 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f 00 00 03 00]
325
326const unsigned char kDisassociateFrame[] = {
327 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
328 0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
329 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
330 0x03, 0x00
331};
332
333const unsigned char kNL80211_CMD_DISASSOCIATE[] = {
334 0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
338 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
339 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
340 0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
341 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
342 0x03, 0x00, 0x00, 0x00,
343};
344
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700345} // namespace
Wade Guthrie0d438532012-05-18 14:18:50 -0700346
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700347unsigned int MockNl80211Socket::number_ = 0;
348
Wade Guthrie0d438532012-05-18 14:18:50 -0700349class Config80211Test : public Test {
350 public:
351 Config80211Test() : config80211_(Config80211::GetInstance()) {}
352 void SetupConfig80211Object() {
353 EXPECT_NE(config80211_, reinterpret_cast<Config80211 *>(NULL));
354 config80211_->sock_ = &socket_;
355 EXPECT_TRUE(config80211_->Init(reinterpret_cast<EventDispatcher *>(NULL)));
Wade Guthried6153612012-08-23 11:36:14 -0700356 config80211_->Reset();
Wade Guthrie0d438532012-05-18 14:18:50 -0700357 }
358
359 Config80211 *config80211_;
360 MockNl80211Socket socket_;
361};
362
363class TestCallbackObject {
364 public:
365 TestCallbackObject() : callback_(Bind(&TestCallbackObject::MessageHandler,
366 Unretained(this))) { }
367 void MessageHandler(const UserBoundNlMessage &msg) {
368 }
369 const Config80211::Callback &GetCallback() const { return callback_; }
370
371 private:
372 Config80211::Callback callback_;
373};
374
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700375// Checks a config80211 parameter to make sure it contains |callback_arg|
376// in its list of broadcast callbacks.
377MATCHER_P(ContainsCallback, callback_arg, "") {
378 if (arg == reinterpret_cast<void *>(NULL)) {
379 LOG(WARNING) << "NULL parameter";
Wade Guthrie0d438532012-05-18 14:18:50 -0700380 return false;
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700381 }
382 const Config80211 *config80211 = static_cast<Config80211 *>(arg);
383 const Config80211::Callback callback =
384 static_cast<const Config80211::Callback>(callback_arg);
385
386 return config80211->FindBroadcastCallback(callback);
Wade Guthrie0d438532012-05-18 14:18:50 -0700387}
388
389TEST_F(Config80211Test, AddLinkTest) {
390 SetupConfig80211Object();
391
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700392 // Create a broadcast callback.
Wade Guthrie0d438532012-05-18 14:18:50 -0700393 TestCallbackObject callback_object;
394
Wade Guthried6153612012-08-23 11:36:14 -0700395 // Install the callback and subscribe to events using it, wifi down
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700396 // (shouldn't actually send the subscription request until wifi comes up).
Wade Guthried6153612012-08-23 11:36:14 -0700397 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700398 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700399 EXPECT_CALL(socket_, GetSequenceNumber())
400 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
Wade Guthried6153612012-08-23 11:36:14 -0700401
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700402 EXPECT_TRUE(config80211_->AddBroadcastCallback(
403 callback_object.GetCallback()));
Wade Guthried6153612012-08-23 11:36:14 -0700404 Config80211::EventType scan_event = Config80211::kEventTypeScan;
405 string scan_event_string;
406 EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string));
407 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
408
409 // Wifi up, should subscribe to events.
410 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700411 .WillOnce(Return(true));
Wade Guthrie0d438532012-05-18 14:18:50 -0700412 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700413 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie0d438532012-05-18 14:18:50 -0700414 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700415 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700416
Wade Guthried6153612012-08-23 11:36:14 -0700417 // Second subscribe, same event (should do nothing).
418 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700419 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700420 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
Wade Guthrie0d438532012-05-18 14:18:50 -0700421
Wade Guthried6153612012-08-23 11:36:14 -0700422 // Bring the wifi back down.
423 config80211_->SetWifiState(Config80211::kWifiDown);
424
425 // Subscribe to a new event with the wifi down (should still do nothing).
426 Config80211::EventType mlme_event = Config80211::kEventTypeMlme;
427 string mlme_event_string;
428 EXPECT_TRUE(Config80211::GetEventTypeString(mlme_event, &mlme_event_string));
429 EXPECT_TRUE(config80211_->SubscribeToEvents(mlme_event));
430
431 // Wifi up (again), should subscribe to the original scan event and the new
432 // mlme event.
433 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700434 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700435 EXPECT_CALL(socket_, AddGroupMembership(mlme_event_string))
436 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700437 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700438 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie5d53d492012-11-07 09:53:31 -0800439 .Times(1)
Wade Guthried6153612012-08-23 11:36:14 -0700440 .WillRepeatedly(Return(true));
441 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700442}
443
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700444TEST_F(Config80211Test, BroadcastCallbackTest) {
445 SetupConfig80211Object();
446
447 nlmsghdr *message = const_cast<nlmsghdr *>(
448 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT));
449
450 MockCallback80211 callback1(config80211_);
451 MockCallback80211 callback2(config80211_);
452 EXPECT_CALL(socket_, GetSequenceNumber())
453 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
454
455 // Simple, 1 callback, case.
456 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
457 EXPECT_TRUE(callback1.InstallAsBroadcastCallback());
458 config80211_->OnNlMessageReceived(message);
459
460 // Add a second callback.
461 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
462 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
463 EXPECT_TRUE(callback2.InstallAsBroadcastCallback());
464 config80211_->OnNlMessageReceived(message);
465
466 // Verify that a callback can't be added twice.
467 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
468 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
469 EXPECT_FALSE(callback1.InstallAsBroadcastCallback());
470 config80211_->OnNlMessageReceived(message);
471
472 // Check that we can remove a callback.
473 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
474 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
475 EXPECT_TRUE(callback1.DeinstallAsCallback());
476 config80211_->OnNlMessageReceived(message);
477
478 // Check that re-adding the callback goes smoothly.
479 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
480 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
481 EXPECT_TRUE(callback1.InstallAsBroadcastCallback());
482 config80211_->OnNlMessageReceived(message);
483
484 // Check that ClearBroadcastCallbacks works.
485 config80211_->ClearBroadcastCallbacks();
486 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
487 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(0);
488 config80211_->OnNlMessageReceived(message);
489}
490
491TEST_F(Config80211Test, MessageCallbackTest) {
492 // Setup.
493 SetupConfig80211Object();
494
495 EXPECT_CALL(socket_, GetSequenceNumber())
496 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
497
498 MockCallback80211 callback_broadcast(config80211_);
499 EXPECT_TRUE(callback_broadcast.InstallAsBroadcastCallback());
500
501 KernelBoundNlMessage sent_message_1;
502 MockCallback80211 callback_sent_1(config80211_);
503 EXPECT_TRUE(sent_message_1.Init());
504 EXPECT_TRUE(sent_message_1.AddNetlinkHeader(&socket_, 0, NL_AUTO_SEQ, 0, 0, 0,
505 CTRL_CMD_GETFAMILY, 0));
506 LOG(INFO) << "Message 1 id:" << sent_message_1.GetId();
507
508 KernelBoundNlMessage sent_message_2;
509 MockCallback80211 callback_sent_2(config80211_);
510 EXPECT_TRUE(sent_message_2.Init());
511 EXPECT_TRUE(sent_message_2.AddNetlinkHeader(&socket_, 0, NL_AUTO_SEQ, 0, 0, 0,
512 CTRL_CMD_GETFAMILY, 0));
513 LOG(INFO) << "Message 2 id:" << sent_message_2.GetId();
514
515 // This is more testing the test code than the code, itself.
516 EXPECT_NE(sent_message_1.GetId(), sent_message_2.GetId());
517
518 // Set up the received message as a response to sent_message_1.
519 scoped_array<unsigned char> message_memory(
520 new unsigned char[sizeof(kNL80211_CMD_DISCONNECT)]);
521 memcpy(message_memory.get(), kNL80211_CMD_DISCONNECT,
522 sizeof(kNL80211_CMD_DISCONNECT));
523 nlmsghdr *received_message =
524 reinterpret_cast<nlmsghdr *>(message_memory.get());
525 received_message->nlmsg_seq = sent_message_1.GetId();
526
527 // Now, we can start the actual test...
528
529 // Verify that generic callback gets called for a message when no
530 // message-specific callback has been installed.
531 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
532 config80211_->OnNlMessageReceived(received_message);
533
534 // Install message-based callback; verify that message callback gets called.
535 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_1,
536 callback_sent_1.GetCallback()));
537 EXPECT_CALL(callback_sent_1, Config80211MessageCallback(_)).Times(1);
538 config80211_->OnNlMessageReceived(received_message);
539
540 // Verify that broadcast callback is called for the message after the
541 // message-specific callback is called once.
542 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
543 config80211_->OnNlMessageReceived(received_message);
544
545 // Install and then uninstall message-specific callback; verify broadcast
546 // callback is called on message receipt.
547 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_1,
548 callback_sent_1.GetCallback()));
549 EXPECT_TRUE(config80211_->UnsetMessageCallbackById(sent_message_1.GetId()));
550 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
551 config80211_->OnNlMessageReceived(received_message);
552
553 // Install callback for different message; verify that broadcast callback is
554 // called for _this_ message.
555 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_2,
556 callback_sent_2.GetCallback()));
557 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
558 config80211_->OnNlMessageReceived(received_message);
559
560 // Change the ID for the message to that of the second callback; verify that
561 // the appropriate callback is called for _that_ message.
562 received_message->nlmsg_seq = sent_message_2.GetId();
563 EXPECT_CALL(callback_sent_2, Config80211MessageCallback(_)).Times(1);
564 config80211_->OnNlMessageReceived(received_message);
565}
566
Wade Guthrie0d438532012-05-18 14:18:50 -0700567TEST_F(Config80211Test, NL80211_CMD_TRIGGER_SCAN) {
568 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
569 const_cast<nlmsghdr *>(
570 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_TRIGGER_SCAN)));
571
572 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
573 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_TRIGGER_SCAN);
574
575 {
576 uint8_t value;
577 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
578 EXPECT_EQ(value, kExpectedWifi);
579 }
580
581 {
582 uint32_t value;
583 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
584 EXPECT_EQ(value, kExpectedIfIndex);
585 }
586
587 // Make sure the scan frequencies in the attribute are the ones we expect.
588 {
589 vector<uint32_t>list;
590 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
591 NL80211_ATTR_SCAN_FREQUENCIES, &list));
592 EXPECT_EQ(arraysize(kScanFrequencyTrigger), list.size());
593 int i = 0;
594 vector<uint32_t>::const_iterator j = list.begin();
595 while (j != list.end()) {
596 EXPECT_EQ(kScanFrequencyTrigger[i], *j);
597 ++i;
598 ++j;
599 }
600 }
601
602 {
603 vector<string> ssids;
604 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
605 &ssids));
606 EXPECT_EQ(ssids.size(), 1);
607 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
608 }
609
610 // Significant only in its existence.
611 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
612}
613
614TEST_F(Config80211Test, NL80211_CMD_NEW_SCAN_RESULTS) {
615 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
616 const_cast<nlmsghdr *>(
617 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_SCAN_RESULTS)));
618
619 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
620 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_SCAN_RESULTS);
621
622 {
623 uint8_t value;
624 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
625 EXPECT_EQ(value, kExpectedWifi);
626 }
627
628 {
629 uint32_t value;
630 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
631 EXPECT_EQ(value, kExpectedIfIndex);
632 }
633
634 // Make sure the scan frequencies in the attribute are the ones we expect.
635 {
636 vector<uint32_t>list;
637 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
638 NL80211_ATTR_SCAN_FREQUENCIES, &list));
639 EXPECT_EQ(arraysize(kScanFrequencyResults), list.size());
640 int i = 0;
641 vector<uint32_t>::const_iterator j = list.begin();
642 while (j != list.end()) {
643 EXPECT_EQ(kScanFrequencyResults[i], *j);
644 ++i;
645 ++j;
646 }
647 }
648
649 {
650 vector<string> ssids;
651 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
652 &ssids));
653 EXPECT_EQ(ssids.size(), 1);
654 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
655 }
656
657 // Significant only in its existence.
658 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
659}
660
661TEST_F(Config80211Test, NL80211_CMD_NEW_STATION) {
662 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
663 const_cast<nlmsghdr *>(
664 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_STATION)));
665
666 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
667 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_STATION);
668
669 {
670 uint32_t value;
671 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
672 EXPECT_EQ(value, kExpectedIfIndex);
673 }
674
675 {
676 string value;
677 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
678 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
679 }
680
681 // TODO(wdg): Make config80211 handle nested attributes so it can deal
682 // with things like NL80211_ATTR_STA_INFO (without just calling
683 // nla_parse_nested).
684 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_STA_INFO));
685
686 {
687 uint32_t value;
688 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_GENERATION, &value));
689 EXPECT_EQ(value, kNewStationExpectedGeneration);
690 }
691}
692
693TEST_F(Config80211Test, NL80211_CMD_AUTHENTICATE) {
694 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
695 const_cast<nlmsghdr *>(
696 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_AUTHENTICATE)));
697
698 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
699 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_AUTHENTICATE);
700
701 {
702 uint8_t value;
703 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
704 EXPECT_EQ(value, kExpectedWifi);
705 }
706
707 {
708 uint32_t value;
709 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
710 EXPECT_EQ(value, kExpectedIfIndex);
711 }
712
713 {
714 void *rawdata = NULL;
715 int frame_byte_count = 0;
716 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
717 &frame_byte_count));
718 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
719 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
720
721 Nl80211Frame frame(frame_data, frame_byte_count);
722 Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame));
723
724 EXPECT_TRUE(frame.IsEqual(expected_frame));
725 }
726}
727
728TEST_F(Config80211Test, NL80211_CMD_ASSOCIATE) {
729 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
730 const_cast<nlmsghdr *>(
731 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_ASSOCIATE)));
732
733 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
734 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_ASSOCIATE);
735
736 {
737 uint8_t value;
738 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
739 EXPECT_EQ(value, kExpectedWifi);
740 }
741
742 {
743 uint32_t value;
744 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
745 EXPECT_EQ(value, kExpectedIfIndex);
746 }
747
748 {
749 void *rawdata = NULL;
750 int frame_byte_count = 0;
751 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
752 &frame_byte_count));
753 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
754 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
755
756 Nl80211Frame frame(frame_data, frame_byte_count);
757 Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame));
758
759 EXPECT_TRUE(frame.IsEqual(expected_frame));
760 }
761}
762
763TEST_F(Config80211Test, NL80211_CMD_CONNECT) {
764 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
765 const_cast<nlmsghdr *>(
766 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_CONNECT)));
767
768 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
769 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_CONNECT);
770
771 {
772 uint8_t value;
773 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
774 EXPECT_EQ(value, kExpectedWifi);
775 }
776
777 {
778 uint32_t value;
779 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
780 EXPECT_EQ(value, kExpectedIfIndex);
781 }
782
783 {
784 string value;
785 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
786 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
787 }
788
789 {
790 uint16_t value;
791 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_STATUS_CODE, &value));
792 EXPECT_EQ(value, kExpectedConnectStatus);
793 }
794
795 // TODO(wdg): Need to check the value of this attribute.
796 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_RESP_IE));
797}
798
799TEST_F(Config80211Test, NL80211_CMD_DEAUTHENTICATE) {
800 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
801 const_cast<nlmsghdr *>(
802 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DEAUTHENTICATE)));
803
804 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
805 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DEAUTHENTICATE);
806
807 {
808 uint8_t value;
809 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
810 EXPECT_EQ(value, kExpectedWifi);
811 }
812
813 {
814 uint32_t value;
815 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
816 EXPECT_EQ(value, kExpectedIfIndex);
817 }
818
819 {
820 void *rawdata = NULL;
821 int frame_byte_count = 0;
822 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
823 &frame_byte_count));
824 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
825 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
826
827 Nl80211Frame frame(frame_data, frame_byte_count);
828 Nl80211Frame expected_frame(kDeauthenticateFrame,
829 sizeof(kDeauthenticateFrame));
830
831 EXPECT_TRUE(frame.IsEqual(expected_frame));
832 }
833}
834
835TEST_F(Config80211Test, NL80211_CMD_DISCONNECT) {
836 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
837 const_cast<nlmsghdr *>(
838 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT)));
839
840 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
841 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISCONNECT);
842
843 {
844 uint8_t value;
845 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
846 EXPECT_EQ(value, kExpectedWifi);
847 }
848
849 {
850 uint32_t value;
851 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
852 EXPECT_EQ(value, kExpectedIfIndex);
853 }
854
855 {
856 uint16_t value;
857 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_REASON_CODE, &value));
858 EXPECT_EQ(value, kExpectedDisconnectReason);
859 }
860
861 // Significant only in its existence.
862 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_DISCONNECTED_BY_AP));
863}
864
865TEST_F(Config80211Test, NL80211_CMD_NOTIFY_CQM) {
866 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
867 const_cast<nlmsghdr *>(
868 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NOTIFY_CQM)));
869
870 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
871 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NOTIFY_CQM);
872
873
874 {
875 uint8_t value;
876 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
877 EXPECT_EQ(value, kExpectedWifi);
878 }
879
880 {
881 uint32_t value;
882 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
883 EXPECT_EQ(value, kExpectedIfIndex);
884 }
885
886 {
887 string value;
888 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
889 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
890 }
891
892 // TODO(wdg): Make config80211 handle nested attributes so it can deal
893 // with things like NL80211_ATTR_CQM (without just calling nla_parse_nested).
894 {
895 static const nla_policy kCqmPolicy[NL80211_ATTR_CQM_MAX + 1] = {
896 { NLA_U32, 0, 0 }, // Who Knows?
897 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THOLD]
898 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_HYST]
899 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]
900 };
901
902 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_CQM));
903 const nlattr *const_data = message->GetAttribute(NL80211_ATTR_CQM);
904 nlattr *cqm_attr = const_cast<nlattr *>(const_data);
905 EXPECT_NE(cqm_attr, reinterpret_cast<nlattr *>(NULL));
906
907 nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
908 EXPECT_EQ(nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr,
909 const_cast<nla_policy *>(kCqmPolicy)), 0);
910
911 EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
912 EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
913 EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
914 kExpectedCqmNotAcked);
915 }
916}
917
918TEST_F(Config80211Test, NL80211_CMD_DISASSOCIATE) {
919 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
920 const_cast<nlmsghdr *>(
921 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISASSOCIATE)));
922
923 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
924 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISASSOCIATE);
925
926
927 {
928 uint8_t value;
929 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
930 EXPECT_EQ(value, kExpectedWifi);
931 }
932
933 {
934 uint32_t value;
935 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
936 EXPECT_EQ(value, kExpectedIfIndex);
937 }
938
939 {
940 void *rawdata = NULL;
941 int frame_byte_count = 0;
942 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
943 &frame_byte_count));
944 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
945 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
946
947 Nl80211Frame frame(frame_data, frame_byte_count);
948 Nl80211Frame expected_frame(kDisassociateFrame, sizeof(kDisassociateFrame));
949
950 EXPECT_TRUE(frame.IsEqual(expected_frame));
951 }
952}
953
954} // namespace shill