1 2 #include <stdint.h> 3 #include <fcntl.h> 4 #include <sys/socket.h> 5 #include <netlink/genl/genl.h> 6 #include <netlink/genl/family.h> 7 #include <netlink/genl/ctrl.h> 8 #include <linux/rtnetlink.h> 9 #include <netpacket/packet.h> 10 #include <linux/filter.h> 11 #include <linux/errqueue.h> 12 13 #include <linux/pkt_sched.h> 14 #include <netlink/object-api.h> 15 #include <netlink/netlink.h> 16 #include <netlink/socket.h> 17 #include <netlink/handlers.h> 18 19 #include <ctype.h> 20 21 #include "wifi_hal.h" 22 #include "common.h" 23 #include "cpp_bindings.h" 24 25 void appendFmt(char *buf, int &offset, const char *fmt, ...) 26 { 27 va_list params; 28 va_start(params, fmt); 29 offset += vsprintf(buf + offset, fmt, params); 30 va_end(params); 31 } 32 33 #define C2S(x) case x: return #x; 34 35 static const char *cmdToString(int cmd) 36 { 37 switch (cmd) { 38 C2S(NL80211_CMD_UNSPEC) 39 C2S(NL80211_CMD_GET_WIPHY) 40 C2S(NL80211_CMD_SET_WIPHY) 41 C2S(NL80211_CMD_NEW_WIPHY) 42 C2S(NL80211_CMD_DEL_WIPHY) 43 C2S(NL80211_CMD_GET_INTERFACE) 44 C2S(NL80211_CMD_SET_INTERFACE) 45 C2S(NL80211_CMD_NEW_INTERFACE) 46 C2S(NL80211_CMD_DEL_INTERFACE) 47 C2S(NL80211_CMD_GET_KEY) 48 C2S(NL80211_CMD_SET_KEY) 49 C2S(NL80211_CMD_NEW_KEY) 50 C2S(NL80211_CMD_DEL_KEY) 51 C2S(NL80211_CMD_GET_BEACON) 52 C2S(NL80211_CMD_SET_BEACON) 53 C2S(NL80211_CMD_START_AP) 54 C2S(NL80211_CMD_STOP_AP) 55 C2S(NL80211_CMD_GET_STATION) 56 C2S(NL80211_CMD_SET_STATION) 57 C2S(NL80211_CMD_NEW_STATION) 58 C2S(NL80211_CMD_DEL_STATION) 59 C2S(NL80211_CMD_GET_MPATH) 60 C2S(NL80211_CMD_SET_MPATH) 61 C2S(NL80211_CMD_NEW_MPATH) 62 C2S(NL80211_CMD_DEL_MPATH) 63 C2S(NL80211_CMD_SET_BSS) 64 C2S(NL80211_CMD_SET_REG) 65 C2S(NL80211_CMD_REQ_SET_REG) 66 C2S(NL80211_CMD_GET_MESH_CONFIG) 67 C2S(NL80211_CMD_SET_MESH_CONFIG) 68 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE) 69 C2S(NL80211_CMD_GET_REG) 70 C2S(NL80211_CMD_GET_SCAN) 71 C2S(NL80211_CMD_TRIGGER_SCAN) 72 C2S(NL80211_CMD_NEW_SCAN_RESULTS) 73 C2S(NL80211_CMD_SCAN_ABORTED) 74 C2S(NL80211_CMD_REG_CHANGE) 75 C2S(NL80211_CMD_AUTHENTICATE) 76 C2S(NL80211_CMD_ASSOCIATE) 77 C2S(NL80211_CMD_DEAUTHENTICATE) 78 C2S(NL80211_CMD_DISASSOCIATE) 79 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE) 80 C2S(NL80211_CMD_REG_BEACON_HINT) 81 C2S(NL80211_CMD_JOIN_IBSS) 82 C2S(NL80211_CMD_LEAVE_IBSS) 83 C2S(NL80211_CMD_TESTMODE) 84 C2S(NL80211_CMD_CONNECT) 85 C2S(NL80211_CMD_ROAM) 86 C2S(NL80211_CMD_DISCONNECT) 87 C2S(NL80211_CMD_SET_WIPHY_NETNS) 88 C2S(NL80211_CMD_GET_SURVEY) 89 C2S(NL80211_CMD_NEW_SURVEY_RESULTS) 90 C2S(NL80211_CMD_SET_PMKSA) 91 C2S(NL80211_CMD_DEL_PMKSA) 92 C2S(NL80211_CMD_FLUSH_PMKSA) 93 C2S(NL80211_CMD_REMAIN_ON_CHANNEL) 94 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL) 95 C2S(NL80211_CMD_SET_TX_BITRATE_MASK) 96 C2S(NL80211_CMD_REGISTER_FRAME) 97 C2S(NL80211_CMD_FRAME) 98 C2S(NL80211_CMD_FRAME_TX_STATUS) 99 C2S(NL80211_CMD_SET_POWER_SAVE) 100 C2S(NL80211_CMD_GET_POWER_SAVE) 101 C2S(NL80211_CMD_SET_CQM) 102 C2S(NL80211_CMD_NOTIFY_CQM) 103 C2S(NL80211_CMD_SET_CHANNEL) 104 C2S(NL80211_CMD_SET_WDS_PEER) 105 C2S(NL80211_CMD_FRAME_WAIT_CANCEL) 106 C2S(NL80211_CMD_JOIN_MESH) 107 C2S(NL80211_CMD_LEAVE_MESH) 108 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE) 109 C2S(NL80211_CMD_UNPROT_DISASSOCIATE) 110 C2S(NL80211_CMD_NEW_PEER_CANDIDATE) 111 C2S(NL80211_CMD_GET_WOWLAN) 112 C2S(NL80211_CMD_SET_WOWLAN) 113 C2S(NL80211_CMD_START_SCHED_SCAN) 114 C2S(NL80211_CMD_STOP_SCHED_SCAN) 115 C2S(NL80211_CMD_SCHED_SCAN_RESULTS) 116 C2S(NL80211_CMD_SCHED_SCAN_STOPPED) 117 C2S(NL80211_CMD_SET_REKEY_OFFLOAD) 118 C2S(NL80211_CMD_PMKSA_CANDIDATE) 119 C2S(NL80211_CMD_TDLS_OPER) 120 C2S(NL80211_CMD_TDLS_MGMT) 121 C2S(NL80211_CMD_UNEXPECTED_FRAME) 122 C2S(NL80211_CMD_PROBE_CLIENT) 123 C2S(NL80211_CMD_REGISTER_BEACONS) 124 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME) 125 C2S(NL80211_CMD_SET_NOACK_MAP) 126 C2S(NL80211_CMD_CH_SWITCH_NOTIFY) 127 C2S(NL80211_CMD_START_P2P_DEVICE) 128 C2S(NL80211_CMD_STOP_P2P_DEVICE) 129 C2S(NL80211_CMD_CONN_FAILED) 130 C2S(NL80211_CMD_SET_MCAST_RATE) 131 C2S(NL80211_CMD_SET_MAC_ACL) 132 C2S(NL80211_CMD_RADAR_DETECT) 133 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES) 134 C2S(NL80211_CMD_UPDATE_FT_IES) 135 C2S(NL80211_CMD_FT_EVENT) 136 C2S(NL80211_CMD_CRIT_PROTOCOL_START) 137 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP) 138 C2S(NL80211_CMD_GET_COALESCE) 139 C2S(NL80211_CMD_SET_COALESCE) 140 C2S(NL80211_CMD_CHANNEL_SWITCH) 141 C2S(NL80211_CMD_VENDOR) 142 C2S(NL80211_CMD_SET_QOS_MAP) 143 default: 144 return "NL80211_CMD_UNKNOWN"; 145 } 146 } 147 148 const char *attributeToString(int attribute) 149 { 150 switch (attribute) { 151 C2S(NL80211_ATTR_UNSPEC) 152 153 C2S(NL80211_ATTR_WIPHY) 154 C2S(NL80211_ATTR_WIPHY_NAME) 155 156 C2S(NL80211_ATTR_IFINDEX) 157 C2S(NL80211_ATTR_IFNAME) 158 C2S(NL80211_ATTR_IFTYPE) 159 160 C2S(NL80211_ATTR_MAC) 161 162 C2S(NL80211_ATTR_KEY_DATA) 163 C2S(NL80211_ATTR_KEY_IDX) 164 C2S(NL80211_ATTR_KEY_CIPHER) 165 C2S(NL80211_ATTR_KEY_SEQ) 166 C2S(NL80211_ATTR_KEY_DEFAULT) 167 168 C2S(NL80211_ATTR_BEACON_INTERVAL) 169 C2S(NL80211_ATTR_DTIM_PERIOD) 170 C2S(NL80211_ATTR_BEACON_HEAD) 171 C2S(NL80211_ATTR_BEACON_TAIL) 172 173 C2S(NL80211_ATTR_STA_AID) 174 C2S(NL80211_ATTR_STA_FLAGS) 175 C2S(NL80211_ATTR_STA_LISTEN_INTERVAL) 176 C2S(NL80211_ATTR_STA_SUPPORTED_RATES) 177 C2S(NL80211_ATTR_STA_VLAN) 178 C2S(NL80211_ATTR_STA_INFO) 179 180 C2S(NL80211_ATTR_WIPHY_BANDS) 181 182 C2S(NL80211_ATTR_MNTR_FLAGS) 183 184 C2S(NL80211_ATTR_MESH_ID) 185 C2S(NL80211_ATTR_STA_PLINK_ACTION) 186 C2S(NL80211_ATTR_MPATH_NEXT_HOP) 187 C2S(NL80211_ATTR_MPATH_INFO) 188 189 C2S(NL80211_ATTR_BSS_CTS_PROT) 190 C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE) 191 C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME) 192 193 C2S(NL80211_ATTR_HT_CAPABILITY) 194 195 C2S(NL80211_ATTR_SUPPORTED_IFTYPES) 196 197 C2S(NL80211_ATTR_REG_ALPHA2) 198 C2S(NL80211_ATTR_REG_RULES) 199 200 C2S(NL80211_ATTR_MESH_CONFIG) 201 202 C2S(NL80211_ATTR_BSS_BASIC_RATES) 203 204 C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS) 205 C2S(NL80211_ATTR_WIPHY_FREQ) 206 C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE) 207 208 C2S(NL80211_ATTR_KEY_DEFAULT_MGMT) 209 210 C2S(NL80211_ATTR_MGMT_SUBTYPE) 211 C2S(NL80211_ATTR_IE) 212 213 C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS) 214 215 C2S(NL80211_ATTR_SCAN_FREQUENCIES) 216 C2S(NL80211_ATTR_SCAN_SSIDS) 217 C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */ 218 C2S(NL80211_ATTR_BSS) 219 220 C2S(NL80211_ATTR_REG_INITIATOR) 221 C2S(NL80211_ATTR_REG_TYPE) 222 223 C2S(NL80211_ATTR_SUPPORTED_COMMANDS) 224 225 C2S(NL80211_ATTR_FRAME) 226 C2S(NL80211_ATTR_SSID) 227 C2S(NL80211_ATTR_AUTH_TYPE) 228 C2S(NL80211_ATTR_REASON_CODE) 229 230 C2S(NL80211_ATTR_KEY_TYPE) 231 232 C2S(NL80211_ATTR_MAX_SCAN_IE_LEN) 233 C2S(NL80211_ATTR_CIPHER_SUITES) 234 235 C2S(NL80211_ATTR_FREQ_BEFORE) 236 C2S(NL80211_ATTR_FREQ_AFTER) 237 238 C2S(NL80211_ATTR_FREQ_FIXED) 239 240 241 C2S(NL80211_ATTR_WIPHY_RETRY_SHORT) 242 C2S(NL80211_ATTR_WIPHY_RETRY_LONG) 243 C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD) 244 C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD) 245 246 C2S(NL80211_ATTR_TIMED_OUT) 247 248 C2S(NL80211_ATTR_USE_MFP) 249 250 C2S(NL80211_ATTR_STA_FLAGS2) 251 252 C2S(NL80211_ATTR_CONTROL_PORT) 253 254 C2S(NL80211_ATTR_TESTDATA) 255 256 C2S(NL80211_ATTR_PRIVACY) 257 258 C2S(NL80211_ATTR_DISCONNECTED_BY_AP) 259 C2S(NL80211_ATTR_STATUS_CODE) 260 261 C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE) 262 C2S(NL80211_ATTR_CIPHER_SUITE_GROUP) 263 C2S(NL80211_ATTR_WPA_VERSIONS) 264 C2S(NL80211_ATTR_AKM_SUITES) 265 266 C2S(NL80211_ATTR_REQ_IE) 267 C2S(NL80211_ATTR_RESP_IE) 268 269 C2S(NL80211_ATTR_PREV_BSSID) 270 271 C2S(NL80211_ATTR_KEY) 272 C2S(NL80211_ATTR_KEYS) 273 274 C2S(NL80211_ATTR_PID) 275 276 C2S(NL80211_ATTR_4ADDR) 277 278 C2S(NL80211_ATTR_SURVEY_INFO) 279 280 C2S(NL80211_ATTR_PMKID) 281 C2S(NL80211_ATTR_MAX_NUM_PMKIDS) 282 283 C2S(NL80211_ATTR_DURATION) 284 285 C2S(NL80211_ATTR_COOKIE) 286 287 C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS) 288 289 C2S(NL80211_ATTR_TX_RATES) 290 291 C2S(NL80211_ATTR_FRAME_MATCH) 292 293 C2S(NL80211_ATTR_ACK) 294 295 C2S(NL80211_ATTR_PS_STATE) 296 297 C2S(NL80211_ATTR_CQM) 298 299 C2S(NL80211_ATTR_LOCAL_STATE_CHANGE) 300 301 C2S(NL80211_ATTR_AP_ISOLATE) 302 303 C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING) 304 C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL) 305 306 C2S(NL80211_ATTR_TX_FRAME_TYPES) 307 C2S(NL80211_ATTR_RX_FRAME_TYPES) 308 C2S(NL80211_ATTR_FRAME_TYPE) 309 310 C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE) 311 C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT) 312 313 C2S(NL80211_ATTR_SUPPORT_IBSS_RSN) 314 315 C2S(NL80211_ATTR_WIPHY_ANTENNA_TX) 316 C2S(NL80211_ATTR_WIPHY_ANTENNA_RX) 317 318 C2S(NL80211_ATTR_MCAST_RATE) 319 320 C2S(NL80211_ATTR_OFFCHANNEL_TX_OK) 321 322 C2S(NL80211_ATTR_BSS_HT_OPMODE) 323 324 C2S(NL80211_ATTR_KEY_DEFAULT_TYPES) 325 326 C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION) 327 328 C2S(NL80211_ATTR_MESH_SETUP) 329 330 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX) 331 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX) 332 333 C2S(NL80211_ATTR_SUPPORT_MESH_AUTH) 334 C2S(NL80211_ATTR_STA_PLINK_STATE) 335 336 C2S(NL80211_ATTR_WOWLAN_TRIGGERS) 337 C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED) 338 339 C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL) 340 341 C2S(NL80211_ATTR_INTERFACE_COMBINATIONS) 342 C2S(NL80211_ATTR_SOFTWARE_IFTYPES) 343 344 C2S(NL80211_ATTR_REKEY_DATA) 345 346 C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS) 347 C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN) 348 349 C2S(NL80211_ATTR_SCAN_SUPP_RATES) 350 351 C2S(NL80211_ATTR_HIDDEN_SSID) 352 353 C2S(NL80211_ATTR_IE_PROBE_RESP) 354 C2S(NL80211_ATTR_IE_ASSOC_RESP) 355 356 C2S(NL80211_ATTR_STA_WME) 357 C2S(NL80211_ATTR_SUPPORT_AP_UAPSD) 358 359 C2S(NL80211_ATTR_ROAM_SUPPORT) 360 361 C2S(NL80211_ATTR_SCHED_SCAN_MATCH) 362 C2S(NL80211_ATTR_MAX_MATCH_SETS) 363 364 C2S(NL80211_ATTR_PMKSA_CANDIDATE) 365 366 C2S(NL80211_ATTR_TX_NO_CCK_RATE) 367 368 C2S(NL80211_ATTR_TDLS_ACTION) 369 C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN) 370 C2S(NL80211_ATTR_TDLS_OPERATION) 371 C2S(NL80211_ATTR_TDLS_SUPPORT) 372 C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP) 373 374 C2S(NL80211_ATTR_DEVICE_AP_SME) 375 376 C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK) 377 378 C2S(NL80211_ATTR_FEATURE_FLAGS) 379 380 C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD) 381 382 C2S(NL80211_ATTR_PROBE_RESP) 383 384 C2S(NL80211_ATTR_DFS_REGION) 385 386 C2S(NL80211_ATTR_DISABLE_HT) 387 C2S(NL80211_ATTR_HT_CAPABILITY_MASK) 388 389 C2S(NL80211_ATTR_NOACK_MAP) 390 391 C2S(NL80211_ATTR_INACTIVITY_TIMEOUT) 392 393 C2S(NL80211_ATTR_RX_SIGNAL_DBM) 394 395 C2S(NL80211_ATTR_BG_SCAN_PERIOD) 396 397 C2S(NL80211_ATTR_WDEV) 398 399 C2S(NL80211_ATTR_USER_REG_HINT_TYPE) 400 401 C2S(NL80211_ATTR_CONN_FAILED_REASON) 402 403 C2S(NL80211_ATTR_SAE_DATA) 404 405 C2S(NL80211_ATTR_VHT_CAPABILITY) 406 407 C2S(NL80211_ATTR_SCAN_FLAGS) 408 409 C2S(NL80211_ATTR_CHANNEL_WIDTH) 410 C2S(NL80211_ATTR_CENTER_FREQ1) 411 C2S(NL80211_ATTR_CENTER_FREQ2) 412 413 C2S(NL80211_ATTR_P2P_CTWINDOW) 414 C2S(NL80211_ATTR_P2P_OPPPS) 415 416 C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE) 417 418 C2S(NL80211_ATTR_ACL_POLICY) 419 420 C2S(NL80211_ATTR_MAC_ADDRS) 421 422 C2S(NL80211_ATTR_MAC_ACL_MAX) 423 424 C2S(NL80211_ATTR_RADAR_EVENT) 425 426 C2S(NL80211_ATTR_EXT_CAPA) 427 C2S(NL80211_ATTR_EXT_CAPA_MASK) 428 429 C2S(NL80211_ATTR_STA_CAPABILITY) 430 C2S(NL80211_ATTR_STA_EXT_CAPABILITY) 431 432 C2S(NL80211_ATTR_PROTOCOL_FEATURES) 433 C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP) 434 435 C2S(NL80211_ATTR_DISABLE_VHT) 436 C2S(NL80211_ATTR_VHT_CAPABILITY_MASK) 437 438 C2S(NL80211_ATTR_MDID) 439 C2S(NL80211_ATTR_IE_RIC) 440 441 C2S(NL80211_ATTR_CRIT_PROT_ID) 442 C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION) 443 444 C2S(NL80211_ATTR_PEER_AID) 445 446 C2S(NL80211_ATTR_COALESCE_RULE) 447 448 C2S(NL80211_ATTR_CH_SWITCH_COUNT) 449 C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX) 450 C2S(NL80211_ATTR_CSA_IES) 451 C2S(NL80211_ATTR_CSA_C_OFF_BEACON) 452 C2S(NL80211_ATTR_CSA_C_OFF_PRESP) 453 454 C2S(NL80211_ATTR_RXMGMT_FLAGS) 455 456 C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS) 457 458 C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES) 459 460 C2S(NL80211_ATTR_HANDLE_DFS) 461 462 C2S(NL80211_ATTR_SUPPORT_5_MHZ) 463 C2S(NL80211_ATTR_SUPPORT_10_MHZ) 464 465 C2S(NL80211_ATTR_OPMODE_NOTIF) 466 467 C2S(NL80211_ATTR_VENDOR_ID) 468 C2S(NL80211_ATTR_VENDOR_SUBCMD) 469 C2S(NL80211_ATTR_VENDOR_DATA) 470 C2S(NL80211_ATTR_VENDOR_EVENTS) 471 472 C2S(NL80211_ATTR_QOS_MAP) 473 default: 474 return "NL80211_ATTR_UNKNOWN"; 475 } 476 } 477 478 void WifiEvent::log() { 479 parse(); 480 481 byte *data = (byte *)genlmsg_attrdata(mHeader, 0); 482 int len = genlmsg_attrlen(mHeader, 0); 483 ALOGD("cmd = %s, len = %d", get_cmdString(), len); 484 ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd()); 485 486 for (int i = 0; i < len; i += 16) { 487 char line[81]; 488 int linelen = min(16, len - i); 489 int offset = 0; 490 appendFmt(line, offset, "%02x", data[i]); 491 for (int j = 1; j < linelen; j++) { 492 appendFmt(line, offset, " %02x", data[i+j]); 493 } 494 495 for (int j = linelen; j < 16; j++) { 496 appendFmt(line, offset, " "); 497 } 498 499 line[23] = '-'; 500 501 appendFmt(line, offset, " "); 502 503 for (int j = 0; j < linelen; j++) { 504 if (isprint(data[i+j])) { 505 appendFmt(line, offset, "%c", data[i+j]); 506 } else { 507 appendFmt(line, offset, "-"); 508 } 509 } 510 511 ALOGD("%s", line); 512 } 513 514 for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) { 515 if (mAttributes[i] != NULL) { 516 ALOGD("found attribute %s", attributeToString(i)); 517 } 518 } 519 520 ALOGD("-- End of message --"); 521 } 522 523 const char *WifiEvent::get_cmdString() { 524 return cmdToString(get_cmd()); 525 } 526 527 528 int WifiEvent::parse() { 529 if (mHeader != NULL) { 530 return WIFI_SUCCESS; 531 } 532 mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg)); 533 int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0), 534 genlmsg_attrlen(mHeader, 0), NULL); 535 536 // ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len); 537 return result; 538 } 539 540 int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) { 541 mMsg = nlmsg_alloc(); 542 if (mMsg != NULL) { 543 genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family, 544 hdrlen, flags, cmd, /* version = */ 0); 545 return WIFI_SUCCESS; 546 } else { 547 return WIFI_ERROR_OUT_OF_MEMORY; 548 } 549 } 550 551 int WifiRequest::create(uint32_t id, int subcmd) { 552 int res = create(NL80211_CMD_VENDOR); 553 if (res < 0) { 554 return res; 555 } 556 557 res = put_u32(NL80211_ATTR_VENDOR_ID, id); 558 if (res < 0) { 559 return res; 560 } 561 562 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd); 563 if (res < 0) { 564 return res; 565 } 566 567 if (mIface != -1) { 568 res = set_iface_id(mIface); 569 } 570 571 return res; 572 } 573 574 575 static int no_seq_check(struct nl_msg *msg, void *arg) 576 { 577 return NL_OK; 578 } 579 580 int WifiCommand::requestResponse() { 581 int err = create(); /* create the message */ 582 if (err < 0) { 583 return err; 584 } 585 586 return requestResponse(mMsg); 587 } 588 589 int WifiCommand::requestResponse(WifiRequest& request) { 590 int err = 0; 591 592 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); 593 if (!cb) 594 goto out; 595 596 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */ 597 if (err < 0) 598 goto out; 599 600 err = 1; 601 602 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); 603 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); 604 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); 605 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); 606 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this); 607 608 while (err > 0) { /* wait for reply */ 609 int res = nl_recvmsgs(mInfo->cmd_sock, cb); 610 if (res) { 611 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res); 612 } 613 } 614 out: 615 nl_cb_put(cb); 616 return err; 617 } 618 619 int WifiCommand::requestEvent(int cmd) { 620 621 ALOGD("requesting event %d", cmd); 622 623 int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this); 624 if (res < 0) { 625 return res; 626 } 627 628 res = create(); /* create the message */ 629 if (res < 0) 630 goto out; 631 632 ALOGD("waiting for response %d", cmd); 633 634 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ 635 if (res < 0) 636 goto out; 637 638 ALOGD("waiting for event %d", cmd); 639 res = mCondition.wait(); 640 if (res < 0) 641 goto out; 642 643 out: 644 wifi_unregister_handler(wifiHandle(), cmd); 645 return res; 646 } 647 648 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { 649 650 int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this); 651 if (res < 0) { 652 return res; 653 } 654 655 res = create(); /* create the message */ 656 if (res < 0) 657 goto out; 658 659 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ 660 if (res < 0) 661 goto out; 662 663 res = mCondition.wait(); 664 if (res < 0) 665 goto out; 666 667 out: 668 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); 669 return res; 670 } 671 672 /* Event handlers */ 673 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) { 674 // ALOGD("response_handler called"); 675 WifiCommand *cmd = (WifiCommand *)arg; 676 WifiEvent reply(msg); 677 int res = reply.parse(); 678 if (res < 0) { 679 ALOGE("Failed to parse reply message = %d", res); 680 return NL_SKIP; 681 } else { 682 // reply.log(); 683 return cmd->handleResponse(reply); 684 } 685 } 686 687 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) { 688 WifiCommand *cmd = (WifiCommand *)arg; 689 WifiEvent event(msg); 690 int res = event.parse(); 691 if (res < 0) { 692 ALOGE("Failed to parse event = %d", res); 693 res = NL_SKIP; 694 } else { 695 res = cmd->handleEvent(event); 696 } 697 698 cmd->mCondition.signal(); 699 return res; 700 } 701 702 /* Other event handlers */ 703 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) { 704 // ALOGD("valid_handler called"); 705 int *err = (int *)arg; 706 *err = 0; 707 return NL_SKIP; 708 } 709 710 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) { 711 // ALOGD("ack_handler called"); 712 int *err = (int *)arg; 713 *err = 0; 714 return NL_STOP; 715 } 716 717 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) { 718 // ALOGD("finish_handler called"); 719 int *ret = (int *)arg; 720 *ret = 0; 721 return NL_SKIP; 722 } 723 724 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { 725 int *ret = (int *)arg; 726 *ret = err->error; 727 728 // ALOGD("error_handler received : %d", err->error); 729 return NL_SKIP; 730 } 731