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