1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdint.h> 18 #include <fcntl.h> 19 #include <sys/socket.h> 20 #include <netlink/genl/genl.h> 21 #include <netlink/genl/family.h> 22 #include <netlink/genl/ctrl.h> 23 #include <linux/rtnetlink.h> 24 #include <netpacket/packet.h> 25 #include <linux/filter.h> 26 #include <linux/errqueue.h> 27 28 #include <linux/pkt_sched.h> 29 #include <netlink/object-api.h> 30 #include <netlink/netlink.h> 31 #include <netlink/socket.h> 32 #include <net/if.h> 33 34 #include "nl80211_copy.h" 35 #include <ctype.h> 36 37 #include "wifi_hal.h" 38 #include "common.h" 39 #include "cpp_bindings.h" 40 #include "vendor_definitions.h" 41 42 void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...) 43 { 44 va_list params; 45 va_start(params, fmt); 46 offset += vsnprintf(buf + offset, buf_len - offset, fmt, params); 47 va_end(params); 48 } 49 50 #define C2S(x) case x: return #x; 51 52 static const char *cmdToString(int cmd) 53 { 54 switch (cmd) { 55 C2S(NL80211_CMD_UNSPEC) 56 C2S(NL80211_CMD_GET_WIPHY) 57 C2S(NL80211_CMD_SET_WIPHY) 58 C2S(NL80211_CMD_NEW_WIPHY) 59 C2S(NL80211_CMD_DEL_WIPHY) 60 C2S(NL80211_CMD_GET_INTERFACE) 61 C2S(NL80211_CMD_SET_INTERFACE) 62 C2S(NL80211_CMD_NEW_INTERFACE) 63 C2S(NL80211_CMD_DEL_INTERFACE) 64 C2S(NL80211_CMD_GET_KEY) 65 C2S(NL80211_CMD_SET_KEY) 66 C2S(NL80211_CMD_NEW_KEY) 67 C2S(NL80211_CMD_DEL_KEY) 68 C2S(NL80211_CMD_GET_BEACON) 69 C2S(NL80211_CMD_SET_BEACON) 70 C2S(NL80211_CMD_START_AP) 71 C2S(NL80211_CMD_STOP_AP) 72 C2S(NL80211_CMD_GET_STATION) 73 C2S(NL80211_CMD_SET_STATION) 74 C2S(NL80211_CMD_NEW_STATION) 75 C2S(NL80211_CMD_DEL_STATION) 76 C2S(NL80211_CMD_GET_MPATH) 77 C2S(NL80211_CMD_SET_MPATH) 78 C2S(NL80211_CMD_NEW_MPATH) 79 C2S(NL80211_CMD_DEL_MPATH) 80 C2S(NL80211_CMD_SET_BSS) 81 C2S(NL80211_CMD_SET_REG) 82 C2S(NL80211_CMD_REQ_SET_REG) 83 C2S(NL80211_CMD_GET_MESH_CONFIG) 84 C2S(NL80211_CMD_SET_MESH_CONFIG) 85 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE) 86 C2S(NL80211_CMD_GET_REG) 87 C2S(NL80211_CMD_GET_SCAN) 88 C2S(NL80211_CMD_TRIGGER_SCAN) 89 C2S(NL80211_CMD_NEW_SCAN_RESULTS) 90 C2S(NL80211_CMD_SCAN_ABORTED) 91 C2S(NL80211_CMD_REG_CHANGE) 92 C2S(NL80211_CMD_AUTHENTICATE) 93 C2S(NL80211_CMD_ASSOCIATE) 94 C2S(NL80211_CMD_DEAUTHENTICATE) 95 C2S(NL80211_CMD_DISASSOCIATE) 96 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE) 97 C2S(NL80211_CMD_REG_BEACON_HINT) 98 C2S(NL80211_CMD_JOIN_IBSS) 99 C2S(NL80211_CMD_LEAVE_IBSS) 100 C2S(NL80211_CMD_TESTMODE) 101 C2S(NL80211_CMD_CONNECT) 102 C2S(NL80211_CMD_ROAM) 103 C2S(NL80211_CMD_DISCONNECT) 104 C2S(NL80211_CMD_SET_WIPHY_NETNS) 105 C2S(NL80211_CMD_GET_SURVEY) 106 C2S(NL80211_CMD_NEW_SURVEY_RESULTS) 107 C2S(NL80211_CMD_SET_PMKSA) 108 C2S(NL80211_CMD_DEL_PMKSA) 109 C2S(NL80211_CMD_FLUSH_PMKSA) 110 C2S(NL80211_CMD_REMAIN_ON_CHANNEL) 111 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL) 112 C2S(NL80211_CMD_SET_TX_BITRATE_MASK) 113 C2S(NL80211_CMD_REGISTER_FRAME) 114 C2S(NL80211_CMD_FRAME) 115 C2S(NL80211_CMD_FRAME_TX_STATUS) 116 C2S(NL80211_CMD_SET_POWER_SAVE) 117 C2S(NL80211_CMD_GET_POWER_SAVE) 118 C2S(NL80211_CMD_SET_CQM) 119 C2S(NL80211_CMD_NOTIFY_CQM) 120 C2S(NL80211_CMD_SET_CHANNEL) 121 C2S(NL80211_CMD_SET_WDS_PEER) 122 C2S(NL80211_CMD_FRAME_WAIT_CANCEL) 123 C2S(NL80211_CMD_JOIN_MESH) 124 C2S(NL80211_CMD_LEAVE_MESH) 125 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE) 126 C2S(NL80211_CMD_UNPROT_DISASSOCIATE) 127 C2S(NL80211_CMD_NEW_PEER_CANDIDATE) 128 C2S(NL80211_CMD_GET_WOWLAN) 129 C2S(NL80211_CMD_SET_WOWLAN) 130 C2S(NL80211_CMD_START_SCHED_SCAN) 131 C2S(NL80211_CMD_STOP_SCHED_SCAN) 132 C2S(NL80211_CMD_SCHED_SCAN_RESULTS) 133 C2S(NL80211_CMD_SCHED_SCAN_STOPPED) 134 C2S(NL80211_CMD_SET_REKEY_OFFLOAD) 135 C2S(NL80211_CMD_PMKSA_CANDIDATE) 136 C2S(NL80211_CMD_TDLS_OPER) 137 C2S(NL80211_CMD_TDLS_MGMT) 138 C2S(NL80211_CMD_UNEXPECTED_FRAME) 139 C2S(NL80211_CMD_PROBE_CLIENT) 140 C2S(NL80211_CMD_REGISTER_BEACONS) 141 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME) 142 C2S(NL80211_CMD_SET_NOACK_MAP) 143 C2S(NL80211_CMD_CH_SWITCH_NOTIFY) 144 C2S(NL80211_CMD_START_P2P_DEVICE) 145 C2S(NL80211_CMD_STOP_P2P_DEVICE) 146 C2S(NL80211_CMD_CONN_FAILED) 147 C2S(NL80211_CMD_SET_MCAST_RATE) 148 C2S(NL80211_CMD_SET_MAC_ACL) 149 C2S(NL80211_CMD_RADAR_DETECT) 150 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES) 151 C2S(NL80211_CMD_UPDATE_FT_IES) 152 C2S(NL80211_CMD_FT_EVENT) 153 C2S(NL80211_CMD_CRIT_PROTOCOL_START) 154 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP) 155 C2S(NL80211_CMD_GET_COALESCE) 156 C2S(NL80211_CMD_SET_COALESCE) 157 C2S(NL80211_CMD_CHANNEL_SWITCH) 158 C2S(NL80211_CMD_VENDOR) 159 C2S(NL80211_CMD_SET_QOS_MAP) 160 default: 161 return "NL80211_CMD_UNKNOWN"; 162 } 163 } 164 165 const char *attributeToString(int attribute) 166 { 167 switch (attribute) { 168 C2S(NL80211_ATTR_UNSPEC) 169 170 C2S(NL80211_ATTR_WIPHY) 171 C2S(NL80211_ATTR_WIPHY_NAME) 172 173 C2S(NL80211_ATTR_IFINDEX) 174 C2S(NL80211_ATTR_IFNAME) 175 C2S(NL80211_ATTR_IFTYPE) 176 177 C2S(NL80211_ATTR_MAC) 178 179 C2S(NL80211_ATTR_KEY_DATA) 180 C2S(NL80211_ATTR_KEY_IDX) 181 C2S(NL80211_ATTR_KEY_CIPHER) 182 C2S(NL80211_ATTR_KEY_SEQ) 183 C2S(NL80211_ATTR_KEY_DEFAULT) 184 185 C2S(NL80211_ATTR_BEACON_INTERVAL) 186 C2S(NL80211_ATTR_DTIM_PERIOD) 187 C2S(NL80211_ATTR_BEACON_HEAD) 188 C2S(NL80211_ATTR_BEACON_TAIL) 189 190 C2S(NL80211_ATTR_STA_AID) 191 C2S(NL80211_ATTR_STA_FLAGS) 192 C2S(NL80211_ATTR_STA_LISTEN_INTERVAL) 193 C2S(NL80211_ATTR_STA_SUPPORTED_RATES) 194 C2S(NL80211_ATTR_STA_VLAN) 195 C2S(NL80211_ATTR_STA_INFO) 196 197 C2S(NL80211_ATTR_WIPHY_BANDS) 198 199 C2S(NL80211_ATTR_MNTR_FLAGS) 200 201 C2S(NL80211_ATTR_MESH_ID) 202 C2S(NL80211_ATTR_STA_PLINK_ACTION) 203 C2S(NL80211_ATTR_MPATH_NEXT_HOP) 204 C2S(NL80211_ATTR_MPATH_INFO) 205 206 C2S(NL80211_ATTR_BSS_CTS_PROT) 207 C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE) 208 C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME) 209 210 C2S(NL80211_ATTR_HT_CAPABILITY) 211 212 C2S(NL80211_ATTR_SUPPORTED_IFTYPES) 213 214 C2S(NL80211_ATTR_REG_ALPHA2) 215 C2S(NL80211_ATTR_REG_RULES) 216 217 C2S(NL80211_ATTR_MESH_CONFIG) 218 219 C2S(NL80211_ATTR_BSS_BASIC_RATES) 220 221 C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS) 222 C2S(NL80211_ATTR_WIPHY_FREQ) 223 C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE) 224 225 C2S(NL80211_ATTR_KEY_DEFAULT_MGMT) 226 227 C2S(NL80211_ATTR_MGMT_SUBTYPE) 228 C2S(NL80211_ATTR_IE) 229 230 C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS) 231 232 C2S(NL80211_ATTR_SCAN_FREQUENCIES) 233 C2S(NL80211_ATTR_SCAN_SSIDS) 234 C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */ 235 C2S(NL80211_ATTR_BSS) 236 237 C2S(NL80211_ATTR_REG_INITIATOR) 238 C2S(NL80211_ATTR_REG_TYPE) 239 240 C2S(NL80211_ATTR_SUPPORTED_COMMANDS) 241 242 C2S(NL80211_ATTR_FRAME) 243 C2S(NL80211_ATTR_SSID) 244 C2S(NL80211_ATTR_AUTH_TYPE) 245 C2S(NL80211_ATTR_REASON_CODE) 246 247 C2S(NL80211_ATTR_KEY_TYPE) 248 249 C2S(NL80211_ATTR_MAX_SCAN_IE_LEN) 250 C2S(NL80211_ATTR_CIPHER_SUITES) 251 252 C2S(NL80211_ATTR_FREQ_BEFORE) 253 C2S(NL80211_ATTR_FREQ_AFTER) 254 255 C2S(NL80211_ATTR_FREQ_FIXED) 256 257 258 C2S(NL80211_ATTR_WIPHY_RETRY_SHORT) 259 C2S(NL80211_ATTR_WIPHY_RETRY_LONG) 260 C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD) 261 C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD) 262 263 C2S(NL80211_ATTR_TIMED_OUT) 264 265 C2S(NL80211_ATTR_USE_MFP) 266 267 C2S(NL80211_ATTR_STA_FLAGS2) 268 269 C2S(NL80211_ATTR_CONTROL_PORT) 270 271 C2S(NL80211_ATTR_TESTDATA) 272 273 C2S(NL80211_ATTR_PRIVACY) 274 275 C2S(NL80211_ATTR_DISCONNECTED_BY_AP) 276 C2S(NL80211_ATTR_STATUS_CODE) 277 278 C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE) 279 C2S(NL80211_ATTR_CIPHER_SUITE_GROUP) 280 C2S(NL80211_ATTR_WPA_VERSIONS) 281 C2S(NL80211_ATTR_AKM_SUITES) 282 283 C2S(NL80211_ATTR_REQ_IE) 284 C2S(NL80211_ATTR_RESP_IE) 285 286 C2S(NL80211_ATTR_PREV_BSSID) 287 288 C2S(NL80211_ATTR_KEY) 289 C2S(NL80211_ATTR_KEYS) 290 291 C2S(NL80211_ATTR_PID) 292 293 C2S(NL80211_ATTR_4ADDR) 294 295 C2S(NL80211_ATTR_SURVEY_INFO) 296 297 C2S(NL80211_ATTR_PMKID) 298 C2S(NL80211_ATTR_MAX_NUM_PMKIDS) 299 300 C2S(NL80211_ATTR_DURATION) 301 302 C2S(NL80211_ATTR_COOKIE) 303 304 C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS) 305 306 C2S(NL80211_ATTR_TX_RATES) 307 308 C2S(NL80211_ATTR_FRAME_MATCH) 309 310 C2S(NL80211_ATTR_ACK) 311 312 C2S(NL80211_ATTR_PS_STATE) 313 314 C2S(NL80211_ATTR_CQM) 315 316 C2S(NL80211_ATTR_LOCAL_STATE_CHANGE) 317 318 C2S(NL80211_ATTR_AP_ISOLATE) 319 320 C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING) 321 C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL) 322 323 C2S(NL80211_ATTR_TX_FRAME_TYPES) 324 C2S(NL80211_ATTR_RX_FRAME_TYPES) 325 C2S(NL80211_ATTR_FRAME_TYPE) 326 327 C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE) 328 C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT) 329 330 C2S(NL80211_ATTR_SUPPORT_IBSS_RSN) 331 332 C2S(NL80211_ATTR_WIPHY_ANTENNA_TX) 333 C2S(NL80211_ATTR_WIPHY_ANTENNA_RX) 334 335 C2S(NL80211_ATTR_MCAST_RATE) 336 337 C2S(NL80211_ATTR_OFFCHANNEL_TX_OK) 338 339 C2S(NL80211_ATTR_BSS_HT_OPMODE) 340 341 C2S(NL80211_ATTR_KEY_DEFAULT_TYPES) 342 343 C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION) 344 345 C2S(NL80211_ATTR_MESH_SETUP) 346 347 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX) 348 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX) 349 350 C2S(NL80211_ATTR_SUPPORT_MESH_AUTH) 351 C2S(NL80211_ATTR_STA_PLINK_STATE) 352 353 C2S(NL80211_ATTR_WOWLAN_TRIGGERS) 354 C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED) 355 356 C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL) 357 358 C2S(NL80211_ATTR_INTERFACE_COMBINATIONS) 359 C2S(NL80211_ATTR_SOFTWARE_IFTYPES) 360 361 C2S(NL80211_ATTR_REKEY_DATA) 362 363 C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS) 364 C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN) 365 366 C2S(NL80211_ATTR_SCAN_SUPP_RATES) 367 368 C2S(NL80211_ATTR_HIDDEN_SSID) 369 370 C2S(NL80211_ATTR_IE_PROBE_RESP) 371 C2S(NL80211_ATTR_IE_ASSOC_RESP) 372 373 C2S(NL80211_ATTR_STA_WME) 374 C2S(NL80211_ATTR_SUPPORT_AP_UAPSD) 375 376 C2S(NL80211_ATTR_ROAM_SUPPORT) 377 378 C2S(NL80211_ATTR_SCHED_SCAN_MATCH) 379 C2S(NL80211_ATTR_MAX_MATCH_SETS) 380 381 C2S(NL80211_ATTR_PMKSA_CANDIDATE) 382 383 C2S(NL80211_ATTR_TX_NO_CCK_RATE) 384 385 C2S(NL80211_ATTR_TDLS_ACTION) 386 C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN) 387 C2S(NL80211_ATTR_TDLS_OPERATION) 388 C2S(NL80211_ATTR_TDLS_SUPPORT) 389 C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP) 390 391 C2S(NL80211_ATTR_DEVICE_AP_SME) 392 393 C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK) 394 395 C2S(NL80211_ATTR_FEATURE_FLAGS) 396 397 C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD) 398 399 C2S(NL80211_ATTR_PROBE_RESP) 400 401 C2S(NL80211_ATTR_DFS_REGION) 402 403 C2S(NL80211_ATTR_DISABLE_HT) 404 C2S(NL80211_ATTR_HT_CAPABILITY_MASK) 405 406 C2S(NL80211_ATTR_NOACK_MAP) 407 408 C2S(NL80211_ATTR_INACTIVITY_TIMEOUT) 409 410 C2S(NL80211_ATTR_RX_SIGNAL_DBM) 411 412 C2S(NL80211_ATTR_BG_SCAN_PERIOD) 413 414 C2S(NL80211_ATTR_WDEV) 415 416 C2S(NL80211_ATTR_USER_REG_HINT_TYPE) 417 418 C2S(NL80211_ATTR_CONN_FAILED_REASON) 419 420 C2S(NL80211_ATTR_SAE_DATA) 421 422 C2S(NL80211_ATTR_VHT_CAPABILITY) 423 424 C2S(NL80211_ATTR_SCAN_FLAGS) 425 426 C2S(NL80211_ATTR_CHANNEL_WIDTH) 427 C2S(NL80211_ATTR_CENTER_FREQ1) 428 C2S(NL80211_ATTR_CENTER_FREQ2) 429 430 C2S(NL80211_ATTR_P2P_CTWINDOW) 431 C2S(NL80211_ATTR_P2P_OPPPS) 432 433 C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE) 434 435 C2S(NL80211_ATTR_ACL_POLICY) 436 437 C2S(NL80211_ATTR_MAC_ADDRS) 438 439 C2S(NL80211_ATTR_MAC_ACL_MAX) 440 441 C2S(NL80211_ATTR_RADAR_EVENT) 442 443 C2S(NL80211_ATTR_EXT_CAPA) 444 C2S(NL80211_ATTR_EXT_CAPA_MASK) 445 446 C2S(NL80211_ATTR_STA_CAPABILITY) 447 C2S(NL80211_ATTR_STA_EXT_CAPABILITY) 448 449 C2S(NL80211_ATTR_PROTOCOL_FEATURES) 450 C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP) 451 452 C2S(NL80211_ATTR_DISABLE_VHT) 453 C2S(NL80211_ATTR_VHT_CAPABILITY_MASK) 454 455 C2S(NL80211_ATTR_MDID) 456 C2S(NL80211_ATTR_IE_RIC) 457 458 C2S(NL80211_ATTR_CRIT_PROT_ID) 459 C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION) 460 461 C2S(NL80211_ATTR_PEER_AID) 462 463 C2S(NL80211_ATTR_COALESCE_RULE) 464 465 C2S(NL80211_ATTR_CH_SWITCH_COUNT) 466 C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX) 467 C2S(NL80211_ATTR_CSA_IES) 468 C2S(NL80211_ATTR_CSA_C_OFF_BEACON) 469 C2S(NL80211_ATTR_CSA_C_OFF_PRESP) 470 471 C2S(NL80211_ATTR_RXMGMT_FLAGS) 472 473 C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS) 474 475 C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES) 476 477 C2S(NL80211_ATTR_HANDLE_DFS) 478 479 C2S(NL80211_ATTR_SUPPORT_5_MHZ) 480 C2S(NL80211_ATTR_SUPPORT_10_MHZ) 481 482 C2S(NL80211_ATTR_OPMODE_NOTIF) 483 484 C2S(NL80211_ATTR_VENDOR_ID) 485 C2S(NL80211_ATTR_VENDOR_SUBCMD) 486 C2S(NL80211_ATTR_VENDOR_DATA) 487 C2S(NL80211_ATTR_VENDOR_EVENTS) 488 489 C2S(NL80211_ATTR_QOS_MAP) 490 default: 491 return "NL80211_ATTR_UNKNOWN"; 492 } 493 } 494 495 void WifiEvent::log() { 496 parse(); 497 498 byte *data = (byte *)genlmsg_attrdata(mHeader, 0); 499 int len = genlmsg_attrlen(mHeader, 0); 500 501 for (int i = 0; i < len; i += 16) { 502 char line[81]; 503 int linelen = min(16, len - i); 504 int offset = 0; 505 appendFmt(line, sizeof(line), offset, "%02x", data[i]); 506 for (int j = 1; j < linelen; j++) { 507 appendFmt(line, sizeof(line), offset, " %02x", data[i+j]); 508 } 509 510 for (int j = linelen; j < 16; j++) { 511 appendFmt(line, sizeof(line), offset, " "); 512 } 513 514 line[23] = '-'; 515 516 appendFmt(line, sizeof(line), offset, " "); 517 518 for (int j = 0; j < linelen; j++) { 519 if (isprint(data[i+j])) { 520 appendFmt(line, sizeof(line), offset, "%c", data[i+j]); 521 } else { 522 appendFmt(line, sizeof(line), offset, "-"); 523 } 524 } 525 526 } 527 528 } 529 530 const char *WifiEvent::get_cmdString() { 531 return cmdToString(get_cmd()); 532 } 533 534 535 int WifiEvent::parse() { 536 if (mHeader != NULL) { 537 return WIFI_SUCCESS; 538 } 539 mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg)); 540 int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0), 541 genlmsg_attrlen(mHeader, 0), NULL); 542 543 return result; 544 } 545 546 wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) { 547 548 destroy(); 549 550 mMsg = nlmsg_alloc(); 551 if (mMsg != NULL) { 552 genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family, 553 hdrlen, flags, cmd, /* version = */ 0); 554 return WIFI_SUCCESS; 555 } else { 556 return WIFI_ERROR_OUT_OF_MEMORY; 557 } 558 } 559 560 wifi_error WifiRequest::create(uint32_t id, int subcmd) { 561 wifi_error res = create(NL80211_CMD_VENDOR); 562 if (res != WIFI_SUCCESS) 563 return res; 564 565 res = put_u32(NL80211_ATTR_VENDOR_ID, id); 566 if (res != WIFI_SUCCESS) 567 return res; 568 569 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd); 570 if (res != WIFI_SUCCESS) 571 return res; 572 573 if (mIface != -1) 574 res = set_iface_id(mIface); 575 576 return res; 577 } 578 579 580 static int no_seq_check(struct nl_msg *msg, void *arg) 581 { 582 return NL_OK; 583 } 584 585 wifi_error WifiCommand::requestResponse() 586 { 587 wifi_error err = create(); /* create the message */ 588 if (err != WIFI_SUCCESS) 589 return err; 590 591 return requestResponse(mMsg); 592 } 593 594 wifi_error WifiCommand::requestResponse(WifiRequest& request) 595 { 596 int err = 0; 597 598 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 599 if (!cb) 600 goto out; 601 602 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */ 603 if (err < 0) 604 goto out; 605 606 err = 1; 607 608 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); 609 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); 610 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); 611 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); 612 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this); 613 614 while (err > 0) { /* wait for reply */ 615 int res = nl_recvmsgs(mInfo->cmd_sock, cb); 616 if (res) { 617 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res); 618 } 619 } 620 out: 621 nl_cb_put(cb); 622 mMsg.destroy(); 623 return mapKernelErrortoWifiHalError(err); 624 } 625 626 wifi_error WifiCommand::requestEvent(int cmd) 627 { 628 629 int status; 630 wifi_error res = wifi_register_handler(wifiHandle(), cmd, event_handler, 631 this); 632 if (res != WIFI_SUCCESS) 633 return res; 634 635 res = create(); /* create the message */ 636 if (res != WIFI_SUCCESS) 637 goto out; 638 639 status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ 640 if (status < 0) { 641 res = mapKernelErrortoWifiHalError(status); 642 goto out; 643 } 644 645 res = mCondition.wait(); 646 if (res != WIFI_SUCCESS) 647 goto out; 648 649 out: 650 wifi_unregister_handler(wifiHandle(), cmd); 651 return res; 652 } 653 654 wifi_error WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { 655 int status; 656 wifi_error res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, 657 event_handler, this); 658 if (res != WIFI_SUCCESS) 659 return res; 660 661 res = create(); /* create the message */ 662 if (res != WIFI_SUCCESS) 663 goto out; 664 665 status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ 666 if (status < 0) { 667 res = mapKernelErrortoWifiHalError(status); 668 goto out; 669 } 670 671 res = mCondition.wait(); 672 if (res != WIFI_SUCCESS) 673 goto out; 674 675 out: 676 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); 677 return res; 678 } 679 680 /* Event handlers */ 681 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) { 682 WifiCommand *cmd = (WifiCommand *)arg; 683 WifiEvent reply(msg); 684 int res = reply.parse(); 685 if (res < 0) { 686 ALOGE("Failed to parse reply message = %d", res); 687 return NL_SKIP; 688 } else { 689 // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */ 690 return cmd->handleResponse(reply); 691 } 692 } 693 694 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) { 695 WifiCommand *cmd = (WifiCommand *)arg; 696 WifiEvent event(msg); 697 int res = event.parse(); 698 if (res < 0) { 699 ALOGE("Failed to parse event = %d", res); 700 res = NL_SKIP; 701 } else { 702 res = cmd->handleEvent(event); 703 } 704 705 cmd->mCondition.signal(); 706 return res; 707 } 708 709 /* Other event handlers */ 710 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) { 711 int *err = (int *)arg; 712 *err = 0; 713 return NL_SKIP; 714 } 715 716 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) { 717 int *err = (int *)arg; 718 *err = 0; 719 return NL_STOP; 720 } 721 722 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) { 723 int *ret = (int *)arg; 724 *ret = 0; 725 return NL_SKIP; 726 } 727 728 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { 729 int *ret = (int *)arg; 730 *ret = err->error; 731 732 return NL_SKIP; 733 } 734 735 736 WifiVendorCommand::WifiVendorCommand(wifi_handle handle, 737 wifi_request_id id, 738 u32 vendor_id, 739 u32 subcmd) 740 : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd), 741 mVendorData(NULL), mDataLen(0) 742 { 743 ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u", 744 this, mVendor_id, mSubcmd); 745 } 746 747 WifiVendorCommand::~WifiVendorCommand() 748 { 749 //ALOGV("~WifiVendorCommand %p destroyed", this); 750 //mVendorData is not destroyed here. Assumption 751 //is that VendorData is specific to each Vendor and they 752 //are responsible for owning the same. 753 } 754 755 // Override this method to parse reply and dig out data; save it 756 // in the corresponding object 757 int WifiVendorCommand::handleResponse(WifiEvent &reply) 758 { 759 struct nlattr **tb = reply.attributes(); 760 struct genlmsghdr *gnlh = reply.header(); 761 762 if (gnlh->cmd == NL80211_CMD_VENDOR) { 763 if (tb[NL80211_ATTR_VENDOR_DATA]) { 764 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]); 765 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); 766 } 767 } 768 return NL_SKIP; 769 } 770 771 // Override this method to parse event and dig out data; 772 // save it in the object 773 int WifiVendorCommand::handleEvent(WifiEvent &event) 774 { 775 struct nlattr **tb = event.attributes(); 776 struct genlmsghdr *gnlh = event.header(); 777 778 if (gnlh->cmd == NL80211_CMD_VENDOR) { 779 /* Vendor Event */ 780 if (!tb[NL80211_ATTR_VENDOR_ID] || 781 !tb[NL80211_ATTR_VENDOR_SUBCMD]) 782 return NL_SKIP; 783 784 mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]); 785 mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]); 786 787 ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u", 788 __FUNCTION__, mVendor_id, mSubcmd); 789 790 if (tb[NL80211_ATTR_VENDOR_DATA]) { 791 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]); 792 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); 793 ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen); 794 hexdump(mVendorData, mDataLen); 795 } 796 } 797 return NL_SKIP; 798 } 799 800 wifi_error WifiVendorCommand::create() { 801 int ifindex; 802 wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); 803 if (ret != WIFI_SUCCESS) 804 return ret; 805 806 // insert the oui in the msg 807 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); 808 if (ret != WIFI_SUCCESS) 809 goto out; 810 811 // insert the subcmd in the msg 812 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); 813 if (ret != WIFI_SUCCESS) 814 goto out; 815 816 //Insert the vendor specific data 817 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 818 if (ret != WIFI_SUCCESS) 819 goto out; 820 hexdump(mVendorData, mDataLen); 821 822 //insert the iface id to be "wlan0" 823 ifindex = if_nametoindex("wlan0"); 824 ret = mMsg.set_iface_id(ifindex); 825 out: 826 return ret; 827 } 828 829 wifi_error WifiVendorCommand::requestResponse() 830 { 831 return WifiCommand::requestResponse(mMsg); 832 } 833 834 wifi_error WifiVendorCommand::requestEvent() 835 { 836 wifi_error res = requestVendorEvent(mVendor_id, mSubcmd); 837 return res; 838 } 839 840 wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value) 841 { 842 return mMsg.put_u8(attribute, value); 843 } 844 845 wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value) 846 { 847 return mMsg.put_u16(attribute, value); 848 } 849 850 wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value) 851 { 852 return mMsg.put_u32(attribute, value); 853 } 854 855 wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value) 856 { 857 return mMsg.put_u64(attribute, value); 858 } 859 860 wifi_error WifiVendorCommand::put_s8(int attribute, s8 value) 861 { 862 return mMsg.put_s8(attribute, value); 863 } 864 865 wifi_error WifiVendorCommand::put_s16(int attribute, s16 value) 866 { 867 return mMsg.put_s16(attribute, value); 868 } 869 870 wifi_error WifiVendorCommand::put_s32(int attribute, s32 value) 871 { 872 return mMsg.put_s32(attribute, value); 873 } 874 875 wifi_error WifiVendorCommand::put_s64(int attribute, s64 value) 876 { 877 return mMsg.put_s64(attribute, value); 878 } 879 880 wifi_error WifiVendorCommand::put_flag(int attribute) 881 { 882 return mMsg.put_flag(attribute); 883 } 884 885 u8 WifiVendorCommand::get_u8(const struct nlattr *nla) 886 { 887 return mMsg.get_u8(nla); 888 } 889 890 u16 WifiVendorCommand::get_u16(const struct nlattr *nla) 891 { 892 return mMsg.get_u16(nla); 893 } 894 895 u32 WifiVendorCommand::get_u32(const struct nlattr *nla) 896 { 897 return mMsg.get_u32(nla); 898 } 899 900 u64 WifiVendorCommand::get_u64(const struct nlattr *nla) 901 { 902 return mMsg.get_u64(nla); 903 } 904 905 s8 WifiVendorCommand::get_s8(const struct nlattr *nla) 906 { 907 return mMsg.get_s8(nla); 908 } 909 910 s16 WifiVendorCommand::get_s16(const struct nlattr *nla) 911 { 912 return mMsg.get_s16(nla); 913 } 914 915 s32 WifiVendorCommand::get_s32(const struct nlattr *nla) 916 { 917 return mMsg.get_s32(nla); 918 } 919 920 s64 WifiVendorCommand::get_s64(const struct nlattr *nla) 921 { 922 return mMsg.get_s64(nla); 923 } 924 925 wifi_error WifiVendorCommand::put_string(int attribute, const char *value) 926 { 927 return mMsg.put_string(attribute, value); 928 } 929 930 wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value) 931 { 932 return mMsg.put_addr(attribute, value); 933 } 934 935 struct nlattr * WifiVendorCommand::attr_start(int attribute) 936 { 937 return mMsg.attr_start(attribute); 938 } 939 940 void WifiVendorCommand::attr_end(struct nlattr *attribute) 941 { 942 return mMsg.attr_end(attribute); 943 } 944 945 wifi_error WifiVendorCommand::set_iface_id(const char* name) 946 { 947 unsigned ifindex = if_nametoindex(name); 948 return mMsg.set_iface_id(ifindex); 949 } 950 951 wifi_error WifiVendorCommand::put_bytes(int attribute, 952 const char *data, 953 int len) 954 { 955 return mMsg.put_bytes(attribute, data, len); 956 } 957 958 wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor, 959 int attribute, 960 mac_addr addr) 961 { 962 if (!tb_vendor[attribute]) { 963 ALOGE("Failed to get attribute : %d", attribute); 964 return WIFI_ERROR_INVALID_ARGS; 965 } 966 if (!addr) { 967 ALOGE("addr is NULL"); 968 return WIFI_ERROR_INVALID_ARGS; 969 } 970 971 if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) { 972 ALOGE("Invalid mac addr lenght\n"); 973 return WIFI_ERROR_INVALID_ARGS; 974 } 975 976 memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]), 977 nla_len(tb_vendor[attribute])); 978 979 return WIFI_SUCCESS; 980 } 981 982 wifi_error initialize_vendor_cmd(wifi_interface_handle iface, 983 wifi_request_id id, 984 u32 subcmd, 985 WifiVendorCommand **vCommand) 986 { 987 wifi_error ret; 988 interface_info *ifaceInfo = getIfaceInfo(iface); 989 wifi_handle wifiHandle = getWifiHandle(iface); 990 991 if (vCommand == NULL) { 992 ALOGE("%s: Error vCommand NULL", __FUNCTION__); 993 return WIFI_ERROR_INVALID_ARGS; 994 } 995 996 *vCommand = new WifiVendorCommand(wifiHandle, id, 997 OUI_QCA, 998 subcmd); 999 if (*vCommand == NULL) { 1000 ALOGE("%s: Object creation failed", __FUNCTION__); 1001 return WIFI_ERROR_OUT_OF_MEMORY; 1002 } 1003 1004 /* Create the message */ 1005 ret = (*vCommand)->create(); 1006 if (ret != WIFI_SUCCESS) 1007 goto cleanup; 1008 1009 ret = (*vCommand)->set_iface_id(ifaceInfo->name); 1010 if (ret != WIFI_SUCCESS) 1011 goto cleanup; 1012 1013 return WIFI_SUCCESS; 1014 1015 cleanup: 1016 delete *vCommand; 1017 return ret; 1018 } 1019