blob: d6faf00658767fe3838a140012e2d65d5e1f31d3 [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
Christopher Wiley393b93f2012-11-08 17:30:58 -0800346uint32 MockNl80211Socket::Send(KernelBoundNlMessage *message) {
347 // Don't need a real family id; this is never sent.
348 const uint32 family_id = 0;
349 uint32 sequence_number = ++sequence_number_;
350 if (genlmsg_put(message->message(), NL_AUTO_PID, sequence_number, family_id,
351 0, 0, message->command(), 0) == NULL) {
352 LOG(ERROR) << "genlmsg_put returned a NULL pointer.";
353 return 0;
354 }
355 return sequence_number;
356}
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700357
Wade Guthrie0d438532012-05-18 14:18:50 -0700358class Config80211Test : public Test {
359 public:
360 Config80211Test() : config80211_(Config80211::GetInstance()) {}
361 void SetupConfig80211Object() {
362 EXPECT_NE(config80211_, reinterpret_cast<Config80211 *>(NULL));
363 config80211_->sock_ = &socket_;
364 EXPECT_TRUE(config80211_->Init(reinterpret_cast<EventDispatcher *>(NULL)));
Wade Guthried6153612012-08-23 11:36:14 -0700365 config80211_->Reset();
Wade Guthrie0d438532012-05-18 14:18:50 -0700366 }
367
368 Config80211 *config80211_;
369 MockNl80211Socket socket_;
370};
371
372class TestCallbackObject {
373 public:
374 TestCallbackObject() : callback_(Bind(&TestCallbackObject::MessageHandler,
375 Unretained(this))) { }
376 void MessageHandler(const UserBoundNlMessage &msg) {
377 }
378 const Config80211::Callback &GetCallback() const { return callback_; }
379
380 private:
381 Config80211::Callback callback_;
382};
383
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700384// Checks a config80211 parameter to make sure it contains |callback_arg|
385// in its list of broadcast callbacks.
386MATCHER_P(ContainsCallback, callback_arg, "") {
387 if (arg == reinterpret_cast<void *>(NULL)) {
388 LOG(WARNING) << "NULL parameter";
Wade Guthrie0d438532012-05-18 14:18:50 -0700389 return false;
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700390 }
391 const Config80211 *config80211 = static_cast<Config80211 *>(arg);
392 const Config80211::Callback callback =
393 static_cast<const Config80211::Callback>(callback_arg);
394
395 return config80211->FindBroadcastCallback(callback);
Wade Guthrie0d438532012-05-18 14:18:50 -0700396}
397
398TEST_F(Config80211Test, AddLinkTest) {
399 SetupConfig80211Object();
400
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700401 // Create a broadcast callback.
Wade Guthrie0d438532012-05-18 14:18:50 -0700402 TestCallbackObject callback_object;
403
Wade Guthried6153612012-08-23 11:36:14 -0700404 // Install the callback and subscribe to events using it, wifi down
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700405 // (shouldn't actually send the subscription request until wifi comes up).
Wade Guthried6153612012-08-23 11:36:14 -0700406 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700407 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700408
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700409 EXPECT_TRUE(config80211_->AddBroadcastCallback(
410 callback_object.GetCallback()));
Wade Guthried6153612012-08-23 11:36:14 -0700411 Config80211::EventType scan_event = Config80211::kEventTypeScan;
412 string scan_event_string;
413 EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string));
414 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
415
416 // Wifi up, should subscribe to events.
417 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700418 .WillOnce(Return(true));
Wade Guthrie0d438532012-05-18 14:18:50 -0700419 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700420 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie0d438532012-05-18 14:18:50 -0700421 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700422 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700423
Wade Guthried6153612012-08-23 11:36:14 -0700424 // Second subscribe, same event (should do nothing).
425 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700426 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700427 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
Wade Guthrie0d438532012-05-18 14:18:50 -0700428
Wade Guthried6153612012-08-23 11:36:14 -0700429 // Bring the wifi back down.
430 config80211_->SetWifiState(Config80211::kWifiDown);
431
432 // Subscribe to a new event with the wifi down (should still do nothing).
433 Config80211::EventType mlme_event = Config80211::kEventTypeMlme;
434 string mlme_event_string;
435 EXPECT_TRUE(Config80211::GetEventTypeString(mlme_event, &mlme_event_string));
436 EXPECT_TRUE(config80211_->SubscribeToEvents(mlme_event));
437
438 // Wifi up (again), should subscribe to the original scan event and the new
439 // mlme event.
440 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700441 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700442 EXPECT_CALL(socket_, AddGroupMembership(mlme_event_string))
443 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700444 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700445 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie5d53d492012-11-07 09:53:31 -0800446 .Times(1)
Wade Guthried6153612012-08-23 11:36:14 -0700447 .WillRepeatedly(Return(true));
448 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700449}
450
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700451TEST_F(Config80211Test, BroadcastCallbackTest) {
452 SetupConfig80211Object();
453
454 nlmsghdr *message = const_cast<nlmsghdr *>(
455 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT));
456
Christopher Wileyfe34be02012-11-12 16:02:46 -0800457 MockCallback80211 callback1;
458 MockCallback80211 callback2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700459
460 // Simple, 1 callback, case.
461 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
Christopher Wileyfe34be02012-11-12 16:02:46 -0800462 callback1.InstallAsBroadcastCallback();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700463 config80211_->OnNlMessageReceived(message);
464
465 // Add a second callback.
466 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
467 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
468 EXPECT_TRUE(callback2.InstallAsBroadcastCallback());
469 config80211_->OnNlMessageReceived(message);
470
471 // Verify that a callback can't be added twice.
472 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
473 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
474 EXPECT_FALSE(callback1.InstallAsBroadcastCallback());
475 config80211_->OnNlMessageReceived(message);
476
477 // Check that we can remove a callback.
478 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
479 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
480 EXPECT_TRUE(callback1.DeinstallAsCallback());
481 config80211_->OnNlMessageReceived(message);
482
483 // Check that re-adding the callback goes smoothly.
484 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
485 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
486 EXPECT_TRUE(callback1.InstallAsBroadcastCallback());
487 config80211_->OnNlMessageReceived(message);
488
489 // Check that ClearBroadcastCallbacks works.
490 config80211_->ClearBroadcastCallbacks();
491 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
492 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(0);
493 config80211_->OnNlMessageReceived(message);
494}
495
496TEST_F(Config80211Test, MessageCallbackTest) {
497 // Setup.
498 SetupConfig80211Object();
499
Christopher Wileyfe34be02012-11-12 16:02:46 -0800500 MockCallback80211 callback_broadcast;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700501 EXPECT_TRUE(callback_broadcast.InstallAsBroadcastCallback());
502
Christopher Wiley393b93f2012-11-08 17:30:58 -0800503 KernelBoundNlMessage sent_message_1(CTRL_CMD_GETFAMILY);
Christopher Wileyfe34be02012-11-12 16:02:46 -0800504 MockCallback80211 callback_sent_1;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700505 EXPECT_TRUE(sent_message_1.Init());
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700506
Christopher Wiley393b93f2012-11-08 17:30:58 -0800507 KernelBoundNlMessage sent_message_2(CTRL_CMD_GETFAMILY);
Christopher Wileyfe34be02012-11-12 16:02:46 -0800508 MockCallback80211 callback_sent_2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700509 EXPECT_TRUE(sent_message_2.Init());
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700510
511 // Set up the received message as a response to sent_message_1.
512 scoped_array<unsigned char> message_memory(
513 new unsigned char[sizeof(kNL80211_CMD_DISCONNECT)]);
514 memcpy(message_memory.get(), kNL80211_CMD_DISCONNECT,
515 sizeof(kNL80211_CMD_DISCONNECT));
516 nlmsghdr *received_message =
517 reinterpret_cast<nlmsghdr *>(message_memory.get());
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700518
519 // Now, we can start the actual test...
520
521 // Verify that generic callback gets called for a message when no
522 // message-specific callback has been installed.
523 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
524 config80211_->OnNlMessageReceived(received_message);
525
Christopher Wiley393b93f2012-11-08 17:30:58 -0800526 // Send the message and give our callback. Verify that we get called back.
527 EXPECT_TRUE(config80211_->SendMessage(&sent_message_1,
Christopher Wileyfe34be02012-11-12 16:02:46 -0800528 callback_sent_1.callback()));
Christopher Wiley393b93f2012-11-08 17:30:58 -0800529 // Make it appear that this message is in response to our sent message.
530 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700531 EXPECT_CALL(callback_sent_1, Config80211MessageCallback(_)).Times(1);
532 config80211_->OnNlMessageReceived(received_message);
533
534 // Verify that broadcast callback is called for the message after the
535 // message-specific callback is called once.
536 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
537 config80211_->OnNlMessageReceived(received_message);
538
539 // Install and then uninstall message-specific callback; verify broadcast
540 // callback is called on message receipt.
Christopher Wiley393b93f2012-11-08 17:30:58 -0800541 EXPECT_TRUE(config80211_->SendMessage(&sent_message_1,
Christopher Wileyfe34be02012-11-12 16:02:46 -0800542 callback_sent_1.callback()));
Christopher Wiley393b93f2012-11-08 17:30:58 -0800543 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
544 EXPECT_TRUE(config80211_->RemoveMessageCallback(sent_message_1));
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700545 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
546 config80211_->OnNlMessageReceived(received_message);
547
548 // Install callback for different message; verify that broadcast callback is
549 // called for _this_ message.
Christopher Wiley393b93f2012-11-08 17:30:58 -0800550 EXPECT_TRUE(config80211_->SendMessage(&sent_message_2,
Christopher Wileyfe34be02012-11-12 16:02:46 -0800551 callback_sent_2.callback()));
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700552 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
553 config80211_->OnNlMessageReceived(received_message);
554
555 // Change the ID for the message to that of the second callback; verify that
556 // the appropriate callback is called for _that_ message.
Christopher Wiley393b93f2012-11-08 17:30:58 -0800557 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700558 EXPECT_CALL(callback_sent_2, Config80211MessageCallback(_)).Times(1);
559 config80211_->OnNlMessageReceived(received_message);
560}
561
Wade Guthrie0d438532012-05-18 14:18:50 -0700562TEST_F(Config80211Test, NL80211_CMD_TRIGGER_SCAN) {
563 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
564 const_cast<nlmsghdr *>(
565 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_TRIGGER_SCAN)));
566
567 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800568 EXPECT_EQ(message->message_type(), NL80211_CMD_TRIGGER_SCAN);
Wade Guthrie0d438532012-05-18 14:18:50 -0700569
570 {
571 uint8_t value;
572 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
573 EXPECT_EQ(value, kExpectedWifi);
574 }
575
576 {
577 uint32_t value;
578 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
579 EXPECT_EQ(value, kExpectedIfIndex);
580 }
581
582 // Make sure the scan frequencies in the attribute are the ones we expect.
583 {
584 vector<uint32_t>list;
585 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
586 NL80211_ATTR_SCAN_FREQUENCIES, &list));
587 EXPECT_EQ(arraysize(kScanFrequencyTrigger), list.size());
588 int i = 0;
589 vector<uint32_t>::const_iterator j = list.begin();
590 while (j != list.end()) {
591 EXPECT_EQ(kScanFrequencyTrigger[i], *j);
592 ++i;
593 ++j;
594 }
595 }
596
597 {
598 vector<string> ssids;
599 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
600 &ssids));
601 EXPECT_EQ(ssids.size(), 1);
602 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
603 }
604
605 // Significant only in its existence.
606 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
607}
608
609TEST_F(Config80211Test, NL80211_CMD_NEW_SCAN_RESULTS) {
610 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
611 const_cast<nlmsghdr *>(
612 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_SCAN_RESULTS)));
613
614 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800615 EXPECT_EQ(message->message_type(), NL80211_CMD_NEW_SCAN_RESULTS);
Wade Guthrie0d438532012-05-18 14:18:50 -0700616
617 {
618 uint8_t value;
619 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
620 EXPECT_EQ(value, kExpectedWifi);
621 }
622
623 {
624 uint32_t value;
625 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
626 EXPECT_EQ(value, kExpectedIfIndex);
627 }
628
629 // Make sure the scan frequencies in the attribute are the ones we expect.
630 {
631 vector<uint32_t>list;
632 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
633 NL80211_ATTR_SCAN_FREQUENCIES, &list));
634 EXPECT_EQ(arraysize(kScanFrequencyResults), list.size());
635 int i = 0;
636 vector<uint32_t>::const_iterator j = list.begin();
637 while (j != list.end()) {
638 EXPECT_EQ(kScanFrequencyResults[i], *j);
639 ++i;
640 ++j;
641 }
642 }
643
644 {
645 vector<string> ssids;
646 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
647 &ssids));
648 EXPECT_EQ(ssids.size(), 1);
649 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
650 }
651
652 // Significant only in its existence.
653 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
654}
655
656TEST_F(Config80211Test, NL80211_CMD_NEW_STATION) {
657 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
658 const_cast<nlmsghdr *>(
659 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_STATION)));
660
661 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800662 EXPECT_EQ(message->message_type(), NL80211_CMD_NEW_STATION);
Wade Guthrie0d438532012-05-18 14:18:50 -0700663
664 {
665 uint32_t value;
666 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
667 EXPECT_EQ(value, kExpectedIfIndex);
668 }
669
670 {
671 string value;
672 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
673 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
674 }
675
676 // TODO(wdg): Make config80211 handle nested attributes so it can deal
677 // with things like NL80211_ATTR_STA_INFO (without just calling
678 // nla_parse_nested).
679 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_STA_INFO));
680
681 {
682 uint32_t value;
683 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_GENERATION, &value));
684 EXPECT_EQ(value, kNewStationExpectedGeneration);
685 }
686}
687
688TEST_F(Config80211Test, NL80211_CMD_AUTHENTICATE) {
689 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
690 const_cast<nlmsghdr *>(
691 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_AUTHENTICATE)));
692
693 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800694 EXPECT_EQ(message->message_type(), NL80211_CMD_AUTHENTICATE);
Wade Guthrie0d438532012-05-18 14:18:50 -0700695
696 {
697 uint8_t value;
698 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
699 EXPECT_EQ(value, kExpectedWifi);
700 }
701
702 {
703 uint32_t value;
704 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
705 EXPECT_EQ(value, kExpectedIfIndex);
706 }
707
708 {
709 void *rawdata = NULL;
710 int frame_byte_count = 0;
711 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
712 &frame_byte_count));
713 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
714 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
715
716 Nl80211Frame frame(frame_data, frame_byte_count);
717 Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame));
718
719 EXPECT_TRUE(frame.IsEqual(expected_frame));
720 }
721}
722
723TEST_F(Config80211Test, NL80211_CMD_ASSOCIATE) {
724 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
725 const_cast<nlmsghdr *>(
726 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_ASSOCIATE)));
727
728 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800729 EXPECT_EQ(message->message_type(), NL80211_CMD_ASSOCIATE);
Wade Guthrie0d438532012-05-18 14:18:50 -0700730
731 {
732 uint8_t value;
733 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
734 EXPECT_EQ(value, kExpectedWifi);
735 }
736
737 {
738 uint32_t value;
739 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
740 EXPECT_EQ(value, kExpectedIfIndex);
741 }
742
743 {
744 void *rawdata = NULL;
745 int frame_byte_count = 0;
746 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
747 &frame_byte_count));
748 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
749 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
750
751 Nl80211Frame frame(frame_data, frame_byte_count);
752 Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame));
753
754 EXPECT_TRUE(frame.IsEqual(expected_frame));
755 }
756}
757
758TEST_F(Config80211Test, NL80211_CMD_CONNECT) {
759 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
760 const_cast<nlmsghdr *>(
761 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_CONNECT)));
762
763 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800764 EXPECT_EQ(message->message_type(), NL80211_CMD_CONNECT);
Wade Guthrie0d438532012-05-18 14:18:50 -0700765
766 {
767 uint8_t value;
768 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
769 EXPECT_EQ(value, kExpectedWifi);
770 }
771
772 {
773 uint32_t value;
774 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
775 EXPECT_EQ(value, kExpectedIfIndex);
776 }
777
778 {
779 string value;
780 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
781 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
782 }
783
784 {
785 uint16_t value;
786 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_STATUS_CODE, &value));
787 EXPECT_EQ(value, kExpectedConnectStatus);
788 }
789
790 // TODO(wdg): Need to check the value of this attribute.
791 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_RESP_IE));
792}
793
794TEST_F(Config80211Test, NL80211_CMD_DEAUTHENTICATE) {
795 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
796 const_cast<nlmsghdr *>(
797 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DEAUTHENTICATE)));
798
799 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800800 EXPECT_EQ(message->message_type(), NL80211_CMD_DEAUTHENTICATE);
Wade Guthrie0d438532012-05-18 14:18:50 -0700801
802 {
803 uint8_t value;
804 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
805 EXPECT_EQ(value, kExpectedWifi);
806 }
807
808 {
809 uint32_t value;
810 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
811 EXPECT_EQ(value, kExpectedIfIndex);
812 }
813
814 {
815 void *rawdata = NULL;
816 int frame_byte_count = 0;
817 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
818 &frame_byte_count));
819 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
820 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
821
822 Nl80211Frame frame(frame_data, frame_byte_count);
823 Nl80211Frame expected_frame(kDeauthenticateFrame,
824 sizeof(kDeauthenticateFrame));
825
826 EXPECT_TRUE(frame.IsEqual(expected_frame));
827 }
828}
829
830TEST_F(Config80211Test, NL80211_CMD_DISCONNECT) {
831 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
832 const_cast<nlmsghdr *>(
833 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT)));
834
835 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800836 EXPECT_EQ(message->message_type(), NL80211_CMD_DISCONNECT);
Wade Guthrie0d438532012-05-18 14:18:50 -0700837
838 {
839 uint8_t value;
840 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
841 EXPECT_EQ(value, kExpectedWifi);
842 }
843
844 {
845 uint32_t value;
846 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
847 EXPECT_EQ(value, kExpectedIfIndex);
848 }
849
850 {
851 uint16_t value;
852 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_REASON_CODE, &value));
853 EXPECT_EQ(value, kExpectedDisconnectReason);
854 }
855
856 // Significant only in its existence.
857 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_DISCONNECTED_BY_AP));
858}
859
860TEST_F(Config80211Test, NL80211_CMD_NOTIFY_CQM) {
861 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
862 const_cast<nlmsghdr *>(
863 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NOTIFY_CQM)));
864
865 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800866 EXPECT_EQ(message->message_type(), NL80211_CMD_NOTIFY_CQM);
Wade Guthrie0d438532012-05-18 14:18:50 -0700867
868
869 {
870 uint8_t value;
871 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
872 EXPECT_EQ(value, kExpectedWifi);
873 }
874
875 {
876 uint32_t value;
877 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
878 EXPECT_EQ(value, kExpectedIfIndex);
879 }
880
881 {
882 string value;
883 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
884 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
885 }
886
887 // TODO(wdg): Make config80211 handle nested attributes so it can deal
888 // with things like NL80211_ATTR_CQM (without just calling nla_parse_nested).
889 {
890 static const nla_policy kCqmPolicy[NL80211_ATTR_CQM_MAX + 1] = {
891 { NLA_U32, 0, 0 }, // Who Knows?
892 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THOLD]
893 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_HYST]
894 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]
895 };
896
897 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_CQM));
898 const nlattr *const_data = message->GetAttribute(NL80211_ATTR_CQM);
899 nlattr *cqm_attr = const_cast<nlattr *>(const_data);
900 EXPECT_NE(cqm_attr, reinterpret_cast<nlattr *>(NULL));
901
902 nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
903 EXPECT_EQ(nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr,
904 const_cast<nla_policy *>(kCqmPolicy)), 0);
905
906 EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
907 EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
908 EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
909 kExpectedCqmNotAcked);
910 }
911}
912
913TEST_F(Config80211Test, NL80211_CMD_DISASSOCIATE) {
914 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
915 const_cast<nlmsghdr *>(
916 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISASSOCIATE)));
917
918 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
Christopher Wiley764538d2012-11-09 10:58:23 -0800919 EXPECT_EQ(message->message_type(), NL80211_CMD_DISASSOCIATE);
Wade Guthrie0d438532012-05-18 14:18:50 -0700920
921
922 {
923 uint8_t value;
924 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
925 EXPECT_EQ(value, kExpectedWifi);
926 }
927
928 {
929 uint32_t value;
930 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
931 EXPECT_EQ(value, kExpectedIfIndex);
932 }
933
934 {
935 void *rawdata = NULL;
936 int frame_byte_count = 0;
937 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
938 &frame_byte_count));
939 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
940 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
941
942 Nl80211Frame frame(frame_data, frame_byte_count);
943 Nl80211Frame expected_frame(kDisassociateFrame, sizeof(kDisassociateFrame));
944
945 EXPECT_TRUE(frame.IsEqual(expected_frame));
946 }
947}
948
949} // namespace shill