| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 1 | // 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 Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 14 | #include <list> | 
 | 15 | #include <string> | 
 | 16 | #include <vector> | 
 | 17 |  | 
 | 18 | #include <base/bind.h> | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 19 | #include <gmock/gmock.h> | 
 | 20 | #include <gtest/gtest.h> | 
 | 21 | #include <netlink/attr.h> | 
 | 22 | #include <netlink/netlink.h> | 
 | 23 |  | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 24 | #include "shill/mock_callback80211_object.h" | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 25 | #include "shill/mock_nl80211_socket.h" | 
 | 26 | #include "shill/nl80211_socket.h" | 
 | 27 | #include "shill/user_bound_nlmessage.h" | 
 | 28 |  | 
 | 29 | using base::Bind; | 
 | 30 | using base::Unretained; | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 31 | using std::list; | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 32 | using std::string; | 
 | 33 | using std::vector; | 
 | 34 | using testing::_; | 
 | 35 | using testing::Return; | 
 | 36 | using testing::Test; | 
 | 37 |  | 
 | 38 | namespace shill { | 
 | 39 |  | 
 | 40 | namespace { | 
 | 41 |  | 
 | 42 | // These data blocks have been collected by shill using Config80211 while, | 
 | 43 | // simultaneously (and manually) comparing shill output with that of the 'iw' | 
 | 44 | // code from which it was derived.  The test strings represent the raw packet | 
 | 45 | // data coming from the kernel.  The comments above each of these strings is | 
 | 46 | // the markup that "iw" outputs for ech of these packets. | 
 | 47 |  | 
 | 48 | // These constants are consistent throughout the packets, below. | 
 | 49 |  | 
 | 50 | const uint32_t kExpectedIfIndex = 4; | 
 | 51 | const uint8_t kExpectedWifi = 0; | 
 | 52 | const char kExpectedMacAddress[] = "c0:3f:0e:77:e8:7f"; | 
 | 53 |  | 
 | 54 |  | 
 | 55 | // wlan0 (phy #0): scan started | 
 | 56 |  | 
 | 57 | const uint32_t kScanFrequencyTrigger[] = { | 
 | 58 |   2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, | 
 | 59 |   2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200, | 
 | 60 |   5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, | 
 | 61 |   5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, | 
 | 62 |   5700, 5745, 5765, 5785, 5805, 5825 | 
 | 63 | }; | 
 | 64 |  | 
 | 65 | const unsigned char kNL80211_CMD_TRIGGER_SCAN[] = { | 
 | 66 |   0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 67 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 68 |   0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 69 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 70 |   0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00, | 
 | 71 |   0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00, | 
 | 72 |   0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00, | 
 | 73 |   0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00, | 
 | 74 |   0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00, | 
 | 75 |   0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00, | 
 | 76 |   0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, | 
 | 77 |   0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00, | 
 | 78 |   0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00, | 
 | 79 |   0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00, | 
 | 80 |   0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00, | 
 | 81 |   0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00, | 
 | 82 |   0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00, | 
 | 83 |   0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00, | 
 | 84 |   0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00, | 
 | 85 |   0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00, | 
 | 86 |   0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00, | 
 | 87 |   0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00, | 
 | 88 |   0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00, | 
 | 89 |   0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00, | 
 | 90 |   0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00, | 
 | 91 |   0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00, | 
 | 92 |   0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00, | 
 | 93 |   0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00, | 
 | 94 |   0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00, | 
 | 95 |   0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00, | 
 | 96 |   0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00, | 
 | 97 |   0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00, | 
 | 98 |   0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00, | 
 | 99 |   0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00, | 
 | 100 |   0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00, | 
 | 101 |   0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00, | 
 | 102 |   0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00, | 
 | 103 |   0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00, | 
 | 104 |   0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00, | 
 | 105 |   0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00, | 
 | 106 |   0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00, | 
 | 107 |   0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00, | 
 | 108 |   0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00, | 
 | 109 |   0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00, | 
 | 110 |   0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 111 | }; | 
 | 112 |  | 
 | 113 |  | 
 | 114 | // wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452 | 
 | 115 | // 2457 2462 2467 2472 2484 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 | 
 | 116 | // 5540 5560 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825, "" | 
 | 117 |  | 
 | 118 | const uint32_t kScanFrequencyResults[] = { | 
 | 119 |   2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, | 
 | 120 |   2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200, | 
 | 121 |   5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, | 
 | 122 |   5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, | 
 | 123 |   5700, 5745, 5765, 5785, 5805, 5825 | 
 | 124 | }; | 
 | 125 |  | 
 | 126 | const unsigned char kNL80211_CMD_NEW_SCAN_RESULTS[] = { | 
 | 127 |   0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 128 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 129 |   0x22, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 130 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 131 |   0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00, | 
 | 132 |   0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00, | 
 | 133 |   0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00, | 
 | 134 |   0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00, | 
 | 135 |   0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00, | 
 | 136 |   0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00, | 
 | 137 |   0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, | 
 | 138 |   0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00, | 
 | 139 |   0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00, | 
 | 140 |   0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00, | 
 | 141 |   0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00, | 
 | 142 |   0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00, | 
 | 143 |   0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00, | 
 | 144 |   0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00, | 
 | 145 |   0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00, | 
 | 146 |   0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00, | 
 | 147 |   0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00, | 
 | 148 |   0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00, | 
 | 149 |   0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00, | 
 | 150 |   0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00, | 
 | 151 |   0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00, | 
 | 152 |   0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00, | 
 | 153 |   0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00, | 
 | 154 |   0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00, | 
 | 155 |   0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00, | 
 | 156 |   0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00, | 
 | 157 |   0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00, | 
 | 158 |   0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00, | 
 | 159 |   0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00, | 
 | 160 |   0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00, | 
 | 161 |   0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00, | 
 | 162 |   0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00, | 
 | 163 |   0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00, | 
 | 164 |   0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00, | 
 | 165 |   0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00, | 
 | 166 |   0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00, | 
 | 167 |   0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00, | 
 | 168 |   0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00, | 
 | 169 |   0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00, | 
 | 170 |   0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00, | 
 | 171 |   0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 172 | }; | 
 | 173 |  | 
 | 174 |  | 
 | 175 | // wlan0: new station c0:3f:0e:77:e8:7f | 
 | 176 |  | 
 | 177 | const uint32_t kNewStationExpectedGeneration = 275; | 
 | 178 |  | 
 | 179 | const unsigned char kNL80211_CMD_NEW_STATION[] = { | 
 | 180 |   0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 181 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 182 |   0x13, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 183 |   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00, | 
 | 184 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00, | 
 | 185 |   0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00, | 
 | 186 |   0x04, 0x00, 0x15, 0x00, | 
 | 187 | }; | 
 | 188 |  | 
 | 189 |  | 
 | 190 | // wlan0 (phy #0): auth c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0: | 
 | 191 | // Successful [frame: b0 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0 | 
 | 192 | // 3f 0e 77 e8 7f 30 07 00 00 02 00 00 00] | 
 | 193 |  | 
 | 194 | const unsigned char kAuthenticateFrame[] = { | 
 | 195 |   0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77, | 
 | 196 |   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 197 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07, | 
 | 198 |   0x00, 0x00, 0x02, 0x00, 0x00, 0x00 | 
 | 199 | }; | 
 | 200 |  | 
 | 201 | const unsigned char kNL80211_CMD_AUTHENTICATE[] = { | 
 | 202 |   0x48, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 203 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 204 |   0x25, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 205 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 206 |   0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x33, 0x00, | 
 | 207 |   0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77, | 
 | 208 |   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 209 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07, | 
 | 210 |   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 211 | }; | 
 | 212 |  | 
 | 213 |  | 
 | 214 | // wlan0 (phy #0): assoc c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0: | 
 | 215 | // Successful [frame: 10 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0 3f 0e | 
 | 216 | // 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 | 
 | 217 | // 60 6c] | 
 | 218 |  | 
 | 219 | const unsigned char kAssociateFrame[] = { | 
 | 220 |   0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77, | 
 | 221 |   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 222 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07, | 
 | 223 |   0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08, | 
 | 224 |   0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, | 
 | 225 |   0x32, 0x04, 0x30, 0x48, 0x60, 0x6c | 
 | 226 | }; | 
 | 227 |  | 
 | 228 | const unsigned char kNL80211_CMD_ASSOCIATE[] = { | 
 | 229 |   0x58, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 230 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 231 |   0x26, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 232 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 233 |   0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x33, 0x00, | 
 | 234 |   0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77, | 
 | 235 |   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 236 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07, | 
 | 237 |   0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08, | 
 | 238 |   0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, | 
 | 239 |   0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00, | 
 | 240 | }; | 
 | 241 |  | 
 | 242 |  | 
 | 243 | // wlan0 (phy #0): connected to c0:3f:0e:77:e8:7f | 
 | 244 |  | 
 | 245 | const uint16_t kExpectedConnectStatus = 0; | 
 | 246 |  | 
 | 247 | const unsigned char kNL80211_CMD_CONNECT[] = { | 
 | 248 |   0x4c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 249 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 250 |   0x2e, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 251 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 252 |   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00, | 
 | 253 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00, | 
 | 254 |   0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 255 |   0x14, 0x00, 0x4e, 0x00, 0x01, 0x08, 0x82, 0x84, | 
 | 256 |   0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x32, 0x04, | 
 | 257 |   0x30, 0x48, 0x60, 0x6c, | 
 | 258 | }; | 
 | 259 |  | 
 | 260 |  | 
 | 261 | // wlan0 (phy #0): deauth c0:3f:0e:77:e8:7f -> ff:ff:ff:ff:ff:ff reason 2: | 
 | 262 | // Previous authentication no longer valid [frame: c0 00 00 00 ff ff ff ff | 
 | 263 | // ff ff c0 3f 0e 77 e8 7f c0 3f 0e 77 e8 7f c0 0e 02 00] | 
 | 264 |  | 
 | 265 | const unsigned char kDeauthenticateFrame[] = { | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 266 |   0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | 
 | 267 |   0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 268 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e, | 
 | 269 |   0x02, 0x00 | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 270 | }; | 
 | 271 |  | 
 | 272 | const unsigned char kNL80211_CMD_DEAUTHENTICATE[] = { | 
 | 273 |   0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 274 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 275 |   0x27, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 276 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 277 |   0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00, | 
 | 278 |   0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | 
 | 279 |   0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, | 
 | 280 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e, | 
 | 281 |   0x02, 0x00, 0x00, 0x00, | 
 | 282 | }; | 
 | 283 |  | 
 | 284 |  | 
 | 285 | // wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no | 
 | 286 | // longer valid | 
 | 287 |  | 
 | 288 | const uint16_t kExpectedDisconnectReason = 2; | 
 | 289 |  | 
 | 290 | const unsigned char kNL80211_CMD_DISCONNECT[] = { | 
 | 291 |   0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 292 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 293 |   0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 294 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 295 |   0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00, | 
 | 296 |   0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00, | 
 | 297 | }; | 
 | 298 |  | 
 | 299 |  | 
 | 300 | // wlan0 (phy #0): connection quality monitor event: peer c0:3f:0e:77:e8:7f | 
 | 301 | // didn't ACK 50 packets | 
 | 302 |  | 
 | 303 | const uint32_t kExpectedCqmNotAcked = 50; | 
 | 304 |  | 
 | 305 | const unsigned char kNL80211_CMD_NOTIFY_CQM[] = { | 
 | 306 |   0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 307 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 308 |   0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 309 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 310 |   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00, | 
 | 311 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00, | 
 | 312 |   0x0c, 0x00, 0x5e, 0x00, 0x08, 0x00, 0x04, 0x00, | 
 | 313 |   0x32, 0x00, 0x00, 0x00, | 
 | 314 | }; | 
 | 315 |  | 
 | 316 |  | 
 | 317 | // wlan0 (phy #0): disassoc 48:5d:60:77:2d:cf -> c0:3f:0e:77:e8:7f reason 3: | 
 | 318 | // Deauthenticated because sending station is  [frame: a0 00 00 00 c0 3f 0e | 
 | 319 | // 77 e8 7f 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f 00 00 03 00] | 
 | 320 |  | 
 | 321 | const unsigned char kDisassociateFrame[] = { | 
 | 322 |   0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77, | 
 | 323 |   0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf, | 
 | 324 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00, | 
 | 325 |   0x03, 0x00 | 
 | 326 | }; | 
 | 327 |  | 
 | 328 | const unsigned char kNL80211_CMD_DISASSOCIATE[] = { | 
 | 329 |   0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, | 
 | 330 |   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
 | 331 |   0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, | 
 | 332 |   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, | 
 | 333 |   0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00, | 
 | 334 |   0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77, | 
 | 335 |   0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf, | 
 | 336 |   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00, | 
 | 337 |   0x03, 0x00, 0x00, 0x00, | 
 | 338 | }; | 
 | 339 |  | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 340 | }  // namespace | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 341 |  | 
 | 342 | class Config80211Test : public Test { | 
 | 343 |  public: | 
 | 344 |   Config80211Test() : config80211_(Config80211::GetInstance()) {} | 
 | 345 |   void SetupConfig80211Object() { | 
 | 346 |     EXPECT_NE(config80211_, reinterpret_cast<Config80211 *>(NULL)); | 
 | 347 |     config80211_->sock_ = &socket_; | 
 | 348 |     EXPECT_TRUE(config80211_->Init(reinterpret_cast<EventDispatcher *>(NULL))); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 349 |     config80211_->Reset(); | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 350 |   } | 
 | 351 |  | 
 | 352 |   Config80211 *config80211_; | 
 | 353 |   MockNl80211Socket socket_; | 
 | 354 | }; | 
 | 355 |  | 
 | 356 | class TestCallbackObject { | 
 | 357 |  public: | 
 | 358 |   TestCallbackObject() : callback_(Bind(&TestCallbackObject::MessageHandler, | 
 | 359 |                                         Unretained(this))) { } | 
 | 360 |   void MessageHandler(const UserBoundNlMessage &msg) { | 
 | 361 |   } | 
 | 362 |   const Config80211::Callback &GetCallback() const { return callback_; } | 
 | 363 |  | 
 | 364 |  private: | 
 | 365 |   Config80211::Callback callback_; | 
 | 366 | }; | 
 | 367 |  | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 368 | // Checks a config80211 parameter to make sure it contains |callback_arg| | 
 | 369 | // in its list of broadcast callbacks. | 
 | 370 | MATCHER_P(ContainsCallback, callback_arg, "") { | 
 | 371 |   if (arg == reinterpret_cast<void *>(NULL)) { | 
 | 372 |     LOG(WARNING) << "NULL parameter"; | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 373 |     return false; | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 374 |   } | 
 | 375 |   const Config80211 *config80211 = static_cast<Config80211 *>(arg); | 
 | 376 |   const Config80211::Callback callback = | 
 | 377 |       static_cast<const Config80211::Callback>(callback_arg); | 
 | 378 |  | 
 | 379 |   return config80211->FindBroadcastCallback(callback); | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 380 | } | 
 | 381 |  | 
 | 382 | TEST_F(Config80211Test, AddLinkTest) { | 
 | 383 |   SetupConfig80211Object(); | 
 | 384 |  | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 385 |   // Create a broadcast callback. | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 386 |   TestCallbackObject callback_object; | 
 | 387 |  | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 388 |   // Install the callback and subscribe to events using it, wifi down | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 389 |   // (shouldn't actually send the subscription request until wifi comes up). | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 390 |   EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0); | 
 | 391 |   EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0); | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 392 |   EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 393 |  | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 394 |   EXPECT_TRUE(config80211_->AddBroadcastCallback( | 
 | 395 |       callback_object.GetCallback())); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 396 |   Config80211::EventType scan_event = Config80211::kEventTypeScan; | 
 | 397 |   string scan_event_string; | 
 | 398 |   EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string)); | 
 | 399 |   EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event)); | 
 | 400 |  | 
 | 401 |   // Wifi up, should subscribe to events. | 
 | 402 |   EXPECT_CALL(socket_, AddGroupMembership(scan_event_string)) | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 403 |       .WillOnce(Return(true)); | 
 | 404 |   EXPECT_CALL(socket_, DisableSequenceChecking()) | 
 | 405 |       .WillOnce(Return(true)); | 
 | 406 |   EXPECT_CALL(socket_, SetNetlinkCallback( | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 407 |       _, ContainsCallback(callback_object.GetCallback()))) | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 408 |       .WillOnce(Return(true)); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 409 |   config80211_->SetWifiState(Config80211::kWifiUp); | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 410 |  | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 411 |   // Second subscribe, same event (should do nothing). | 
 | 412 |   EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0); | 
 | 413 |   EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0); | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 414 |   EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 415 |   EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event)); | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 416 |  | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 417 |   // Bring the wifi back down. | 
 | 418 |   config80211_->SetWifiState(Config80211::kWifiDown); | 
 | 419 |  | 
 | 420 |   // Subscribe to a new event with the wifi down (should still do nothing). | 
 | 421 |   Config80211::EventType mlme_event = Config80211::kEventTypeMlme; | 
 | 422 |   string mlme_event_string; | 
 | 423 |   EXPECT_TRUE(Config80211::GetEventTypeString(mlme_event, &mlme_event_string)); | 
 | 424 |   EXPECT_TRUE(config80211_->SubscribeToEvents(mlme_event)); | 
 | 425 |  | 
 | 426 |   // Wifi up (again), should subscribe to the original scan event and the new | 
 | 427 |   // mlme event. | 
 | 428 |   EXPECT_CALL(socket_, AddGroupMembership(scan_event_string)) | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 429 |       .WillOnce(Return(true)); | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 430 |   EXPECT_CALL(socket_, AddGroupMembership(mlme_event_string)) | 
 | 431 |       .WillOnce(Return(true)); | 
 | 432 |   EXPECT_CALL(socket_, DisableSequenceChecking()) | 
 | 433 |       .Times(2) | 
 | 434 |       .WillRepeatedly(Return(true)); | 
 | 435 |   EXPECT_CALL(socket_, SetNetlinkCallback( | 
| Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 436 |        _, ContainsCallback(callback_object.GetCallback()))) | 
| Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 437 |       .Times(2) | 
 | 438 |       .WillRepeatedly(Return(true)); | 
 | 439 |   config80211_->SetWifiState(Config80211::kWifiUp); | 
| Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 440 | } | 
 | 441 |  | 
 | 442 | TEST_F(Config80211Test, NL80211_CMD_TRIGGER_SCAN) { | 
 | 443 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 444 |       const_cast<nlmsghdr *>( | 
 | 445 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_TRIGGER_SCAN))); | 
 | 446 |  | 
 | 447 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 448 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_TRIGGER_SCAN); | 
 | 449 |  | 
 | 450 |   { | 
 | 451 |     uint8_t value; | 
 | 452 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 453 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 454 |   } | 
 | 455 |  | 
 | 456 |   { | 
 | 457 |     uint32_t value; | 
 | 458 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 459 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 460 |   } | 
 | 461 |  | 
 | 462 |   // Make sure the scan frequencies in the attribute are the ones we expect. | 
 | 463 |   { | 
 | 464 |     vector<uint32_t>list; | 
 | 465 |     EXPECT_TRUE(message->GetScanFrequenciesAttribute( | 
 | 466 |         NL80211_ATTR_SCAN_FREQUENCIES, &list)); | 
 | 467 |     EXPECT_EQ(arraysize(kScanFrequencyTrigger), list.size()); | 
 | 468 |     int i = 0; | 
 | 469 |     vector<uint32_t>::const_iterator j = list.begin(); | 
 | 470 |     while (j != list.end()) { | 
 | 471 |       EXPECT_EQ(kScanFrequencyTrigger[i], *j); | 
 | 472 |       ++i; | 
 | 473 |       ++j; | 
 | 474 |     } | 
 | 475 |   } | 
 | 476 |  | 
 | 477 |   { | 
 | 478 |     vector<string> ssids; | 
 | 479 |     EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS, | 
 | 480 |                                                &ssids)); | 
 | 481 |     EXPECT_EQ(ssids.size(), 1); | 
 | 482 |     EXPECT_EQ(ssids[0].compare(""), 0);  // Expect a single, empty SSID. | 
 | 483 |   } | 
 | 484 |  | 
 | 485 |   // Significant only in its existence. | 
 | 486 |   EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH)); | 
 | 487 | } | 
 | 488 |  | 
 | 489 | TEST_F(Config80211Test, NL80211_CMD_NEW_SCAN_RESULTS) { | 
 | 490 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 491 |       const_cast<nlmsghdr *>( | 
 | 492 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_SCAN_RESULTS))); | 
 | 493 |  | 
 | 494 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 495 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_SCAN_RESULTS); | 
 | 496 |  | 
 | 497 |   { | 
 | 498 |     uint8_t value; | 
 | 499 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 500 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 501 |   } | 
 | 502 |  | 
 | 503 |   { | 
 | 504 |     uint32_t value; | 
 | 505 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 506 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 507 |   } | 
 | 508 |  | 
 | 509 |   // Make sure the scan frequencies in the attribute are the ones we expect. | 
 | 510 |   { | 
 | 511 |     vector<uint32_t>list; | 
 | 512 |     EXPECT_TRUE(message->GetScanFrequenciesAttribute( | 
 | 513 |         NL80211_ATTR_SCAN_FREQUENCIES, &list)); | 
 | 514 |     EXPECT_EQ(arraysize(kScanFrequencyResults), list.size()); | 
 | 515 |     int i = 0; | 
 | 516 |     vector<uint32_t>::const_iterator j = list.begin(); | 
 | 517 |     while (j != list.end()) { | 
 | 518 |       EXPECT_EQ(kScanFrequencyResults[i], *j); | 
 | 519 |       ++i; | 
 | 520 |       ++j; | 
 | 521 |     } | 
 | 522 |   } | 
 | 523 |  | 
 | 524 |   { | 
 | 525 |     vector<string> ssids; | 
 | 526 |     EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS, | 
 | 527 |                                                &ssids)); | 
 | 528 |     EXPECT_EQ(ssids.size(), 1); | 
 | 529 |     EXPECT_EQ(ssids[0].compare(""), 0);  // Expect a single, empty SSID. | 
 | 530 |   } | 
 | 531 |  | 
 | 532 |   // Significant only in its existence. | 
 | 533 |   EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH)); | 
 | 534 | } | 
 | 535 |  | 
 | 536 | TEST_F(Config80211Test, NL80211_CMD_NEW_STATION) { | 
 | 537 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 538 |       const_cast<nlmsghdr *>( | 
 | 539 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_STATION))); | 
 | 540 |  | 
 | 541 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 542 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_STATION); | 
 | 543 |  | 
 | 544 |   { | 
 | 545 |     uint32_t value; | 
 | 546 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 547 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 548 |   } | 
 | 549 |  | 
 | 550 |   { | 
 | 551 |     string value; | 
 | 552 |     EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value)); | 
 | 553 |     EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0); | 
 | 554 |   } | 
 | 555 |  | 
 | 556 |   // TODO(wdg): Make config80211 handle nested attributes so it can deal | 
 | 557 |   // with things like NL80211_ATTR_STA_INFO (without just calling | 
 | 558 |   // nla_parse_nested). | 
 | 559 |   EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_STA_INFO)); | 
 | 560 |  | 
 | 561 |   { | 
 | 562 |     uint32_t value; | 
 | 563 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_GENERATION, &value)); | 
 | 564 |     EXPECT_EQ(value, kNewStationExpectedGeneration); | 
 | 565 |   } | 
 | 566 | } | 
 | 567 |  | 
 | 568 | TEST_F(Config80211Test, NL80211_CMD_AUTHENTICATE) { | 
 | 569 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 570 |       const_cast<nlmsghdr *>( | 
 | 571 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_AUTHENTICATE))); | 
 | 572 |  | 
 | 573 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 574 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_AUTHENTICATE); | 
 | 575 |  | 
 | 576 |   { | 
 | 577 |     uint8_t value; | 
 | 578 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 579 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 580 |   } | 
 | 581 |  | 
 | 582 |   { | 
 | 583 |     uint32_t value; | 
 | 584 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 585 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 586 |   } | 
 | 587 |  | 
 | 588 |   { | 
 | 589 |     void *rawdata = NULL; | 
 | 590 |     int frame_byte_count = 0; | 
 | 591 |     EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata, | 
 | 592 |                                              &frame_byte_count)); | 
 | 593 |     EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL)); | 
 | 594 |     const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata); | 
 | 595 |  | 
 | 596 |     Nl80211Frame frame(frame_data, frame_byte_count); | 
 | 597 |     Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame)); | 
 | 598 |  | 
 | 599 |     EXPECT_TRUE(frame.IsEqual(expected_frame)); | 
 | 600 |   } | 
 | 601 | } | 
 | 602 |  | 
 | 603 | TEST_F(Config80211Test, NL80211_CMD_ASSOCIATE) { | 
 | 604 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 605 |       const_cast<nlmsghdr *>( | 
 | 606 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_ASSOCIATE))); | 
 | 607 |  | 
 | 608 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 609 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_ASSOCIATE); | 
 | 610 |  | 
 | 611 |   { | 
 | 612 |     uint8_t value; | 
 | 613 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 614 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 615 |   } | 
 | 616 |  | 
 | 617 |   { | 
 | 618 |     uint32_t value; | 
 | 619 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 620 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 621 |   } | 
 | 622 |  | 
 | 623 |   { | 
 | 624 |     void *rawdata = NULL; | 
 | 625 |     int frame_byte_count = 0; | 
 | 626 |     EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata, | 
 | 627 |                                              &frame_byte_count)); | 
 | 628 |     EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL)); | 
 | 629 |     const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata); | 
 | 630 |  | 
 | 631 |     Nl80211Frame frame(frame_data, frame_byte_count); | 
 | 632 |     Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame)); | 
 | 633 |  | 
 | 634 |     EXPECT_TRUE(frame.IsEqual(expected_frame)); | 
 | 635 |   } | 
 | 636 | } | 
 | 637 |  | 
 | 638 | TEST_F(Config80211Test, NL80211_CMD_CONNECT) { | 
 | 639 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 640 |       const_cast<nlmsghdr *>( | 
 | 641 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_CONNECT))); | 
 | 642 |  | 
 | 643 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 644 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_CONNECT); | 
 | 645 |  | 
 | 646 |   { | 
 | 647 |     uint8_t value; | 
 | 648 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 649 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 650 |   } | 
 | 651 |  | 
 | 652 |   { | 
 | 653 |     uint32_t value; | 
 | 654 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 655 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 656 |   } | 
 | 657 |  | 
 | 658 |   { | 
 | 659 |     string value; | 
 | 660 |     EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value)); | 
 | 661 |     EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0); | 
 | 662 |   } | 
 | 663 |  | 
 | 664 |   { | 
 | 665 |     uint16_t value; | 
 | 666 |     EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_STATUS_CODE, &value)); | 
 | 667 |     EXPECT_EQ(value, kExpectedConnectStatus); | 
 | 668 |   } | 
 | 669 |  | 
 | 670 |   // TODO(wdg): Need to check the value of this attribute. | 
 | 671 |   EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_RESP_IE)); | 
 | 672 | } | 
 | 673 |  | 
 | 674 | TEST_F(Config80211Test, NL80211_CMD_DEAUTHENTICATE) { | 
 | 675 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 676 |       const_cast<nlmsghdr *>( | 
 | 677 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DEAUTHENTICATE))); | 
 | 678 |  | 
 | 679 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 680 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DEAUTHENTICATE); | 
 | 681 |  | 
 | 682 |   { | 
 | 683 |     uint8_t value; | 
 | 684 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 685 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 686 |   } | 
 | 687 |  | 
 | 688 |   { | 
 | 689 |     uint32_t value; | 
 | 690 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 691 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 692 |   } | 
 | 693 |  | 
 | 694 |   { | 
 | 695 |     void *rawdata = NULL; | 
 | 696 |     int frame_byte_count = 0; | 
 | 697 |     EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata, | 
 | 698 |                                              &frame_byte_count)); | 
 | 699 |     EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL)); | 
 | 700 |     const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata); | 
 | 701 |  | 
 | 702 |     Nl80211Frame frame(frame_data, frame_byte_count); | 
 | 703 |     Nl80211Frame expected_frame(kDeauthenticateFrame, | 
 | 704 |                                 sizeof(kDeauthenticateFrame)); | 
 | 705 |  | 
 | 706 |     EXPECT_TRUE(frame.IsEqual(expected_frame)); | 
 | 707 |   } | 
 | 708 | } | 
 | 709 |  | 
 | 710 | TEST_F(Config80211Test, NL80211_CMD_DISCONNECT) { | 
 | 711 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 712 |       const_cast<nlmsghdr *>( | 
 | 713 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT))); | 
 | 714 |  | 
 | 715 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 716 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISCONNECT); | 
 | 717 |  | 
 | 718 |   { | 
 | 719 |     uint8_t value; | 
 | 720 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 721 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 722 |   } | 
 | 723 |  | 
 | 724 |   { | 
 | 725 |     uint32_t value; | 
 | 726 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 727 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 728 |   } | 
 | 729 |  | 
 | 730 |   { | 
 | 731 |     uint16_t value; | 
 | 732 |     EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_REASON_CODE, &value)); | 
 | 733 |     EXPECT_EQ(value, kExpectedDisconnectReason); | 
 | 734 |   } | 
 | 735 |  | 
 | 736 |   // Significant only in its existence. | 
 | 737 |   EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_DISCONNECTED_BY_AP)); | 
 | 738 | } | 
 | 739 |  | 
 | 740 | TEST_F(Config80211Test, NL80211_CMD_NOTIFY_CQM) { | 
 | 741 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 742 |       const_cast<nlmsghdr *>( | 
 | 743 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NOTIFY_CQM))); | 
 | 744 |  | 
 | 745 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 746 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NOTIFY_CQM); | 
 | 747 |  | 
 | 748 |  | 
 | 749 |   { | 
 | 750 |     uint8_t value; | 
 | 751 |     EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value)); | 
 | 752 |     EXPECT_EQ(value, kExpectedWifi); | 
 | 753 |   } | 
 | 754 |  | 
 | 755 |   { | 
 | 756 |     uint32_t value; | 
 | 757 |     EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value)); | 
 | 758 |     EXPECT_EQ(value, kExpectedIfIndex); | 
 | 759 |   } | 
 | 760 |  | 
 | 761 |   { | 
 | 762 |     string value; | 
 | 763 |     EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value)); | 
 | 764 |     EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0); | 
 | 765 |   } | 
 | 766 |  | 
 | 767 |   // TODO(wdg): Make config80211 handle nested attributes so it can deal | 
 | 768 |   // with things like NL80211_ATTR_CQM (without just calling nla_parse_nested). | 
 | 769 |   { | 
 | 770 |     static const nla_policy kCqmPolicy[NL80211_ATTR_CQM_MAX + 1] = { | 
 | 771 |       { NLA_U32, 0, 0 },  // Who Knows? | 
 | 772 |       { NLA_U32, 0, 0 },  // [NL80211_ATTR_CQM_RSSI_THOLD] | 
 | 773 |       { NLA_U32, 0, 0 },  // [NL80211_ATTR_CQM_RSSI_HYST] | 
 | 774 |       { NLA_U32, 0, 0 },  // [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] | 
 | 775 |     }; | 
 | 776 |  | 
 | 777 |     EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_CQM)); | 
 | 778 |     const nlattr *const_data = message->GetAttribute(NL80211_ATTR_CQM); | 
 | 779 |     nlattr *cqm_attr = const_cast<nlattr *>(const_data); | 
 | 780 |     EXPECT_NE(cqm_attr, reinterpret_cast<nlattr *>(NULL)); | 
 | 781 |  | 
 | 782 |     nlattr *cqm[NL80211_ATTR_CQM_MAX + 1]; | 
 | 783 |     EXPECT_EQ(nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr, | 
 | 784 |                      const_cast<nla_policy *>(kCqmPolicy)), 0); | 
 | 785 |  | 
 | 786 |     EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]); | 
 | 787 |     EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]); | 
 | 788 |     EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]), | 
 | 789 |               kExpectedCqmNotAcked); | 
 | 790 |   } | 
 | 791 | } | 
 | 792 |  | 
 | 793 | TEST_F(Config80211Test, NL80211_CMD_DISASSOCIATE) { | 
 | 794 |   UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage( | 
 | 795 |       const_cast<nlmsghdr *>( | 
 | 796 |         reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISASSOCIATE))); | 
 | 797 |  | 
 | 798 |   EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL)); | 
 | 799 |   EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISASSOCIATE); | 
 | 800 |  | 
 | 801 |  | 
 | 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(kDisassociateFrame, sizeof(kDisassociateFrame)); | 
 | 824 |  | 
 | 825 |     EXPECT_TRUE(frame.IsEqual(expected_frame)); | 
 | 826 |   } | 
 | 827 | } | 
 | 828 |  | 
 | 829 | }  // namespace shill |