1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Portions copyright (C) 2017 Broadcom Limited 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include <stdint.h> 20 #include <fcntl.h> 21 #include <sys/socket.h> 22 #include <netlink/genl/genl.h> 23 #include <netlink/genl/family.h> 24 #include <netlink/genl/ctrl.h> 25 #include <linux/rtnetlink.h> 26 #include <netpacket/packet.h> 27 #include <linux/filter.h> 28 #include <linux/errqueue.h> 29 #include <errno.h> 30 31 #include <linux/pkt_sched.h> 32 #include <netlink/object-api.h> 33 #include <netlink/netlink.h> 34 #include <netlink/socket.h> 35 #include <netlink-private/object-api.h> 36 #include <netlink-private/types.h> 37 #include <unistd.h> 38 #include <cutils/properties.h> 39 40 41 #include "nl80211_copy.h" 42 #include "sync.h" 43 44 #define LOG_TAG "WifiHAL" 45 46 #include <log/log.h> 47 48 #include "wifi_hal.h" 49 #include "common.h" 50 #include "cpp_bindings.h" 51 #include <sys/stat.h> 52 #include "brcm_version.h" 53 #define WIFI_HAL_EVENT_SOCK_PORT 645 54 55 #define ARRAYSIZE(a) (u8)(sizeof(a) / sizeof(a[0])) 56 typedef enum { 57 LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START, 58 LOGGER_TRIGGER_MEM_DUMP, 59 LOGGER_GET_MEM_DUMP, 60 LOGGER_GET_VER, 61 LOGGER_GET_RING_STATUS, 62 LOGGER_GET_RING_DATA, 63 LOGGER_GET_FEATURE, 64 LOGGER_RESET_LOGGING, 65 LOGGER_TRIGGER_DRIVER_MEM_DUMP, 66 LOGGER_GET_DRIVER_MEM_DUMP, 67 LOGGER_START_PKT_FATE_MONITORING, 68 LOGGER_GET_TX_PKT_FATES, 69 LOGGER_GET_RX_PKT_FATES, 70 LOGGER_GET_WAKE_REASON_STATS, 71 LOGGER_DEBUG_GET_DUMP, 72 LOGGER_FILE_DUMP_DONE_IND, 73 LOGGER_SET_HAL_START, 74 LOGGER_HAL_STOP, 75 LOGGER_SET_HAL_PID 76 } DEBUG_SUB_COMMAND; 77 78 #define MAX_NV_FILE 4 79 #define MAX_SKU_NAME_LEN 5 80 #define OTA_PATH "/data/vendor/firmware/wifi/" 81 #define OTA_CLM_FILE "bcmdhd_clm.blob" 82 #define OTA_NVRAM_FILE "bcmdhd.cal" 83 #define HW_DEV_PROP "ro.revision" 84 #define HW_SKU_PROP "ro.boot.hardware.sku" 85 86 typedef enum { 87 NVRAM, 88 CLM_BLOB 89 } OTA_TYPE; 90 91 char ota_nvram_ext[10]; 92 typedef struct ota_info_buf { 93 u32 ota_clm_len; 94 const void *ota_clm_buf[1]; 95 u32 ota_nvram_len; 96 const void *ota_nvram_buf[1]; 97 } ota_info_buf_t; 98 u32 applied_ota_version = 0; 99 100 typedef enum { 101 LOGGER_ATTRIBUTE_INVALID = 0, 102 LOGGER_ATTRIBUTE_DRIVER_VER = 1, 103 LOGGER_ATTRIBUTE_FW_VER = 2, 104 LOGGER_ATTRIBUTE_RING_ID = 3, 105 LOGGER_ATTRIBUTE_RING_NAME = 4, 106 LOGGER_ATTRIBUTE_RING_FLAGS = 5, 107 LOGGER_ATTRIBUTE_LOG_LEVEL = 6, 108 LOGGER_ATTRIBUTE_LOG_TIME_INTVAL = 7, 109 LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE = 8, 110 LOGGER_ATTRIBUTE_FW_DUMP_LEN = 9, 111 LOGGER_ATTRIBUTE_FW_DUMP_DATA = 10, 112 LOGGER_ATTRIBUTE_FW_ERR_CODE = 11, 113 LOGGER_ATTRIBUTE_RING_DATA = 12, 114 LOGGER_ATTRIBUTE_RING_STATUS = 13, 115 LOGGER_ATTRIBUTE_RING_NUM = 14, 116 LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN = 15, 117 LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA = 16, 118 LOGGER_ATTRIBUTE_PKT_FATE_NUM = 17, 119 LOGGER_ATTRIBUTE_PKT_FATE_DATA = 18, 120 LOGGER_ATTRIBUTE_HANG_REASON = 19, 121 /* Add new attributes just above this */ 122 LOGGER_ATTRIBUTE_MAX 123 } LOGGER_ATTRIBUTE; 124 125 typedef enum { 126 DEBUG_OFF = 0, 127 DEBUG_NORMAL, 128 DEBUG_VERBOSE, 129 DEBUG_VERY, 130 DEBUG_VERY_VERY, 131 } LOGGER_LEVEL; 132 133 typedef enum { 134 GET_FW_VER, 135 GET_DRV_VER, 136 GET_RING_DATA, 137 GET_RING_STATUS, 138 GET_FEATURE, 139 START_RING_LOG, 140 } GetCmdType; 141 142 typedef enum { 143 PACKET_MONITOR_START, 144 TX_PACKET_FATE, 145 RX_PACKET_FATE, 146 } PktFateReqType; 147 148 enum wake_stat_attributes { 149 WAKE_STAT_ATTRIBUTE_INVALID, 150 WAKE_STAT_ATTRIBUTE_TOTAL, 151 WAKE_STAT_ATTRIBUTE_WAKE, 152 WAKE_STAT_ATTRIBUTE_COUNT, 153 WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED, 154 WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW, 155 WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE, 156 WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT, 157 WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED, 158 WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE, 159 WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT, 160 WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT, 161 WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT, 162 WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT, 163 WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT, 164 WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA, 165 WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA, 166 WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS, 167 WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT, 168 WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT, 169 WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT, 170 WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO, 171 WAKE_STAT_ATTRIBUTE_MAX 172 }; 173 174 typedef enum { 175 SET_HAL_START_ATTRIBUTE_DEINIT = 0x0001, 176 SET_HAL_START_ATTRIBUTE_PRE_INIT = 0x0002, 177 SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003 178 } SET_HAL_START_ATTRIBUTE; 179 180 typedef enum { 181 OTA_DOWNLOAD_CLM_LENGTH_ATTR = 0x0001, 182 OTA_DOWNLOAD_CLM_ATTR = 0x0002, 183 OTA_DOWNLOAD_NVRAM_LENGTH_ATTR = 0x0003, 184 OTA_DOWNLOAD_NVRAM_ATTR = 0x0004, 185 OTA_SET_FORCE_REG_ON = 0x0005, 186 OTA_CUR_NVRAM_EXT_ATTR = 0x0006, 187 } OTA_DOWNLOAD_ATTRIBUTE; 188 189 #define HAL_START_REQUEST_ID 2 190 #define HAL_RESTART_ID 3 191 #define FILE_NAME_LEN 256 192 /////////////////////////////////////////////////////////////////////////////// 193 class DebugCommand : public WifiCommand 194 { 195 char *mBuff; 196 int *mBuffSize; 197 u32 *mNumRings; 198 wifi_ring_buffer_status *mStatus; 199 unsigned int *mSupport; 200 u32 mVerboseLevel; 201 u32 mFlags; 202 u32 mMaxIntervalSec; 203 u32 mMinDataSize; 204 char *mRingName; 205 GetCmdType mType; 206 207 public: 208 209 // constructor for get version 210 DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size, 211 GetCmdType cmdType) 212 : WifiCommand("DebugCommand", iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType 213 (cmdType) 214 { 215 mNumRings = NULL; 216 mStatus = NULL; 217 mSupport = NULL; 218 mVerboseLevel = 0; 219 mFlags = 0; 220 mMaxIntervalSec = 0; 221 mMinDataSize = 0; 222 mRingName = NULL; 223 memset(mBuff, 0, *mBuffSize); 224 } 225 226 // constructor for ring data 227 DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType) 228 : WifiCommand("DebugCommand", iface, 0), mRingName(ring_name), mType(cmdType) 229 { 230 mBuff = NULL; 231 mBuffSize = NULL; 232 mNumRings = NULL; 233 mStatus = NULL; 234 mSupport = NULL; 235 mVerboseLevel = 0; 236 mFlags = 0; 237 mMaxIntervalSec = 0; 238 mMinDataSize = 0; 239 } 240 241 // constructor for ring status 242 DebugCommand(wifi_interface_handle iface, u32 *num_rings, 243 wifi_ring_buffer_status *status, GetCmdType cmdType) 244 : WifiCommand("DebugCommand", iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType) 245 { 246 mBuff = NULL; 247 mBuffSize = NULL; 248 mSupport = NULL; 249 mVerboseLevel = 0; 250 mFlags = 0; 251 mMaxIntervalSec = 0; 252 mMinDataSize = 0; 253 mRingName = NULL; 254 memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings)); 255 } 256 257 // constructor for feature set 258 DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType) 259 : WifiCommand("DebugCommand", iface, 0), mSupport(support), mType(cmdType) 260 { 261 mBuff = NULL; 262 mBuffSize = NULL; 263 mNumRings = NULL; 264 mStatus = NULL; 265 mVerboseLevel = 0; 266 mFlags = 0; 267 mMaxIntervalSec = 0; 268 mMinDataSize = 0; 269 mRingName = NULL; 270 } 271 272 // constructor for ring params 273 DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags, 274 u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType) 275 : WifiCommand("DebugCommand", iface, 0), mVerboseLevel(verbose_level), mFlags(flags), 276 mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size), 277 mRingName(ring_name), mType(cmdType) 278 { 279 mBuff = NULL; 280 mBuffSize = NULL; 281 mNumRings = NULL; 282 mStatus = NULL; 283 mSupport = NULL; 284 } 285 286 int createRingRequest(WifiRequest& request) { 287 int result = request.create(GOOGLE_OUI, LOGGER_START_LOGGING); 288 if (result != WIFI_SUCCESS) { 289 ALOGE("Failed to create start ring logger request; result = %d", result); 290 return result; 291 } 292 293 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 294 295 result = request.put_u32(LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel); 296 if (result != WIFI_SUCCESS) { 297 ALOGE("Failed to put log level; result = %d", result); 298 return result; 299 } 300 result = request.put_u32(LOGGER_ATTRIBUTE_RING_FLAGS, mFlags); 301 if (result != WIFI_SUCCESS) { 302 ALOGE("Failed to put ring flags; result = %d", result); 303 return result; 304 } 305 result = request.put_u32(LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec); 306 if (result != WIFI_SUCCESS) { 307 ALOGE("Failed to put log time interval; result = %d", result); 308 return result; 309 } 310 result = request.put_u32(LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize); 311 if (result != WIFI_SUCCESS) { 312 ALOGE("Failed to put min data size; result = %d", result); 313 return result; 314 } 315 result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName); 316 if (result != WIFI_SUCCESS) { 317 ALOGE("Failed to put ringbuffer name; result = %d", result); 318 return result; 319 } 320 request.attr_end(data); 321 322 return WIFI_SUCCESS; 323 } 324 325 int createRequest(WifiRequest &request) { 326 int result; 327 328 switch (mType) { 329 case GET_FW_VER: 330 { 331 result = request.create(GOOGLE_OUI, LOGGER_GET_VER); 332 if (result != WIFI_SUCCESS) { 333 ALOGE("Failed to create get fw version request; result = %d", result); 334 return result; 335 } 336 337 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 338 339 // Driver expecting only attribute type, passing mbuff as data with 340 // length 0 to avoid undefined state 341 result = request.put(LOGGER_ATTRIBUTE_FW_VER, mBuff, 0); 342 if (result != WIFI_SUCCESS) { 343 ALOGE("Failed to put get fw version request; result = %d", result); 344 return result; 345 } 346 request.attr_end(data); 347 break; 348 } 349 350 case GET_DRV_VER: 351 { 352 result = request.create(GOOGLE_OUI, LOGGER_GET_VER); 353 if (result != WIFI_SUCCESS) { 354 ALOGE("Failed to create get drv version request; result = %d", result); 355 return result; 356 } 357 358 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 359 360 // Driver expecting only attribute type, passing mbuff as data with 361 // length 0 to avoid undefined state 362 result = request.put(LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0); 363 364 if (result != WIFI_SUCCESS) { 365 ALOGE("Failed to put get drv version request; result = %d", result); 366 return result; 367 } 368 request.attr_end(data); 369 break; 370 } 371 372 case GET_RING_DATA: 373 { 374 result = request.create(GOOGLE_OUI, LOGGER_GET_RING_DATA); 375 if (result != WIFI_SUCCESS) { 376 ALOGE("Failed to create get ring data request; result = %d", result); 377 return result; 378 } 379 380 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 381 result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName); 382 if (result != WIFI_SUCCESS) { 383 ALOGE("Failed to put ring data request; result = %d", result); 384 return result; 385 } 386 request.attr_end(data); 387 break; 388 } 389 390 case GET_RING_STATUS: 391 { 392 result = request.create(GOOGLE_OUI, LOGGER_GET_RING_STATUS); 393 if (result != WIFI_SUCCESS) { 394 ALOGE("Failed to create get ring status request; result = %d", result); 395 return result; 396 } 397 break; 398 } 399 400 case GET_FEATURE: 401 { 402 result = request.create(GOOGLE_OUI, LOGGER_GET_FEATURE); 403 if (result != WIFI_SUCCESS) { 404 ALOGE("Failed to create get feature request; result = %d", result); 405 return result; 406 } 407 break; 408 } 409 410 case START_RING_LOG: 411 result = createRingRequest(request); 412 break; 413 414 default: 415 ALOGE("Unknown Debug command"); 416 result = WIFI_ERROR_UNKNOWN; 417 } 418 return result; 419 } 420 421 int start() { 422 // ALOGD("Start debug command"); 423 WifiRequest request(familyId(), ifaceId()); 424 int result = createRequest(request); 425 if (result != WIFI_SUCCESS) { 426 ALOGE("Failed to create debug request; result = %d", result); 427 return result; 428 } 429 430 result = requestResponse(request); 431 if (result != WIFI_SUCCESS) { 432 ALOGE("Failed to register debug response; result = %d", result); 433 } 434 return result; 435 } 436 437 virtual int handleResponse(WifiEvent& reply) { 438 ALOGD("In DebugCommand::handleResponse"); 439 440 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 441 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 442 return NL_SKIP; 443 } 444 445 switch (mType) { 446 case GET_DRV_VER: 447 case GET_FW_VER: 448 { 449 void *data = reply.get_vendor_data(); 450 int len = reply.get_vendor_data_len(); 451 452 ALOGD("len = %d, expected len = %d", len, *mBuffSize); 453 memcpy(mBuff, data, min(len, *mBuffSize)); 454 if (*mBuffSize < len) 455 return NL_SKIP; 456 *mBuffSize = len; 457 break; 458 } 459 460 case START_RING_LOG: 461 case GET_RING_DATA: 462 break; 463 464 case GET_RING_STATUS: 465 { 466 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 467 int len = reply.get_vendor_data_len(); 468 wifi_ring_buffer_status *status(mStatus); 469 470 if (vendor_data == NULL || len == 0) { 471 ALOGE("No Debug data found"); 472 return NL_SKIP; 473 } 474 475 nl_iterator it(vendor_data); 476 if (it.get_type() == LOGGER_ATTRIBUTE_RING_NUM) { 477 unsigned int num_rings = it.get_u32(); 478 if (*mNumRings < num_rings) { 479 ALOGE("Not enough status buffers provided, available: %d required: %d", 480 *mNumRings, num_rings); 481 } else { 482 *mNumRings = num_rings; 483 } 484 } else { 485 ALOGE("Unknown attribute: %d expecting %d", 486 it.get_type(), LOGGER_ATTRIBUTE_RING_NUM); 487 return NL_SKIP; 488 } 489 490 it.next(); 491 for (unsigned int i = 0; it.has_next() && i < *mNumRings; it.next()) { 492 if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) { 493 memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status)); 494 i++; 495 status++; 496 } else { 497 ALOGW("Ignoring invalid attribute type = %d, size = %d", 498 it.get_type(), it.get_len()); 499 } 500 } 501 break; 502 } 503 504 case GET_FEATURE: 505 { 506 void *data = reply.get_vendor_data(); 507 int len = reply.get_vendor_data_len(); 508 509 ALOGD("len = %d, expected len = %lu", len, sizeof(unsigned int)); 510 memcpy(mSupport, data, sizeof(unsigned int)); 511 break; 512 } 513 514 default: 515 ALOGW("Unknown Debug command"); 516 } 517 return NL_OK; 518 } 519 520 virtual int handleEvent(WifiEvent& event) { 521 /* NO events! */ 522 return NL_SKIP; 523 } 524 }; 525 526 /* API to collect a firmware version string */ 527 wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer, 528 int buffer_size) 529 { 530 if (buffer && (buffer_size > 0)) { 531 DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER); 532 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 533 wifi_error result = (wifi_error)cmd->start(); 534 cmd->releaseRef(); 535 return result; 536 } else { 537 ALOGE("FW version buffer NULL"); 538 return WIFI_ERROR_INVALID_ARGS; 539 } 540 } 541 542 /* API to collect a driver version string */ 543 wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size) 544 { 545 if (buffer && (buffer_size > 0)) { 546 DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER); 547 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 548 wifi_error result = (wifi_error)cmd->start(); 549 cmd->releaseRef(); 550 return result; 551 } else { 552 ALOGE("Driver version buffer NULL"); 553 return WIFI_ERROR_INVALID_ARGS; 554 } 555 } 556 557 /* API to collect driver records */ 558 wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name) 559 { 560 DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA); 561 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 562 wifi_error result = (wifi_error)cmd->start(); 563 cmd->releaseRef(); 564 return result; 565 } 566 567 /* API to get the status of all ring buffers supported by driver */ 568 wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, 569 u32 *num_rings, wifi_ring_buffer_status *status) 570 { 571 if (status && num_rings) { 572 DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS); 573 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 574 wifi_error result = (wifi_error)cmd->start(); 575 cmd->releaseRef(); 576 return result; 577 } else { 578 ALOGE("Ring status buffer NULL"); 579 return WIFI_ERROR_INVALID_ARGS; 580 } 581 } 582 583 /* API to get supportable feature */ 584 wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface, 585 unsigned int *support) 586 { 587 if (support) { 588 DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE); 589 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 590 wifi_error result = (wifi_error)cmd->start(); 591 cmd->releaseRef(); 592 return result; 593 } else { 594 ALOGE("Get support buffer NULL"); 595 return WIFI_ERROR_INVALID_ARGS; 596 } 597 } 598 599 wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, 600 u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name) 601 { 602 if (ring_name) { 603 DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec, 604 min_data_size, ring_name, START_RING_LOG); 605 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 606 wifi_error result = (wifi_error)cmd->start(); 607 cmd->releaseRef(); 608 return result; 609 } else { 610 ALOGE("Ring name NULL"); 611 return WIFI_ERROR_INVALID_ARGS; 612 } 613 } 614 615 616 /////////////////////////////////////////////////////////////////////////////// 617 class SetLogHandler : public WifiCommand 618 { 619 wifi_ring_buffer_data_handler mHandler; 620 621 public: 622 SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler) 623 : WifiCommand("SetLogHandler", iface, id), mHandler(handler) 624 { } 625 626 int start() { 627 ALOGV("Register loghandler"); 628 int result; 629 uint32_t event_sock_pid = getpid() + (WIFI_HAL_EVENT_SOCK_PORT << 22); 630 registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); 631 632 WifiRequest request(familyId(), ifaceId()); 633 634 /* set hal event socket port to driver */ 635 result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_PID); 636 if (result != WIFI_SUCCESS) { 637 ALOGV("Failed to set Hal preInit; result = %d", result); 638 return result; 639 } 640 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 641 result = request.put_u32(SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID, event_sock_pid); 642 if (result != WIFI_SUCCESS) { 643 ALOGV("Hal preInit Failed to put pic = %d", result); 644 return result; 645 } 646 647 if (result != WIFI_SUCCESS) { 648 ALOGV("Hal preInit Failed to put pid= %d", result); 649 return result; 650 } 651 652 request.attr_end(data); 653 654 result = requestResponse(request); 655 if (result != WIFI_SUCCESS) { 656 ALOGE("Failed to register set Hal preInit; result = %d", result); 657 return result; 658 } 659 return result; 660 } 661 662 virtual int cancel() { 663 /* Send a command to driver to stop generating logging events */ 664 ALOGV("Clear loghandler"); 665 666 /* unregister event handler */ 667 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); 668 wifi_unregister_cmd(wifiHandle(), id()); 669 670 WifiRequest request(familyId(), ifaceId()); 671 int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING); 672 if (result != WIFI_SUCCESS) { 673 ALOGE("failed to create reset request; result = %d", result); 674 return result; 675 } 676 677 result = requestResponse(request); 678 if (result != WIFI_SUCCESS) { 679 ALOGE("failed to request reset; result = %d", result); 680 return result; 681 } 682 683 ALOGD("Success to clear loghandler"); 684 return WIFI_SUCCESS; 685 } 686 687 virtual int handleEvent(WifiEvent& event) { 688 char *buffer = NULL; 689 int buffer_size = 0; 690 691 // ALOGD("In SetLogHandler::handleEvent"); 692 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 693 int len = event.get_vendor_data_len(); 694 int event_id = event.get_vendor_subcmd(); 695 // ALOGI("Got Logger event: %d", event_id); 696 697 if (vendor_data == NULL || len == 0) { 698 ALOGE("No Debug data found"); 699 return NL_SKIP; 700 } 701 702 if(event_id == GOOGLE_DEBUG_RING_EVENT) { 703 wifi_ring_buffer_status status; 704 memset(&status, 0, sizeof(status)); 705 706 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 707 if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) { 708 memcpy(&status, it.get_data(), sizeof(status)); 709 } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) { 710 buffer_size = it.get_len(); 711 buffer = (char *)it.get_data(); 712 } else { 713 ALOGW("Ignoring invalid attribute type = %d, size = %d", 714 it.get_type(), it.get_len()); 715 } 716 } 717 718 // ALOGI("Retrieved Debug data"); 719 if (mHandler.on_ring_buffer_data) { 720 /* Skip msg header. Retrieved log */ 721 char *pBuff; 722 wifi_ring_buffer_entry *buffer_entry = 723 (wifi_ring_buffer_entry *) buffer; 724 pBuff = (char *) (buffer_entry + 1); 725 (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff, 726 buffer_entry->entry_size, &status); 727 } 728 } else { 729 ALOGE("Unknown Event"); 730 return NL_SKIP; 731 } 732 return NL_OK; 733 } 734 }; 735 736 wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface, 737 wifi_ring_buffer_data_handler handler) 738 { 739 wifi_handle handle = getWifiHandle(iface); 740 ALOGV("Loghandler start, handle = %p", handle); 741 742 SetLogHandler *cmd = new SetLogHandler(iface, id, handler); 743 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 744 wifi_error result = wifi_register_cmd(handle, id, cmd); 745 if (result != WIFI_SUCCESS) { 746 cmd->releaseRef(); 747 return result; 748 } 749 result = (wifi_error)cmd->start(); 750 if (result != WIFI_SUCCESS) { 751 wifi_unregister_cmd(handle, id); 752 cmd->releaseRef(); 753 return result; 754 } 755 return result; 756 } 757 758 wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface) 759 { 760 wifi_handle handle = getWifiHandle(iface); 761 ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle); 762 763 if (id == -1) { 764 wifi_ring_buffer_data_handler handler; 765 memset(&handler, 0, sizeof(handler)); 766 767 SetLogHandler *cmd = new SetLogHandler(iface, id, handler); 768 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 769 cmd->cancel(); 770 cmd->releaseRef(); 771 return WIFI_SUCCESS; 772 } 773 774 return wifi_get_cancel_cmd(id, iface); 775 } 776 777 /////////////////////////////////////////////////////////////////////////////// 778 class SetAlertHandler : public WifiCommand 779 { 780 wifi_alert_handler mHandler; 781 int mBuffSize; 782 char *mBuff; 783 int mErrCode; 784 785 public: 786 SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler) 787 : WifiCommand("SetAlertHandler", iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL), 788 mErrCode(0) 789 { } 790 791 int start() { 792 ALOGV("Start Alerting"); 793 registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT); 794 return WIFI_SUCCESS; 795 } 796 797 virtual int cancel() { 798 ALOGV("Clear alerthandler"); 799 800 /* unregister alert handler */ 801 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT); 802 wifi_unregister_cmd(wifiHandle(), id()); 803 ALOGD("Success to clear alerthandler"); 804 return WIFI_SUCCESS; 805 } 806 807 virtual int handleResponse(WifiEvent& reply) { 808 ALOGD("In SetAlertHandler::handleResponse"); 809 810 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 811 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 812 return NL_SKIP; 813 } 814 815 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 816 int len = reply.get_vendor_data_len(); 817 818 ALOGD("len = %d", len); 819 if (vendor_data == NULL || len == 0) { 820 ALOGE("no vendor data in memory dump response; ignoring it"); 821 return NL_SKIP; 822 } 823 824 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 825 if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) { 826 ALOGI("Initiating alert callback"); 827 if (mHandler.on_alert) { 828 (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode); 829 } 830 if (mBuff) { 831 free(mBuff); 832 mBuff = NULL; 833 } 834 } 835 } 836 return NL_OK; 837 } 838 839 virtual int handleEvent(WifiEvent& event) { 840 char *buffer = NULL; 841 int buffer_size = 0; 842 bool is_err_alert = false; 843 844 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 845 int len = event.get_vendor_data_len(); 846 int event_id = event.get_vendor_subcmd(); 847 ALOGI("Got event: %d", event_id); 848 849 if (vendor_data == NULL || len == 0) { 850 ALOGE("No Debug data found"); 851 return NL_SKIP; 852 } 853 854 if (event_id == GOOGLE_DEBUG_MEM_DUMP_EVENT) { 855 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 856 if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) { 857 mBuffSize = it.get_u32(); 858 } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) { 859 buffer_size = it.get_len(); 860 buffer = (char *)it.get_data(); 861 } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_ERR_CODE) { 862 /* Error code is for error alert event only */ 863 mErrCode = it.get_u32(); 864 is_err_alert = true; 865 } else { 866 ALOGW("Ignoring invalid attribute type = %d, size = %d", 867 it.get_type(), it.get_len()); 868 } 869 } 870 871 if (is_err_alert) { 872 mBuffSize = sizeof(mErrCode); 873 if (mBuff) free(mBuff); 874 mBuff = (char *)malloc(mBuffSize); 875 if (!mBuff) { 876 ALOGE("Buffer allocation failed"); 877 return NL_SKIP; 878 } 879 memcpy(mBuff, (char *)&mErrCode, mBuffSize); 880 ALOGI("Initiating alert callback"); 881 if (mHandler.on_alert) { 882 (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode); 883 } 884 if (mBuff) { 885 free(mBuff); 886 mBuff = NULL; 887 } 888 mBuffSize = 0; 889 return NL_OK; 890 } 891 892 if (mBuffSize) { 893 ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size); 894 if (mBuff) free(mBuff); 895 mBuff = (char *)malloc(mBuffSize + buffer_size); 896 if (!mBuff) { 897 ALOGE("Buffer allocation failed"); 898 return NL_SKIP; 899 } 900 memcpy(mBuff, buffer, buffer_size); 901 902 WifiRequest request(familyId(), ifaceId()); 903 int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP); 904 if (result != WIFI_SUCCESS) { 905 ALOGE("Failed to create get memory dump request; result = %d", result); 906 free(mBuff); 907 return NL_SKIP; 908 } 909 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 910 result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize); 911 if (result != WIFI_SUCCESS) { 912 ALOGE("Failed to put get memory dump request; result = %d", result); 913 return result; 914 } 915 916 result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, 917 (uint64_t)(mBuff+buffer_size)); 918 if (result != WIFI_SUCCESS) { 919 ALOGE("Failed to put get memory dump request; result = %d", result); 920 return result; 921 } 922 923 request.attr_end(data); 924 mBuffSize += buffer_size; 925 926 result = requestResponse(request); 927 928 if (result != WIFI_SUCCESS) { 929 ALOGE("Failed to register get momory dump response; result = %d", result); 930 } 931 } else { 932 ALOGE("dump event missing dump length attribute"); 933 return NL_SKIP; 934 } 935 } 936 return NL_OK; 937 } 938 }; 939 940 class SetRestartHandler : public WifiCommand 941 { 942 wifi_subsystem_restart_handler mHandler; 943 char *mBuff; 944 public: 945 SetRestartHandler(wifi_handle handle, wifi_request_id id, wifi_subsystem_restart_handler handler) 946 : WifiCommand("SetRestartHandler", handle, id), mHandler(handler), mBuff(NULL) 947 { } 948 int start() { 949 ALOGI("Start Restart Handler handler:%p", mHandler); 950 registerVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED); 951 return WIFI_SUCCESS; 952 } 953 virtual int cancel() { 954 ALOGI("Clear Restart Handler"); 955 956 /* unregister alert handler */ 957 unregisterVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED); 958 wifi_unregister_cmd(wifiHandle(), id()); 959 ALOGI("Success to clear restarthandler"); 960 return WIFI_SUCCESS; 961 } 962 963 virtual int handleResponse(WifiEvent& reply) { 964 /* Nothing to do on response! */ 965 return NL_OK; 966 } 967 968 virtual int handleEvent(WifiEvent& event) { 969 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 970 int len = event.get_vendor_data_len(); 971 int event_id = event.get_vendor_subcmd(); 972 ALOGI("Got event: %d", event_id); 973 974 if (vendor_data == NULL || len == 0) { 975 ALOGE("No Debug data found"); 976 return NL_SKIP; 977 } 978 if (event_id == BRCM_VENDOR_EVENT_HANGED) { 979 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 980 if (it.get_type() == LOGGER_ATTRIBUTE_HANG_REASON) { 981 mBuff = (char *)it.get_data(); 982 } else { 983 ALOGI("Ignoring invalid attribute type = %d, size = %d", 984 it.get_type(), it.get_len()); 985 } 986 } 987 988 if (*mHandler.on_subsystem_restart) { 989 (*mHandler.on_subsystem_restart)(mBuff); 990 ALOGI("Hang event received. Trigger SSR handler:%p", 991 mHandler.on_subsystem_restart); 992 } else { 993 ALOGI("No Restart handler registered"); 994 } 995 } 996 return NL_OK; 997 } 998 }; 999 1000 /////////////////////////////////////////////////////////////////////////////// 1001 class SubSystemRestart : public WifiCommand 1002 { 1003 public: 1004 SubSystemRestart(wifi_interface_handle iface) 1005 : WifiCommand("SubSystemRestart", iface, 0) 1006 { } 1007 1008 int createRequest(WifiRequest& request) { 1009 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_TRIGGER_SSR); 1010 if (result < 0) { 1011 return result; 1012 } 1013 1014 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1015 1016 request.attr_end(data); 1017 return WIFI_SUCCESS; 1018 } 1019 1020 int create() { 1021 WifiRequest request(familyId(), ifaceId()); 1022 1023 int result = createRequest(request); 1024 if (result < 0) { 1025 ALOGE("Failed to create ssr request result = %d\n", result); 1026 return result; 1027 } 1028 1029 result = requestResponse(request); 1030 if (result != WIFI_SUCCESS) { 1031 ALOGE("Failed to register ssr response; result = %d\n", result); 1032 } 1033 return result; 1034 } 1035 1036 protected: 1037 int handleResponse(WifiEvent& reply) { 1038 /* Nothing to do on response! */ 1039 return NL_OK; 1040 } 1041 1042 int handleEvent(WifiEvent& event) { 1043 /* NO events to handle here! */ 1044 return NL_SKIP; 1045 } 1046 1047 }; 1048 /////////////////////////////////////////////////////////////////////////////// 1049 class HalInit : public WifiCommand 1050 { 1051 int mErrCode; 1052 1053 public: 1054 HalInit(wifi_interface_handle iface, int id) 1055 : WifiCommand("HalInit", iface, id), mErrCode(0) 1056 { } 1057 1058 int start() { 1059 ALOGE("Start Set Hal"); 1060 WifiRequest request(familyId(), ifaceId()); 1061 1062 int result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_START); 1063 if (result != WIFI_SUCCESS) { 1064 ALOGE("Failed to set hal start; result = %d", result); 1065 return result; 1066 } 1067 1068 result = requestResponse(request); 1069 if (result != WIFI_SUCCESS) { 1070 ALOGE("Failed to register set hal start response; result = %d", result); 1071 } 1072 return result; 1073 } 1074 1075 1076 virtual int cancel() { 1077 ALOGE("Cancel: Stop Hal"); 1078 WifiRequest request(familyId(), ifaceId()); 1079 1080 int result = request.create(GOOGLE_OUI, LOGGER_HAL_STOP); 1081 if (result != WIFI_SUCCESS) { 1082 ALOGE("Failed to stop hal ; result = %d", result); 1083 return result; 1084 } 1085 1086 result = requestResponse(request); 1087 if (result != WIFI_SUCCESS) { 1088 ALOGE("Failed to register set hal start response; result = %d", result); 1089 } 1090 wifi_unregister_cmd(wifiHandle(), id()); 1091 ALOGV("Stop HAL Successfully Completed, mErrCode = %d\n", mErrCode); 1092 return result; 1093 } 1094 1095 int preInit() { 1096 ALOGE("Hal preInit"); 1097 WifiRequest request(familyId(), ifaceId()); 1098 1099 int result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_START); 1100 if (result != WIFI_SUCCESS) { 1101 ALOGE("Failed to set Hal preInit; result = %d", result); 1102 return result; 1103 } 1104 1105 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1106 result = request.put_string(SET_HAL_START_ATTRIBUTE_PRE_INIT, (char *)HAL_VERSION); 1107 if (result != WIFI_SUCCESS) { 1108 ALOGE("Hal preInit Failed to put data= %d", result); 1109 return result; 1110 } 1111 request.attr_end(data); 1112 1113 result = requestResponse(request); 1114 if (result != WIFI_SUCCESS) { 1115 ALOGE("Failed to register set Hal preInit; result = %d", result); 1116 } 1117 return result; 1118 } 1119 1120 virtual int handleResponse(WifiEvent& reply) { 1121 ALOGE("In SetHalStarted::handleResponse"); 1122 1123 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1124 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 1125 return NL_SKIP; 1126 } 1127 return NL_OK; 1128 } 1129 1130 virtual int handleEvent(WifiEvent& event) { 1131 /* NO events! */ 1132 return NL_SKIP; 1133 } 1134 }; 1135 1136 1137 wifi_error wifi_start_hal(wifi_interface_handle iface) 1138 { 1139 wifi_handle handle = getWifiHandle(iface); 1140 ALOGV("HAL INIT start, handle = %p", handle); 1141 1142 HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID); 1143 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1144 wifi_error result = wifi_register_cmd(handle, HAL_START_REQUEST_ID, cmd); 1145 if (result != WIFI_SUCCESS) { 1146 cmd->releaseRef(); 1147 return result; 1148 } 1149 result = (wifi_error)cmd->start(); 1150 if (result != WIFI_SUCCESS) { 1151 wifi_unregister_cmd(handle,HAL_START_REQUEST_ID); 1152 cmd->releaseRef(); 1153 return result; 1154 } 1155 return result; 1156 } 1157 1158 wifi_error wifi_hal_preInit(wifi_interface_handle iface) 1159 { 1160 wifi_handle handle = getWifiHandle(iface); 1161 ALOGV("wifi_hal_preInit, handle = %p", handle); 1162 1163 HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID); 1164 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1165 wifi_error result = wifi_register_cmd(handle, HAL_START_REQUEST_ID, cmd); 1166 if (result != WIFI_SUCCESS) { 1167 cmd->releaseRef(); 1168 return result; 1169 } 1170 result = (wifi_error)cmd->preInit(); 1171 if (result != WIFI_SUCCESS) { 1172 wifi_unregister_cmd(handle,HAL_START_REQUEST_ID); 1173 cmd->releaseRef(); 1174 return result; 1175 } 1176 return result; 1177 } 1178 1179 wifi_error wifi_stop_hal(wifi_interface_handle iface) 1180 { 1181 HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID); 1182 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1183 cmd->cancel(); 1184 cmd->releaseRef(); 1185 return WIFI_SUCCESS; 1186 } 1187 1188 1189 wifi_error wifi_set_subsystem_restart_handler(wifi_handle handle, 1190 wifi_subsystem_restart_handler handler) 1191 { 1192 hal_info *info = NULL; 1193 1194 info = (hal_info *)handle; 1195 if (info == NULL) { 1196 ALOGE("Could not find hal info\n"); 1197 return WIFI_ERROR_UNKNOWN; 1198 } 1199 1200 SetRestartHandler *cmd = new SetRestartHandler(handle, HAL_RESTART_ID, handler); 1201 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1202 wifi_error result = wifi_register_cmd(handle, HAL_RESTART_ID, cmd); 1203 if (result != WIFI_SUCCESS) { 1204 cmd->releaseRef(); 1205 return result; 1206 } 1207 1208 result = (wifi_error)cmd->start(); 1209 if (result != WIFI_SUCCESS) { 1210 wifi_unregister_cmd(handle, HAL_RESTART_ID); 1211 cmd->releaseRef(); 1212 return result; 1213 } 1214 1215 /* Cache the handler to use it for trigger subsystem restart */ 1216 ALOGI("Register SSR handler:%p", handler); 1217 info->restart_handler = handler; 1218 return result; 1219 } 1220 1221 wifi_error wifi_trigger_subsystem_restart(wifi_handle handle) 1222 { 1223 wifi_error result = WIFI_SUCCESS; 1224 hal_info *info = NULL; 1225 char error_str[20]; 1226 SubSystemRestart *cmd = NULL; 1227 wifi_interface_handle *ifaceHandles = NULL; 1228 wifi_interface_handle wlan0Handle; 1229 int numIfaceHandles = 0; 1230 1231 info = (hal_info *)handle; 1232 if (handle == NULL || info == NULL) { 1233 ALOGE("Could not find hal info\n"); 1234 result = WIFI_ERROR_UNKNOWN; 1235 goto exit; 1236 } 1237 1238 ALOGI("Trigger subsystem restart\n"); 1239 1240 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles); 1241 1242 cmd = new SubSystemRestart(wlan0Handle); 1243 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1244 1245 result = (wifi_error)cmd->create(); 1246 if (result != WIFI_SUCCESS) { 1247 cmd->releaseRef(); 1248 strncpy(error_str, "WIFI_ERROR_UNKNOWN", sizeof(error_str)); 1249 ALOGE("Failed to create SSR"); 1250 goto exit; 1251 } 1252 1253 strncpy(error_str, "WIFI_SUCCESS", sizeof(error_str)); 1254 1255 exit: 1256 if (info->restart_handler.on_subsystem_restart) { 1257 ALOGI("Trigger ssr handler registered handler:%p", 1258 info->restart_handler.on_subsystem_restart); 1259 (info->restart_handler.on_subsystem_restart)(error_str); 1260 } else { 1261 ALOGI("No trigger ssr handler registered"); 1262 } 1263 1264 return result; 1265 } 1266 1267 wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface, 1268 wifi_alert_handler handler) 1269 { 1270 wifi_handle handle = getWifiHandle(iface); 1271 ALOGV("Alerthandler start, handle = %p", handle); 1272 1273 SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler); 1274 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1275 wifi_error result = wifi_register_cmd(handle, id, cmd); 1276 if (result != WIFI_SUCCESS) { 1277 cmd->releaseRef(); 1278 return result; 1279 } 1280 result = (wifi_error)cmd->start(); 1281 if (result != WIFI_SUCCESS) { 1282 wifi_unregister_cmd(handle, id); 1283 cmd->releaseRef(); 1284 return result; 1285 } 1286 return result; 1287 } 1288 1289 wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface) 1290 { 1291 wifi_handle handle = getWifiHandle(iface); 1292 ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle); 1293 1294 if (id == -1) { 1295 wifi_alert_handler handler; 1296 memset(&handler, 0, sizeof(handler)); 1297 1298 SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler); 1299 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1300 cmd->cancel(); 1301 cmd->releaseRef(); 1302 return WIFI_SUCCESS; 1303 } 1304 1305 return wifi_get_cancel_cmd(id, iface); 1306 } 1307 1308 /////////////////////////////////////////////////////////////////////////////// 1309 class MemoryDumpCommand: public WifiCommand 1310 { 1311 wifi_firmware_memory_dump_handler mHandler; 1312 int mBuffSize; 1313 char *mBuff; 1314 1315 public: 1316 MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler) 1317 : WifiCommand("MemoryDumpCommand", iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL) 1318 { } 1319 1320 int start() { 1321 ALOGD("Start memory dump command"); 1322 WifiRequest request(familyId(), ifaceId()); 1323 1324 int result = request.create(GOOGLE_OUI, LOGGER_TRIGGER_MEM_DUMP); 1325 if (result != WIFI_SUCCESS) { 1326 ALOGE("Failed to create trigger fw memory dump request; result = %d", result); 1327 return result; 1328 } 1329 1330 result = requestResponse(request); 1331 if (result != WIFI_SUCCESS) { 1332 ALOGE("Failed to register trigger memory dump response; result = %d", result); 1333 } 1334 return result; 1335 } 1336 1337 virtual int handleResponse(WifiEvent& reply) { 1338 ALOGD("In MemoryDumpCommand::handleResponse"); 1339 1340 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1341 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 1342 return NL_SKIP; 1343 } 1344 1345 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 1346 int len = reply.get_vendor_data_len(); 1347 1348 ALOGD("len = %d", len); 1349 if (vendor_data == NULL || len == 0) { 1350 ALOGE("no vendor data in memory dump response; ignoring it"); 1351 return NL_SKIP; 1352 } 1353 1354 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 1355 if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) { 1356 mBuffSize = it.get_u32(); 1357 1358 if (mBuff) 1359 free(mBuff); 1360 mBuff = (char *)malloc(mBuffSize); 1361 if (!mBuff) { 1362 ALOGE("Buffer allocation failed"); 1363 return NL_SKIP; 1364 } 1365 WifiRequest request(familyId(), ifaceId()); 1366 int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP); 1367 if (result != WIFI_SUCCESS) { 1368 ALOGE("Failed to create get memory dump request; result = %d", result); 1369 free(mBuff); 1370 return NL_SKIP; 1371 } 1372 1373 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1374 result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize); 1375 if (result != WIFI_SUCCESS) { 1376 ALOGE("Failed to put get memory dump request; result = %d", result); 1377 return result; 1378 } 1379 1380 result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff); 1381 if (result != WIFI_SUCCESS) { 1382 ALOGE("Failed to put get memory dump request; result = %d", result); 1383 return result; 1384 } 1385 request.attr_end(data); 1386 1387 result = requestResponse(request); 1388 if (result != WIFI_SUCCESS) { 1389 ALOGE("Failed to register get momory dump response; result = %d", result); 1390 } 1391 } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) { 1392 ALOGI("Initiating memory dump callback"); 1393 if (mHandler.on_firmware_memory_dump) { 1394 (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize); 1395 } 1396 if (mBuff) { 1397 free(mBuff); 1398 mBuff = NULL; 1399 } 1400 } else { 1401 ALOGW("Ignoring invalid attribute type = %d, size = %d", 1402 it.get_type(), it.get_len()); 1403 } 1404 } 1405 return NL_OK; 1406 } 1407 1408 virtual int handleEvent(WifiEvent& event) { 1409 /* NO events! */ 1410 return NL_SKIP; 1411 } 1412 }; 1413 1414 /* API to collect a firmware memory dump for a given iface */ 1415 wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface, 1416 wifi_firmware_memory_dump_handler handler) 1417 { 1418 MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler); 1419 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1420 wifi_error result = (wifi_error)cmd->start(); 1421 cmd->releaseRef(); 1422 return result; 1423 } 1424 1425 class PacketFateCommand: public WifiCommand 1426 { 1427 void *mReportBufs; 1428 size_t mNoReqFates; 1429 size_t *mNoProvidedFates; 1430 PktFateReqType mReqType; 1431 1432 public: 1433 PacketFateCommand(wifi_interface_handle handle) 1434 : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START) 1435 { 1436 mReportBufs = NULL; 1437 mNoReqFates = 0; 1438 mNoProvidedFates = NULL; 1439 } 1440 1441 PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs, 1442 size_t n_requested_fates, size_t *n_provided_fates) 1443 : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs), 1444 mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates), 1445 mReqType(TX_PACKET_FATE) 1446 { } 1447 1448 PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs, 1449 size_t n_requested_fates, size_t *n_provided_fates) 1450 : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs), 1451 mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates), 1452 mReqType(RX_PACKET_FATE) 1453 { } 1454 1455 int createRequest(WifiRequest& request) { 1456 if (mReqType == TX_PACKET_FATE) { 1457 ALOGD("%s Get Tx packet fate request\n", __FUNCTION__); 1458 return createTxPktFateRequest(request); 1459 } else if (mReqType == RX_PACKET_FATE) { 1460 ALOGD("%s Get Rx packet fate request\n", __FUNCTION__); 1461 return createRxPktFateRequest(request); 1462 } else if (mReqType == PACKET_MONITOR_START) { 1463 ALOGD("%s Monitor packet fate request\n", __FUNCTION__); 1464 return createMonitorPktFateRequest(request); 1465 } else { 1466 ALOGE("%s Unknown packet fate request\n", __FUNCTION__); 1467 return WIFI_ERROR_NOT_SUPPORTED; 1468 } 1469 return WIFI_SUCCESS; 1470 } 1471 1472 int createMonitorPktFateRequest(WifiRequest& request) { 1473 int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING); 1474 if (result < 0) { 1475 return result; 1476 } 1477 1478 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1479 request.attr_end(data); 1480 return result; 1481 } 1482 1483 int createTxPktFateRequest(WifiRequest& request) { 1484 int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES); 1485 if (result < 0) { 1486 return result; 1487 } 1488 1489 memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report))); 1490 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1491 result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates); 1492 if (result < 0) { 1493 return result; 1494 } 1495 result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs); 1496 if (result < 0) { 1497 return result; 1498 } 1499 request.attr_end(data); 1500 return result; 1501 } 1502 1503 int createRxPktFateRequest(WifiRequest& request) { 1504 int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES); 1505 if (result < 0) { 1506 return result; 1507 } 1508 1509 memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report))); 1510 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1511 result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates); 1512 if (result < 0) { 1513 return result; 1514 } 1515 result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs); 1516 if (result < 0) { 1517 return result; 1518 } 1519 request.attr_end(data); 1520 return result; 1521 } 1522 1523 int start() { 1524 ALOGD("Start get packet fate command\n"); 1525 WifiRequest request(familyId(), ifaceId()); 1526 1527 int result = createRequest(request); 1528 if (result < 0) { 1529 ALOGE("Failed to create get pkt fate request; result = %d\n", result); 1530 return result; 1531 } 1532 1533 result = requestResponse(request); 1534 if (result != WIFI_SUCCESS) { 1535 ALOGE("Failed to register get pkt fate response; result = %d\n", result); 1536 } 1537 return result; 1538 } 1539 1540 int handleResponse(WifiEvent& reply) { 1541 ALOGD("In GetPktFateCommand::handleResponse\n"); 1542 1543 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1544 ALOGI("Ignoring reply with cmd = %d", reply.get_cmd()); 1545 return NL_SKIP; 1546 } 1547 1548 int id = reply.get_vendor_id(); 1549 int subcmd = reply.get_vendor_subcmd(); 1550 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 1551 int len = reply.get_vendor_data_len(); 1552 1553 ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 1554 1555 if (mReqType == TX_PACKET_FATE) { 1556 ALOGI("Response recieved for get TX pkt fate command\n"); 1557 } else if (mReqType == RX_PACKET_FATE) { 1558 ALOGI("Response recieved for get RX pkt fate command\n"); 1559 } else if (mReqType == PACKET_MONITOR_START) { 1560 ALOGI("Response recieved for monitor pkt fate command\n"); 1561 return NL_OK; 1562 } else { 1563 ALOGE("Response recieved for unknown pkt fate command\n"); 1564 return NL_SKIP; 1565 } 1566 1567 if (vendor_data == NULL || len == 0) { 1568 ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n"); 1569 return NL_SKIP; 1570 } 1571 1572 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 1573 if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) { 1574 *mNoProvidedFates = it.get_u32(); 1575 ALOGI("No: of pkt fates provided is %zu\n", *mNoProvidedFates); 1576 } else { 1577 ALOGE("Ignoring invalid attribute type = %d, size = %d\n", 1578 it.get_type(), it.get_len()); 1579 } 1580 } 1581 1582 return NL_OK; 1583 } 1584 1585 int handleEvent(WifiEvent& event) { 1586 /* NO events to handle here! */ 1587 return NL_SKIP; 1588 } 1589 }; 1590 1591 class GetWakeReasonCountCommand : public WifiCommand { 1592 WLAN_DRIVER_WAKE_REASON_CNT *mWakeReasonCnt; 1593 void *mCmdEventWakeCount; 1594 public: 1595 GetWakeReasonCountCommand(wifi_interface_handle handle, 1596 WLAN_DRIVER_WAKE_REASON_CNT *wlanDriverWakeReasonCount) : 1597 WifiCommand("GetWakeReasonCountCommand", handle, 0), 1598 mWakeReasonCnt(wlanDriverWakeReasonCount) 1599 { 1600 mCmdEventWakeCount = mWakeReasonCnt->cmd_event_wake_cnt; 1601 } 1602 1603 int createRequest(WifiRequest& request) { 1604 int result = request.create(GOOGLE_OUI, LOGGER_GET_WAKE_REASON_STATS); 1605 if (result < 0) { 1606 return result; 1607 } 1608 1609 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1610 1611 request.attr_end(data); 1612 return WIFI_SUCCESS; 1613 } 1614 1615 int start() { 1616 ALOGD("Start get wake stats command\n"); 1617 WifiRequest request(familyId(), ifaceId()); 1618 1619 int result = createRequest(request); 1620 if (result < 0) { 1621 ALOGE("Failed to create request result = %d\n", result); 1622 return result; 1623 } 1624 1625 result = requestResponse(request); 1626 if (result != WIFI_SUCCESS) { 1627 ALOGE("Failed to register wake stats response; result = %d\n", result); 1628 } 1629 return result; 1630 } 1631 1632 protected: 1633 int handleResponse(WifiEvent& reply) { 1634 ALOGE("In GetWakeReasonCountCommand::handleResponse"); 1635 1636 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1637 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 1638 return NL_SKIP; 1639 } 1640 1641 int id = reply.get_vendor_id(); 1642 int subcmd = reply.get_vendor_subcmd(); 1643 1644 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 1645 int len = reply.get_vendor_data_len(); 1646 1647 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 1648 if (vendor_data == NULL || len == 0) { 1649 ALOGE("no vendor data in GetGetWakeReasonCountCommand response; ignoring it"); 1650 return NL_SKIP; 1651 } 1652 1653 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 1654 switch (it.get_type()) { 1655 case WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW: 1656 mWakeReasonCnt->total_driver_fw_local_wake = 1657 it.get_u32(); 1658 break; 1659 case WAKE_STAT_ATTRIBUTE_TOTAL: 1660 mWakeReasonCnt->total_cmd_event_wake = 1661 it.get_u32(); 1662 break; 1663 case WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED: 1664 mWakeReasonCnt->cmd_event_wake_cnt_used = 1665 it.get_u32(); 1666 break; 1667 case WAKE_STAT_ATTRIBUTE_WAKE: 1668 memcpy(mCmdEventWakeCount, it.get_data(), 1669 (mWakeReasonCnt->cmd_event_wake_cnt_used * sizeof(int))); 1670 break; 1671 case WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE: 1672 mWakeReasonCnt->total_rx_data_wake = 1673 it.get_u32(); 1674 break; 1675 case WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT: 1676 mWakeReasonCnt->rx_wake_details.rx_unicast_cnt = 1677 it.get_u32(); 1678 break; 1679 case WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT: 1680 mWakeReasonCnt->rx_wake_details.rx_multicast_cnt = 1681 it.get_u32(); 1682 break; 1683 case WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT: 1684 mWakeReasonCnt->rx_wake_details.rx_broadcast_cnt = 1685 it.get_u32(); 1686 break; 1687 case WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT: 1688 mWakeReasonCnt->rx_wake_pkt_classification_info.icmp_pkt = 1689 it.get_u32(); 1690 break; 1691 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT: 1692 mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_pkt = 1693 it.get_u32(); 1694 break; 1695 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA: 1696 mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_ra = 1697 it.get_u32(); 1698 break; 1699 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA: 1700 mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_na = 1701 it.get_u32(); 1702 break; 1703 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS: 1704 mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_ns = 1705 it.get_u32(); 1706 break; 1707 case WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT: 1708 mWakeReasonCnt->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt = 1709 it.get_u32(); 1710 break; 1711 case WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT: 1712 mWakeReasonCnt->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt = 1713 it.get_u32(); 1714 break; 1715 case WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT: 1716 mWakeReasonCnt->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt = 1717 it.get_u32(); 1718 break; 1719 default: 1720 break; 1721 } 1722 1723 } 1724 return NL_OK; 1725 } 1726 }; 1727 1728 wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle) 1729 { 1730 PacketFateCommand *cmd = new PacketFateCommand(handle); 1731 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1732 wifi_error result = (wifi_error)cmd->start(); 1733 cmd->releaseRef(); 1734 return result; 1735 } 1736 1737 wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle, 1738 wifi_tx_report *tx_report_bufs, size_t n_requested_fates, 1739 size_t *n_provided_fates) 1740 { 1741 PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs, 1742 n_requested_fates, n_provided_fates); 1743 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1744 wifi_error result = (wifi_error)cmd->start(); 1745 cmd->releaseRef(); 1746 return result; 1747 } 1748 1749 wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle, 1750 wifi_rx_report *rx_report_bufs, size_t n_requested_fates, 1751 size_t *n_provided_fates) 1752 { 1753 PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs, 1754 n_requested_fates, n_provided_fates); 1755 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1756 wifi_error result = (wifi_error)cmd->start(); 1757 cmd->releaseRef(); 1758 return result; 1759 } 1760 1761 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle handle, 1762 WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) 1763 { 1764 GetWakeReasonCountCommand *cmd = 1765 new GetWakeReasonCountCommand(handle, wifi_wake_reason_cnt); 1766 wifi_error result = (wifi_error)cmd->start(); 1767 cmd->releaseRef(); 1768 return result; 1769 } 1770 1771 /////////////////////////////////////////////////////////////////////////////// 1772 class OtaUpdateCommand : public WifiCommand 1773 { 1774 int mErrCode; 1775 1776 public: 1777 OtaUpdateCommand(wifi_interface_handle iface) 1778 : WifiCommand("OtaUpdateCommand", iface, 0), mErrCode(0) 1779 { } 1780 1781 int start() { 1782 ALOGE("Start OtaUpdateCommand"); 1783 WifiRequest request(familyId(), ifaceId()); 1784 1785 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_GET_OTA_CURRUNT_INFO); 1786 if (result != WIFI_SUCCESS) { 1787 ALOGE("Failed to set hal start; result = %d", result); 1788 return result; 1789 } 1790 1791 result = requestResponse(request); 1792 if (result != WIFI_SUCCESS) { 1793 ALOGE("Failed to register set hal start response; result = %d", result); 1794 } 1795 return result; 1796 } 1797 1798 int otaDownload(ota_info_buf_t* buf, uint32_t ota_version) { 1799 u32 force_reg_on = false; 1800 WifiRequest request(familyId(), ifaceId()); 1801 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_OTA_UPDATE); 1802 1803 ALOGE("Download the OTA configuration"); 1804 if (result != WIFI_SUCCESS) { 1805 ALOGE("Failed to set Hal preInit; result = %d", result); 1806 return result; 1807 } 1808 1809 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1810 1811 result = request.put_u32(OTA_DOWNLOAD_CLM_LENGTH_ATTR, buf->ota_clm_len); 1812 if (result != WIFI_SUCCESS) { 1813 ALOGE("otaDownload Failed to put data= %d", result); 1814 return result; 1815 } 1816 1817 result = request.put(OTA_DOWNLOAD_CLM_ATTR, buf->ota_clm_buf, sizeof(*buf->ota_clm_buf)); 1818 if (result != WIFI_SUCCESS) { 1819 ALOGE("otaDownload Failed to put data= %d", result); 1820 return result; 1821 } 1822 1823 result = request.put_u32(OTA_DOWNLOAD_NVRAM_LENGTH_ATTR, buf->ota_nvram_len); 1824 if (result != WIFI_SUCCESS) { 1825 ALOGE("otaDownload Failed to put data= %d", result); 1826 return result; 1827 } 1828 1829 result = request.put(OTA_DOWNLOAD_NVRAM_ATTR, 1830 buf->ota_nvram_buf, sizeof(*buf->ota_nvram_buf)); 1831 if (result != WIFI_SUCCESS) { 1832 ALOGE("otaDownload Failed to put data= %d", result); 1833 return result; 1834 } 1835 1836 if (applied_ota_version != ota_version) { 1837 force_reg_on = true; 1838 applied_ota_version = ota_version; 1839 } 1840 result = request.put_u32(OTA_SET_FORCE_REG_ON, force_reg_on); 1841 if (result != WIFI_SUCCESS) { 1842 ALOGE("otaDownload Failed to put data= %d", result); 1843 return result; 1844 } 1845 1846 request.attr_end(data); 1847 1848 result = requestResponse(request); 1849 if (result != WIFI_SUCCESS) { 1850 ALOGE("Failed to register set otaDownload; result = %d", result); 1851 } 1852 1853 return result; 1854 } 1855 1856 virtual int handleResponse(WifiEvent& reply) { 1857 ALOGD("In OtaUpdateCommand::handleResponse"); 1858 1859 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1860 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 1861 return NL_SKIP; 1862 } 1863 1864 int id = reply.get_vendor_id(); 1865 int subcmd = reply.get_vendor_subcmd(); 1866 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 1867 int len = reply.get_vendor_data_len(); 1868 1869 ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 1870 1871 if (vendor_data == NULL || len == 0) { 1872 ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n"); 1873 return NL_SKIP; 1874 } 1875 1876 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 1877 switch (it.get_type()) { 1878 case OTA_CUR_NVRAM_EXT_ATTR: 1879 strncpy(ota_nvram_ext, (char*)it.get_string(), it.get_len()); 1880 ALOGI("Current Nvram ext [%s]\n", ota_nvram_ext); 1881 break; 1882 default: 1883 ALOGE("Ignoring invalid attribute type = %d, size = %d\n", 1884 it.get_type(), it.get_len()); 1885 break; 1886 } 1887 } 1888 return NL_OK; 1889 } 1890 1891 virtual int handleEvent(WifiEvent& event) { 1892 /* NO events! */ 1893 return NL_SKIP; 1894 } 1895 }; 1896 1897 wifi_error read_ota_file(char* file, char** buffer, uint32_t* size) 1898 { 1899 FILE* fp = NULL; 1900 int file_size, count; 1901 char* buf; 1902 fp = fopen(file, "r"); 1903 1904 if (fp == NULL) { 1905 ALOGI("File [%s] doesn't exist.", file); 1906 return WIFI_ERROR_NOT_AVAILABLE; 1907 } 1908 1909 fseek(fp, 0, SEEK_END); 1910 file_size = ftell(fp); 1911 1912 buf = (char *)malloc(file_size + 1); 1913 if (buf == NULL) { 1914 fclose(fp); 1915 return WIFI_ERROR_UNKNOWN; 1916 } 1917 memset(buf, 0, file_size + 1); 1918 fseek(fp, 0, SEEK_SET); 1919 count = fread(buf, file_size, 1, fp); 1920 1921 *buffer = (char*) buf; 1922 *size = file_size; 1923 fclose(fp); 1924 return WIFI_SUCCESS; 1925 } 1926 1927 wifi_error check_multiple_nvram_clm(uint32_t type, char* hw_revision, char* hw_sku, 1928 char** buffer, uint32_t* buffer_len) 1929 { 1930 char file_name[MAX_NV_FILE][FILE_NAME_LEN]; 1931 char nvram_clmblob_default_file[FILE_NAME_LEN] = {0,}; 1932 wifi_error result = WIFI_SUCCESS; 1933 1934 if (type == CLM_BLOB) { 1935 sprintf(nvram_clmblob_default_file, "%s%s", OTA_PATH, OTA_CLM_FILE); 1936 } 1937 else if (type == NVRAM) { 1938 sprintf(nvram_clmblob_default_file, "%s%s", OTA_PATH, OTA_NVRAM_FILE); 1939 } 1940 for (unsigned int i = 0; i < MAX_NV_FILE; i++) { 1941 memset(file_name[i], 0, FILE_NAME_LEN); 1942 } 1943 1944 sprintf(file_name[0], "%s_%s_%s", nvram_clmblob_default_file, hw_revision, hw_sku); 1945 sprintf(file_name[1], "%s_%s", nvram_clmblob_default_file, hw_revision); 1946 sprintf(file_name[2], "%s_%s", nvram_clmblob_default_file, hw_sku); 1947 sprintf(file_name[3], "%s", nvram_clmblob_default_file); 1948 1949 for (unsigned int i = 0; i < MAX_NV_FILE; i++) { 1950 result = read_ota_file(file_name[i], buffer, buffer_len); 1951 if (result == WIFI_SUCCESS) { 1952 ALOGI("[OTA] %s PATH %s", type == NVRAM ? "NVRAM" : "CLM", file_name[i]); 1953 break; 1954 } 1955 } 1956 return result; 1957 } 1958 1959 wifi_error wifi_hal_ota_update(wifi_interface_handle iface, uint32_t ota_version) 1960 { 1961 wifi_handle handle = getWifiHandle(iface); 1962 wifi_error result = WIFI_SUCCESS; 1963 ota_info_buf_t buf; 1964 char *buffer_nvram = NULL; 1965 char *buffer_clm = NULL; 1966 char prop_revision_buf[PROPERTY_VALUE_MAX] = {0,}; 1967 char prop_sku_buf[PROPERTY_VALUE_MAX] = {0,}; 1968 char sku_name[MAX_SKU_NAME_LEN] = {0,}; 1969 1970 OtaUpdateCommand *cmd = new OtaUpdateCommand(iface); 1971 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1972 1973 ALOGD("wifi_hal_ota_update, handle = %p, ota_version %d\n", handle, ota_version); 1974 1975 result = (wifi_error)cmd->start(); 1976 if (result != WIFI_SUCCESS) { 1977 cmd->releaseRef(); 1978 return result; 1979 } 1980 1981 property_get(HW_DEV_PROP, prop_revision_buf, NULL); 1982 property_get(HW_SKU_PROP, prop_sku_buf, NULL); 1983 1984 if (strcmp(prop_sku_buf, "G9S9B") == 0 || 1985 strcmp(prop_sku_buf, "G8V0U") == 0 || 1986 strcmp(prop_sku_buf, "GFQM1") == 0) { 1987 strncpy(sku_name, "MMW", MAX_SKU_NAME_LEN); 1988 } else if (strcmp(prop_sku_buf, "GR1YH") == 0 || 1989 strcmp(prop_sku_buf, "GF5KQ") == 0 || 1990 strcmp(prop_sku_buf, "GPQ72") == 0) { 1991 strncpy(sku_name, "JPN", MAX_SKU_NAME_LEN); 1992 } else if (strcmp(prop_sku_buf, "GB7N6") == 0 || 1993 strcmp(prop_sku_buf, "GLU0G") == 0 || 1994 strcmp(prop_sku_buf, "GNA8F") == 0) { 1995 strncpy(sku_name, "ROW", MAX_SKU_NAME_LEN); 1996 } else { 1997 strncpy(sku_name, "NA", MAX_SKU_NAME_LEN); 1998 } 1999 2000 check_multiple_nvram_clm(CLM_BLOB, prop_revision_buf, sku_name, &buffer_clm, &buf.ota_clm_len); 2001 if (buffer_clm == NULL) { 2002 ALOGE("buffer_clm is null"); 2003 goto exit; 2004 } 2005 buf.ota_clm_buf[0] = buffer_clm; 2006 2007 check_multiple_nvram_clm(NVRAM, prop_revision_buf, sku_name, 2008 &buffer_nvram, &buf.ota_nvram_len); 2009 if (buffer_nvram == NULL) { 2010 ALOGE("buffer_nvram is null"); 2011 goto exit; 2012 } 2013 buf.ota_nvram_buf[0] = buffer_nvram; 2014 cmd->otaDownload(&buf, ota_version); 2015 2016 exit: 2017 if (buffer_clm != NULL) { 2018 free(buffer_clm); 2019 } 2020 if (buffer_nvram != NULL) { 2021 free(buffer_nvram); 2022 } 2023 2024 cmd->releaseRef(); 2025 2026 return result; 2027 } 2028