blob: 9bae3030c86afd002b2fdee0bae2100339420094 [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);
398 EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700399 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700400 EXPECT_CALL(socket_, GetSequenceNumber())
401 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
Wade Guthried6153612012-08-23 11:36:14 -0700402
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700403 EXPECT_TRUE(config80211_->AddBroadcastCallback(
404 callback_object.GetCallback()));
Wade Guthried6153612012-08-23 11:36:14 -0700405 Config80211::EventType scan_event = Config80211::kEventTypeScan;
406 string scan_event_string;
407 EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string));
408 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
409
410 // Wifi up, should subscribe to events.
411 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700412 .WillOnce(Return(true));
413 EXPECT_CALL(socket_, DisableSequenceChecking())
414 .WillOnce(Return(true));
415 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700416 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie0d438532012-05-18 14:18:50 -0700417 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700418 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700419
Wade Guthried6153612012-08-23 11:36:14 -0700420 // Second subscribe, same event (should do nothing).
421 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
422 EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700423 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700424 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
Wade Guthrie0d438532012-05-18 14:18:50 -0700425
Wade Guthried6153612012-08-23 11:36:14 -0700426 // Bring the wifi back down.
427 config80211_->SetWifiState(Config80211::kWifiDown);
428
429 // Subscribe to a new event with the wifi down (should still do nothing).
430 Config80211::EventType mlme_event = Config80211::kEventTypeMlme;
431 string mlme_event_string;
432 EXPECT_TRUE(Config80211::GetEventTypeString(mlme_event, &mlme_event_string));
433 EXPECT_TRUE(config80211_->SubscribeToEvents(mlme_event));
434
435 // Wifi up (again), should subscribe to the original scan event and the new
436 // mlme event.
437 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700438 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700439 EXPECT_CALL(socket_, AddGroupMembership(mlme_event_string))
440 .WillOnce(Return(true));
441 EXPECT_CALL(socket_, DisableSequenceChecking())
442 .Times(2)
443 .WillRepeatedly(Return(true));
444 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700445 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthried6153612012-08-23 11:36:14 -0700446 .Times(2)
447 .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
457 MockCallback80211 callback1(config80211_);
458 MockCallback80211 callback2(config80211_);
459 EXPECT_CALL(socket_, GetSequenceNumber())
460 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
461
462 // Simple, 1 callback, case.
463 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
464 EXPECT_TRUE(callback1.InstallAsBroadcastCallback());
465 config80211_->OnNlMessageReceived(message);
466
467 // Add a second callback.
468 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
469 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
470 EXPECT_TRUE(callback2.InstallAsBroadcastCallback());
471 config80211_->OnNlMessageReceived(message);
472
473 // Verify that a callback can't be added twice.
474 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
475 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
476 EXPECT_FALSE(callback1.InstallAsBroadcastCallback());
477 config80211_->OnNlMessageReceived(message);
478
479 // Check that we can remove a callback.
480 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
481 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
482 EXPECT_TRUE(callback1.DeinstallAsCallback());
483 config80211_->OnNlMessageReceived(message);
484
485 // Check that re-adding the callback goes smoothly.
486 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(1);
487 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(1);
488 EXPECT_TRUE(callback1.InstallAsBroadcastCallback());
489 config80211_->OnNlMessageReceived(message);
490
491 // Check that ClearBroadcastCallbacks works.
492 config80211_->ClearBroadcastCallbacks();
493 EXPECT_CALL(callback1, Config80211MessageCallback(_)).Times(0);
494 EXPECT_CALL(callback2, Config80211MessageCallback(_)).Times(0);
495 config80211_->OnNlMessageReceived(message);
496}
497
498TEST_F(Config80211Test, MessageCallbackTest) {
499 // Setup.
500 SetupConfig80211Object();
501
502 EXPECT_CALL(socket_, GetSequenceNumber())
503 .WillRepeatedly(Invoke(&MockNl80211Socket::GetNextNumber));
504
505 MockCallback80211 callback_broadcast(config80211_);
506 EXPECT_TRUE(callback_broadcast.InstallAsBroadcastCallback());
507
508 KernelBoundNlMessage sent_message_1;
509 MockCallback80211 callback_sent_1(config80211_);
510 EXPECT_TRUE(sent_message_1.Init());
511 EXPECT_TRUE(sent_message_1.AddNetlinkHeader(&socket_, 0, NL_AUTO_SEQ, 0, 0, 0,
512 CTRL_CMD_GETFAMILY, 0));
513 LOG(INFO) << "Message 1 id:" << sent_message_1.GetId();
514
515 KernelBoundNlMessage sent_message_2;
516 MockCallback80211 callback_sent_2(config80211_);
517 EXPECT_TRUE(sent_message_2.Init());
518 EXPECT_TRUE(sent_message_2.AddNetlinkHeader(&socket_, 0, NL_AUTO_SEQ, 0, 0, 0,
519 CTRL_CMD_GETFAMILY, 0));
520 LOG(INFO) << "Message 2 id:" << sent_message_2.GetId();
521
522 // This is more testing the test code than the code, itself.
523 EXPECT_NE(sent_message_1.GetId(), sent_message_2.GetId());
524
525 // Set up the received message as a response to sent_message_1.
526 scoped_array<unsigned char> message_memory(
527 new unsigned char[sizeof(kNL80211_CMD_DISCONNECT)]);
528 memcpy(message_memory.get(), kNL80211_CMD_DISCONNECT,
529 sizeof(kNL80211_CMD_DISCONNECT));
530 nlmsghdr *received_message =
531 reinterpret_cast<nlmsghdr *>(message_memory.get());
532 received_message->nlmsg_seq = sent_message_1.GetId();
533
534 // Now, we can start the actual test...
535
536 // Verify that generic callback gets called for a message when no
537 // message-specific callback has been installed.
538 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
539 config80211_->OnNlMessageReceived(received_message);
540
541 // Install message-based callback; verify that message callback gets called.
542 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_1,
543 callback_sent_1.GetCallback()));
544 EXPECT_CALL(callback_sent_1, Config80211MessageCallback(_)).Times(1);
545 config80211_->OnNlMessageReceived(received_message);
546
547 // Verify that broadcast callback is called for the message after the
548 // message-specific callback is called once.
549 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
550 config80211_->OnNlMessageReceived(received_message);
551
552 // Install and then uninstall message-specific callback; verify broadcast
553 // callback is called on message receipt.
554 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_1,
555 callback_sent_1.GetCallback()));
556 EXPECT_TRUE(config80211_->UnsetMessageCallbackById(sent_message_1.GetId()));
557 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
558 config80211_->OnNlMessageReceived(received_message);
559
560 // Install callback for different message; verify that broadcast callback is
561 // called for _this_ message.
562 EXPECT_TRUE(config80211_->SetMessageCallback(sent_message_2,
563 callback_sent_2.GetCallback()));
564 EXPECT_CALL(callback_broadcast, Config80211MessageCallback(_)).Times(1);
565 config80211_->OnNlMessageReceived(received_message);
566
567 // Change the ID for the message to that of the second callback; verify that
568 // the appropriate callback is called for _that_ message.
569 received_message->nlmsg_seq = sent_message_2.GetId();
570 EXPECT_CALL(callback_sent_2, Config80211MessageCallback(_)).Times(1);
571 config80211_->OnNlMessageReceived(received_message);
572}
573
Wade Guthrie0d438532012-05-18 14:18:50 -0700574TEST_F(Config80211Test, NL80211_CMD_TRIGGER_SCAN) {
575 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
576 const_cast<nlmsghdr *>(
577 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_TRIGGER_SCAN)));
578
579 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
580 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_TRIGGER_SCAN);
581
582 {
583 uint8_t value;
584 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
585 EXPECT_EQ(value, kExpectedWifi);
586 }
587
588 {
589 uint32_t value;
590 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
591 EXPECT_EQ(value, kExpectedIfIndex);
592 }
593
594 // Make sure the scan frequencies in the attribute are the ones we expect.
595 {
596 vector<uint32_t>list;
597 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
598 NL80211_ATTR_SCAN_FREQUENCIES, &list));
599 EXPECT_EQ(arraysize(kScanFrequencyTrigger), list.size());
600 int i = 0;
601 vector<uint32_t>::const_iterator j = list.begin();
602 while (j != list.end()) {
603 EXPECT_EQ(kScanFrequencyTrigger[i], *j);
604 ++i;
605 ++j;
606 }
607 }
608
609 {
610 vector<string> ssids;
611 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
612 &ssids));
613 EXPECT_EQ(ssids.size(), 1);
614 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
615 }
616
617 // Significant only in its existence.
618 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
619}
620
621TEST_F(Config80211Test, NL80211_CMD_NEW_SCAN_RESULTS) {
622 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
623 const_cast<nlmsghdr *>(
624 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_SCAN_RESULTS)));
625
626 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
627 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_SCAN_RESULTS);
628
629 {
630 uint8_t value;
631 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
632 EXPECT_EQ(value, kExpectedWifi);
633 }
634
635 {
636 uint32_t value;
637 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
638 EXPECT_EQ(value, kExpectedIfIndex);
639 }
640
641 // Make sure the scan frequencies in the attribute are the ones we expect.
642 {
643 vector<uint32_t>list;
644 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
645 NL80211_ATTR_SCAN_FREQUENCIES, &list));
646 EXPECT_EQ(arraysize(kScanFrequencyResults), list.size());
647 int i = 0;
648 vector<uint32_t>::const_iterator j = list.begin();
649 while (j != list.end()) {
650 EXPECT_EQ(kScanFrequencyResults[i], *j);
651 ++i;
652 ++j;
653 }
654 }
655
656 {
657 vector<string> ssids;
658 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
659 &ssids));
660 EXPECT_EQ(ssids.size(), 1);
661 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
662 }
663
664 // Significant only in its existence.
665 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
666}
667
668TEST_F(Config80211Test, NL80211_CMD_NEW_STATION) {
669 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
670 const_cast<nlmsghdr *>(
671 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_STATION)));
672
673 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
674 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_STATION);
675
676 {
677 uint32_t value;
678 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
679 EXPECT_EQ(value, kExpectedIfIndex);
680 }
681
682 {
683 string value;
684 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
685 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
686 }
687
688 // TODO(wdg): Make config80211 handle nested attributes so it can deal
689 // with things like NL80211_ATTR_STA_INFO (without just calling
690 // nla_parse_nested).
691 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_STA_INFO));
692
693 {
694 uint32_t value;
695 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_GENERATION, &value));
696 EXPECT_EQ(value, kNewStationExpectedGeneration);
697 }
698}
699
700TEST_F(Config80211Test, NL80211_CMD_AUTHENTICATE) {
701 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
702 const_cast<nlmsghdr *>(
703 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_AUTHENTICATE)));
704
705 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
706 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_AUTHENTICATE);
707
708 {
709 uint8_t value;
710 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
711 EXPECT_EQ(value, kExpectedWifi);
712 }
713
714 {
715 uint32_t value;
716 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
717 EXPECT_EQ(value, kExpectedIfIndex);
718 }
719
720 {
721 void *rawdata = NULL;
722 int frame_byte_count = 0;
723 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
724 &frame_byte_count));
725 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
726 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
727
728 Nl80211Frame frame(frame_data, frame_byte_count);
729 Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame));
730
731 EXPECT_TRUE(frame.IsEqual(expected_frame));
732 }
733}
734
735TEST_F(Config80211Test, NL80211_CMD_ASSOCIATE) {
736 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
737 const_cast<nlmsghdr *>(
738 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_ASSOCIATE)));
739
740 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
741 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_ASSOCIATE);
742
743 {
744 uint8_t value;
745 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
746 EXPECT_EQ(value, kExpectedWifi);
747 }
748
749 {
750 uint32_t value;
751 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
752 EXPECT_EQ(value, kExpectedIfIndex);
753 }
754
755 {
756 void *rawdata = NULL;
757 int frame_byte_count = 0;
758 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
759 &frame_byte_count));
760 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
761 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
762
763 Nl80211Frame frame(frame_data, frame_byte_count);
764 Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame));
765
766 EXPECT_TRUE(frame.IsEqual(expected_frame));
767 }
768}
769
770TEST_F(Config80211Test, NL80211_CMD_CONNECT) {
771 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
772 const_cast<nlmsghdr *>(
773 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_CONNECT)));
774
775 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
776 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_CONNECT);
777
778 {
779 uint8_t value;
780 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
781 EXPECT_EQ(value, kExpectedWifi);
782 }
783
784 {
785 uint32_t value;
786 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
787 EXPECT_EQ(value, kExpectedIfIndex);
788 }
789
790 {
791 string value;
792 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
793 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
794 }
795
796 {
797 uint16_t value;
798 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_STATUS_CODE, &value));
799 EXPECT_EQ(value, kExpectedConnectStatus);
800 }
801
802 // TODO(wdg): Need to check the value of this attribute.
803 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_RESP_IE));
804}
805
806TEST_F(Config80211Test, NL80211_CMD_DEAUTHENTICATE) {
807 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
808 const_cast<nlmsghdr *>(
809 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DEAUTHENTICATE)));
810
811 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
812 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DEAUTHENTICATE);
813
814 {
815 uint8_t value;
816 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
817 EXPECT_EQ(value, kExpectedWifi);
818 }
819
820 {
821 uint32_t value;
822 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
823 EXPECT_EQ(value, kExpectedIfIndex);
824 }
825
826 {
827 void *rawdata = NULL;
828 int frame_byte_count = 0;
829 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
830 &frame_byte_count));
831 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
832 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
833
834 Nl80211Frame frame(frame_data, frame_byte_count);
835 Nl80211Frame expected_frame(kDeauthenticateFrame,
836 sizeof(kDeauthenticateFrame));
837
838 EXPECT_TRUE(frame.IsEqual(expected_frame));
839 }
840}
841
842TEST_F(Config80211Test, NL80211_CMD_DISCONNECT) {
843 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
844 const_cast<nlmsghdr *>(
845 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT)));
846
847 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
848 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISCONNECT);
849
850 {
851 uint8_t value;
852 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
853 EXPECT_EQ(value, kExpectedWifi);
854 }
855
856 {
857 uint32_t value;
858 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
859 EXPECT_EQ(value, kExpectedIfIndex);
860 }
861
862 {
863 uint16_t value;
864 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_REASON_CODE, &value));
865 EXPECT_EQ(value, kExpectedDisconnectReason);
866 }
867
868 // Significant only in its existence.
869 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_DISCONNECTED_BY_AP));
870}
871
872TEST_F(Config80211Test, NL80211_CMD_NOTIFY_CQM) {
873 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
874 const_cast<nlmsghdr *>(
875 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NOTIFY_CQM)));
876
877 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
878 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NOTIFY_CQM);
879
880
881 {
882 uint8_t value;
883 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
884 EXPECT_EQ(value, kExpectedWifi);
885 }
886
887 {
888 uint32_t value;
889 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
890 EXPECT_EQ(value, kExpectedIfIndex);
891 }
892
893 {
894 string value;
895 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
896 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
897 }
898
899 // TODO(wdg): Make config80211 handle nested attributes so it can deal
900 // with things like NL80211_ATTR_CQM (without just calling nla_parse_nested).
901 {
902 static const nla_policy kCqmPolicy[NL80211_ATTR_CQM_MAX + 1] = {
903 { NLA_U32, 0, 0 }, // Who Knows?
904 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THOLD]
905 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_HYST]
906 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]
907 };
908
909 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_CQM));
910 const nlattr *const_data = message->GetAttribute(NL80211_ATTR_CQM);
911 nlattr *cqm_attr = const_cast<nlattr *>(const_data);
912 EXPECT_NE(cqm_attr, reinterpret_cast<nlattr *>(NULL));
913
914 nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
915 EXPECT_EQ(nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr,
916 const_cast<nla_policy *>(kCqmPolicy)), 0);
917
918 EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
919 EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
920 EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
921 kExpectedCqmNotAcked);
922 }
923}
924
925TEST_F(Config80211Test, NL80211_CMD_DISASSOCIATE) {
926 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
927 const_cast<nlmsghdr *>(
928 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISASSOCIATE)));
929
930 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
931 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISASSOCIATE);
932
933
934 {
935 uint8_t value;
936 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
937 EXPECT_EQ(value, kExpectedWifi);
938 }
939
940 {
941 uint32_t value;
942 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
943 EXPECT_EQ(value, kExpectedIfIndex);
944 }
945
946 {
947 void *rawdata = NULL;
948 int frame_byte_count = 0;
949 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
950 &frame_byte_count));
951 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
952 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
953
954 Nl80211Frame frame(frame_data, frame_byte_count);
955 Nl80211Frame expected_frame(kDisassociateFrame, sizeof(kDisassociateFrame));
956
957 EXPECT_TRUE(frame.IsEqual(expected_frame));
958 }
959}
960
961} // namespace shill