1aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <stdint.h> 2aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <fcntl.h> 3aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <sys/socket.h> 4aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/genl/genl.h> 5aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/genl/family.h> 6aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/genl/ctrl.h> 7aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <linux/rtnetlink.h> 8aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netpacket/packet.h> 9aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <linux/filter.h> 10aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <linux/errqueue.h> 11aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 12aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <linux/pkt_sched.h> 13aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/object-api.h> 14aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/netlink.h> 15aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink/socket.h> 16aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <netlink-types.h> 17aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 18aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include "nl80211_copy.h" 19aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include "sync.h" 20aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 21aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#define LOG_TAG "WifiHAL" 22aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 23aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include <utils/Log.h> 24aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 25aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include "wifi_hal.h" 26aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include "common.h" 27aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee#include "cpp_bindings.h" 28aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 29aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leeusing namespace android; 30aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 31aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leetypedef enum { 32aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START, 33aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_TRIGGER_MEM_DUMP, 34aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_GET_MEM_DUMP, 35aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_GET_VER, 36aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_GET_RING_STATUS, 37aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_GET_RING_DATA, 38aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_GET_FEATURE, 39c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee LOGGER_RESET_LOGGING, 407e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_TRIGGER_DRIVER_MEM_DUMP, 417e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_GET_DRIVER_MEM_DUMP, 427e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_START_PKT_FATE_MONITORING, 437e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_GET_TX_PKT_FATES, 447e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_GET_RX_PKT_FATES, 45aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} DEBUG_SUB_COMMAND; 46aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 47aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leetypedef enum { 48aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_DRIVER_VER, 49aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_FW_VER, 50aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_ID, 51aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_NAME, 52aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_FLAGS, 53aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_LOG_LEVEL, 54aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, 55aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, 56aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_FW_DUMP_LEN, 57aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_FW_DUMP_DATA, 58aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // LOGGER_ATTRIBUTE_FW_ERR_CODE, 59aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_DATA, 60aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_STATUS, 61aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee LOGGER_ATTRIBUTE_RING_NUM, 627e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN, 637e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA, 647e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_ATTRIBUTE_PKT_FATE_NUM, 657e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma LOGGER_ATTRIBUTE_PKT_FATE_DATA, 66aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} LOGGER_ATTRIBUTE; 67aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 68aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leetypedef enum { 69aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DEBUG_OFF = 0, 70aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DEBUG_NORMAL, 71aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DEBUG_VERBOSE, 72aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DEBUG_VERY, 73aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DEBUG_VERY_VERY, 74aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} LOGGER_LEVEL; 75aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 76aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leetypedef enum { 77aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GET_FW_VER, 78aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GET_DRV_VER, 79aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GET_RING_DATA, 80aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GET_RING_STATUS, 81aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GET_FEATURE, 82aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee START_RING_LOG, 83aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} GetCmdType; 84aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 857e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmatypedef enum { 867e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PACKET_MONITOR_START, 877e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma TX_PACKET_FATE, 887e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma RX_PACKET_FATE, 897e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma} PktFateReqType; 907e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 91aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 92aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/////////////////////////////////////////////////////////////////////////////// 93aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leeclass DebugCommand : public WifiCommand 94aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 95040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe char *mBuff; 96aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int *mBuffSize; 97aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 *mNumRings; 98040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe wifi_ring_buffer_status *mStatus; 99aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee unsigned int *mSupport; 100aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 mVerboseLevel; 101aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 mFlags; 102aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 mMaxIntervalSec; 103aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 mMinDataSize; 104aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee char *mRingName; 105aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GetCmdType mType; 106aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 107aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leepublic: 108aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 109aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // constructor for get version 110040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size, 111aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee GetCmdType cmdType) 112d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("DebugCommand", iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType 113d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande (cmdType) 114aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 115040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe memset(mBuff, 0, *mBuffSize); 116aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 117aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 118aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // constructor for ring data 119aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType) 120d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("DebugCommand", iface, 0), mRingName(ring_name), mType(cmdType) 121aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 122aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 123aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // constructor for ring status 124aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand(wifi_interface_handle iface, u32 *num_rings, 125040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe wifi_ring_buffer_status *status, GetCmdType cmdType) 126d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("DebugCommand", iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType) 127aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 128040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings)); 129aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 130aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 131aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // constructor for feature set 132aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType) 133d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("DebugCommand", iface, 0), mSupport(support), mType(cmdType) 134aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 135aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 136aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // constructor for ring params 137aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags, 138aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType) 139d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("DebugCommand", iface, 0), mVerboseLevel(verbose_level), mFlags(flags), 140aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size), 141aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mRingName(ring_name), mType(cmdType) 142aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 143aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 144aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int createRingRequest(WifiRequest& request) { 145aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result = request.create(GOOGLE_OUI, LOGGER_START_LOGGING); 146aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 147aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create start ring logger request; result = %d", result); 148aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 149aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 150aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 151aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 152aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 153aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel); 154aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 155aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put log level; result = %d", result); 156aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 157aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 158aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_RING_FLAGS, mFlags); 159aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 160aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put ring flags; result = %d", result); 161aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 162aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 163aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec); 164aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 165aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put log time interval; result = %d", result); 166aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 167aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 168aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize); 169aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 170aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put min data size; result = %d", result); 171aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 172aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 173aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName); 174aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 175aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put ringbuffer name; result = %d", result); 176aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 177aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 178aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 179aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 180aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_SUCCESS; 181aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 182aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 183aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int createRequest(WifiRequest &request) { 184aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result; 185aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 186aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee switch (mType) { 187aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_FW_VER: 188aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 189aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.create(GOOGLE_OUI, LOGGER_GET_VER); 190aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 191aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get fw version request; result = %d", result); 192aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 193aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 194aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 195aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 196aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 197aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // Driver expecting only attribute type, passing mbuff as data with 198aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // length 0 to avoid undefined state 199040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe result = request.put(LOGGER_ATTRIBUTE_FW_VER, mBuff, 0); 200aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 201aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get fw version request; result = %d", result); 202aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 203aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 204aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 205aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 206aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 207aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 208aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_DRV_VER: 209aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 210aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.create(GOOGLE_OUI, LOGGER_GET_VER); 211aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 212aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get drv version request; result = %d", result); 213aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 214aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 215aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 216aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 217aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 218aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // Driver expecting only attribute type, passing mbuff as data with 219aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee // length 0 to avoid undefined state 220040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe result = request.put(LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0); 221aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 222aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 223aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get drv version request; result = %d", result); 224aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 225aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 226aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 227aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 228aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 229aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 230aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_RING_DATA: 231aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 232aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.create(GOOGLE_OUI, LOGGER_GET_RING_DATA); 233aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 234aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get ring data request; result = %d", result); 235aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 236aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 237aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 238aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 239aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName); 240aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 241aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put ring data request; result = %d", result); 242aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 243aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 244aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 245aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 246aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 247aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 248aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_RING_STATUS: 249aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 250aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.create(GOOGLE_OUI, LOGGER_GET_RING_STATUS); 251aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 252aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get ring status request; result = %d", result); 253aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 254aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 255aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 256aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 257aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 258aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_FEATURE: 259aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 260aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.create(GOOGLE_OUI, LOGGER_GET_FEATURE); 261aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 262aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get feature request; result = %d", result); 263aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 264aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 265aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 266aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 267aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 268aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case START_RING_LOG: 269aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = createRingRequest(request); 270aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 271aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 272aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee default: 273aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Unknown Debug command"); 274aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = WIFI_ERROR_UNKNOWN; 275aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 276aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 277aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 278aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 279aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int start() { 280bedc792622bd9ef90c30e4d8c5efa194f1010d2eVinit Deshpande // ALOGD("Start debug command"); 281aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee WifiRequest request(familyId(), ifaceId()); 282aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result = createRequest(request); 283aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 284aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create debug request; result = %d", result); 285aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 286aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 287aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 288aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = requestResponse(request); 289aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 290aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to register debug response; result = %d", result); 291aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 292aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 293aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 294aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 295aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleResponse(WifiEvent& reply) { 296aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("In DebugCommand::handleResponse"); 297aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 298aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (reply.get_cmd() != NL80211_CMD_VENDOR) { 299aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 300aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 301aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 302aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 303aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee switch (mType) { 304aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_DRV_VER: 305aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_FW_VER: 306aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 307aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee void *data = reply.get_vendor_data(); 308aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = reply.get_vendor_data_len(); 309aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 310aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("len = %d, expected len = %d", len, *mBuffSize); 311040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe memcpy(mBuff, data, min(len, *mBuffSize)); 312aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (*mBuffSize < len) 313aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 314aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee *mBuffSize = len; 315aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 316aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 317aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 318aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case START_RING_LOG: 319aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_RING_DATA: 320aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 321aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 322aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_RING_STATUS: 323aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 324aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 325aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = reply.get_vendor_data_len(); 326040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe wifi_ring_buffer_status *status(mStatus); 327aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 328aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (vendor_data == NULL || len == 0) { 329aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("No Debug data found"); 330aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 331aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 332aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 333aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nl_iterator it(vendor_data); 334aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_RING_NUM) { 335aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee unsigned int num_rings = it.get_u32(); 336aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (*mNumRings < num_rings) { 337aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Not enough status buffers provided, available: %d required: %d", 338aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee *mNumRings, num_rings); 339aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 340aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee *mNumRings = num_rings; 341aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 342aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 343aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Unknown attribute: %d expecting %d", 344aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.get_type(), LOGGER_ATTRIBUTE_RING_NUM); 345aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 346aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 347aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 348aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.next(); 349aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee for (unsigned int i = 0; it.has_next() && i < *mNumRings; it.next()) { 350aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) { 351aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status)); 352aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee i++; 353aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee status++; 354aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 355aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGW("Ignoring invalid attribute type = %d, size = %d", 356aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.get_type(), it.get_len()); 357aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 358aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 359aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 360aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 361aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 362aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee case GET_FEATURE: 363aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { 364aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee void *data = reply.get_vendor_data(); 365aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = reply.get_vendor_data_len(); 366aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 367aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("len = %d, expected len = %d", len, sizeof(unsigned int)); 368aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee memcpy(mSupport, data, sizeof(unsigned int)); 369aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee break; 370aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 371aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 372aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee default: 373aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGW("Unknown Debug command"); 374aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 375aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_OK; 376aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 377aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 378aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleEvent(WifiEvent& event) { 379aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee /* NO events! */ 380aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 381aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 382aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee}; 383aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 384aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to collect a firmware version string */ 385040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhewifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer, 386040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe int buffer_size) 387aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 388040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe if (buffer && (buffer_size > 0)) { 389040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER); 3906af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 3916af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 3926af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 3936af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 394aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 395aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("FW version buffer NULL"); 396aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_ERROR_INVALID_ARGS; 397aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 398aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 399aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 400aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to collect a driver version string */ 401040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhewifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size) 402aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 403040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe if (buffer && (buffer_size > 0)) { 404040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER); 4056af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 4066af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 4076af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 4086af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 409aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 410aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Driver version buffer NULL"); 411aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_ERROR_INVALID_ARGS; 412aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 413aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 414aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 415aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to collect driver records */ 416aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name) 417aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 418aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA); 4196af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 4206af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 4216af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 4226af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 423aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 424aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 425aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to get the status of all ring buffers supported by driver */ 426aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, 427040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe u32 *num_rings, wifi_ring_buffer_status *status) 428aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 429040ee11fb7c5f1781537ae4343c056c0a49dcfc5xinhe if (status && num_rings) { 430aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS); 4316af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 4326af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 4336af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 4346af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 435aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 436aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Ring status buffer NULL"); 437aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_ERROR_INVALID_ARGS; 438aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 439aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 440aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 441aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to get supportable feature */ 442aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface, 443aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee unsigned int *support) 444aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 445aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (support) { 446aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE); 4476af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 4486af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 4496af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 4506af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 451aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 452aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Get support buffer NULL"); 453aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_ERROR_INVALID_ARGS; 454aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 455aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 456aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 457aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, 458aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name) 459aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 460aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (ring_name) { 4616af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec, 4626af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma min_data_size, ring_name, START_RING_LOG); 4636af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 4646af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 4656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 4666af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 467aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 468aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Ring name NULL"); 469aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_ERROR_INVALID_ARGS; 470aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 471aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 472aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 473aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 474aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/////////////////////////////////////////////////////////////////////////////// 475aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leeclass SetLogHandler : public WifiCommand 476aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 477aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_ring_buffer_data_handler mHandler; 478aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 479aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leepublic: 480aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler) 481d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetLogHandler", iface, id), mHandler(handler) 482aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 483aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 484aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int start() { 48556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Register loghandler"); 486aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); 487aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_SUCCESS; 488aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 489aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 4905ca0ce0387ccaa71c18c09278bf8d810759c3aa9Vinit Deshpande virtual int cancel() { 491c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee /* Send a command to driver to stop generating logging events */ 49256deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Clear loghandler"); 493c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee 494f02f545dd490b658110fb837f4905050b3ed9c52Vinit Deshpande /* unregister event handler */ 495f02f545dd490b658110fb837f4905050b3ed9c52Vinit Deshpande unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); 496f02f545dd490b658110fb837f4905050b3ed9c52Vinit Deshpande 497c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee WifiRequest request(familyId(), ifaceId()); 498c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING); 499c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee if (result != WIFI_SUCCESS) { 500c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee ALOGE("failed to create reset request; result = %d", result); 501c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee return result; 502c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee } 503c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee 504c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee result = requestResponse(request); 505c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee if (result != WIFI_SUCCESS) { 506c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee ALOGE("failed to request reset; result = %d", result); 507c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee return result; 508c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee } 5095ca0ce0387ccaa71c18c09278bf8d810759c3aa9Vinit Deshpande 51056deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGD("Success to clear loghandler"); 5115ca0ce0387ccaa71c18c09278bf8d810759c3aa9Vinit Deshpande return WIFI_SUCCESS; 5125ca0ce0387ccaa71c18c09278bf8d810759c3aa9Vinit Deshpande } 5135ca0ce0387ccaa71c18c09278bf8d810759c3aa9Vinit Deshpande 514aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleEvent(WifiEvent& event) { 515aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee char *buffer = NULL; 516aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int buffer_size = 0; 517aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 518bedc792622bd9ef90c30e4d8c5efa194f1010d2eVinit Deshpande // ALOGD("In SetLogHandler::handleEvent"); 519aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 520aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = event.get_vendor_data_len(); 521aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int event_id = event.get_vendor_subcmd(); 522bedc792622bd9ef90c30e4d8c5efa194f1010d2eVinit Deshpande // ALOGI("Got Logger event: %d", event_id); 523aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 524aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (vendor_data == NULL || len == 0) { 525aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("No Debug data found"); 526aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 527aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 528aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 529aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if(event_id == GOOGLE_DEBUG_RING_EVENT) { 530aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_ring_buffer_status status; 531aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee memset(&status, 0, sizeof(status)); 532aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 533aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 534aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) { 535aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee memcpy(&status, it.get_data(), sizeof(status)); 536aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) { 537aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee buffer_size = it.get_len(); 538aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee buffer = (char *)it.get_data(); 539aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 540aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGW("Ignoring invalid attribute type = %d, size = %d", 541aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.get_type(), it.get_len()); 542aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 543aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 544aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 545bedc792622bd9ef90c30e4d8c5efa194f1010d2eVinit Deshpande // ALOGI("Retrieved Debug data"); 546aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mHandler.on_ring_buffer_data) { 547aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee (*mHandler.on_ring_buffer_data)((char *)status.name, buffer, buffer_size, 548aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee &status); 549aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 550aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 551aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Unknown Event"); 552aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 553aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 554aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_OK; 555aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 556aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee}; 557aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 558aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface, 559aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_ring_buffer_data_handler handler) 560aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 561aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_handle handle = getWifiHandle(iface); 56256deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Loghandler start, handle = %p", handle); 563aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 56456deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee SetLogHandler *cmd = new SetLogHandler(iface, id, handler); 5656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 5666af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 5676af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 5686af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 5696af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 5706af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 5716af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 5726af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 5736af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_unregister_cmd(handle, id); 5746af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 57556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return result; 576aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 5776af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 578aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 579aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 580c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLeewifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface) 581c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee{ 582c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee wifi_handle handle = getWifiHandle(iface); 58356deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle); 584c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee 58556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee if (id == -1) { 58656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee wifi_ring_buffer_data_handler handler; 58756deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee memset(&handler, 0, sizeof(handler)); 58856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 58956deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee SetLogHandler *cmd = new SetLogHandler(iface, id, handler); 5906af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 591c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee cmd->cancel(); 592c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee cmd->releaseRef(); 593c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee return WIFI_SUCCESS; 594c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee } 59556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 59656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return wifi_cancel_cmd(id, iface); 597c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee} 598c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee 599aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/////////////////////////////////////////////////////////////////////////////// 600aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leeclass SetAlertHandler : public WifiCommand 601aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 602aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_alert_handler mHandler; 603aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int mBuffSize; 604aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee char *mBuff; 605aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int mErrCode; 606aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 607aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leepublic: 608aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler) 609d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetAlertHandler", iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL), 610d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande mErrCode(0) 611aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 612aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 613aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int start() { 61456deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Start Alerting"); 615aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT); 616aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return WIFI_SUCCESS; 617aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 618aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 61956deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee virtual int cancel() { 62056deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Clear alerthandler"); 62156deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 62256deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee /* unregister alert handler */ 62356deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT); 62456deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee wifi_unregister_cmd(wifiHandle(), id()); 62556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGD("Success to clear alerthandler"); 62656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return WIFI_SUCCESS; 62756deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee } 62856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 629aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleResponse(WifiEvent& reply) { 630aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("In SetAlertHandler::handleResponse"); 631aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 632aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (reply.get_cmd() != NL80211_CMD_VENDOR) { 633aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 634aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 635aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 636aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 637aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 638aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = reply.get_vendor_data_len(); 639aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 640aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("len = %d", len); 641aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (vendor_data == NULL || len == 0) { 642aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("no vendor data in memory dump response; ignoring it"); 643aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 644aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 645aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 646aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 647aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) { 648aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGI("Initiating alert callback"); 649aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mHandler.on_alert) { 650aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode); 651aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 652aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mBuff) { 653aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee free(mBuff); 654aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuff = NULL; 655aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 656aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 657aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 658aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_OK; 659aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 660aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 661aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleEvent(WifiEvent& event) { 662aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_ring_buffer_id ring_id; 663aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee char *buffer = NULL; 664aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int buffer_size = 0; 665aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 666aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 667aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 668aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = event.get_vendor_data_len(); 669aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int event_id = event.get_vendor_subcmd(); 670aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGI("Got event: %d", event_id); 671aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 672aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (vendor_data == NULL || len == 0) { 673aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("No Debug data found"); 674aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 675aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 676aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 677aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (event_id == GOOGLE_DEBUG_MEM_DUMP_EVENT) { 678aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 679aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) { 680aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuffSize = it.get_u32(); 681aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) { 682aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee buffer_size = it.get_len(); 683aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee buffer = (char *)it.get_data(); 684aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee /* 685aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_ERR_CODE) { 686aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mErrCode = it.get_u32(); 687aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee */ 688aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 689aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGW("Ignoring invalid attribute type = %d, size = %d", 690aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.get_type(), it.get_len()); 691aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 692aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 693aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mBuffSize) { 694aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size); 695aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mBuff) free(mBuff); 696aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuff = (char *)malloc(mBuffSize + buffer_size); 697aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (!mBuff) { 698aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Buffer allocation failed"); 699aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 700aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 701aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee memcpy(mBuff, buffer, buffer_size); 702aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 703aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee WifiRequest request(familyId(), ifaceId()); 704aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP); 705aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 706aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get memory dump request; result = %d", result); 707aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee free(mBuff); 708aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 709aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 710aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 711aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize); 712aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 713aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get memory dump request; result = %d", result); 714aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 715aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 716b3b31174c61e38a970b956cb50cb66cd1903ca9bJerry Lee 717b3b31174c61e38a970b956cb50cb66cd1903ca9bJerry Lee result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, 718b3b31174c61e38a970b956cb50cb66cd1903ca9bJerry Lee (uint64_t)(mBuff+buffer_size)); 719aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 720aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get memory dump request; result = %d", result); 721aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 722aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 723865ee9aa73c86404aa1ec3895a0a828a2b888ec5xinhe 724aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 725aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuffSize += buffer_size; 726aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 727aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = requestResponse(request); 728aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 729aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 730aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to register get momory dump response; result = %d", result); 731aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 732aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 733aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("dump event missing dump length attribute"); 734aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 735aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 736aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 737aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_OK; 738aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 739aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee}; 740aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 741aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface, 742aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_alert_handler handler) 743aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 744aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_handle handle = getWifiHandle(iface); 74556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Alerthandler start, handle = %p", handle); 74656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 747aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler); 7486af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 7496af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 7506af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 7516af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 7526af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 7536af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 7546af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 7556af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 7566af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_unregister_cmd(handle, id); 7576af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 75856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return result; 75956deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee } 7606af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 761aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 762aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 76356deba26a624507fc2e0e6b134f8bd88d091a141Jerry Leewifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface) 76456deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee{ 76556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee wifi_handle handle = getWifiHandle(iface); 76656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle); 76756deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 76856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee if (id == -1) { 76956deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee wifi_alert_handler handler; 77056deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee memset(&handler, 0, sizeof(handler)); 77156deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 77256deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler); 7736af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 77456deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee cmd->cancel(); 77556deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee cmd->releaseRef(); 77656deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return WIFI_SUCCESS; 77756deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee } 77856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee 77956deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee return wifi_cancel_cmd(id, iface); 78056deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee} 781aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 782aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/////////////////////////////////////////////////////////////////////////////// 783aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leeclass MemoryDumpCommand: public WifiCommand 784aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 785aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_firmware_memory_dump_handler mHandler; 786aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int mBuffSize; 787aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee char *mBuff; 788aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 789aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leepublic: 790aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler) 791d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("MemoryDumpCommand", iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL) 792aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee { } 793aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 794aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int start() { 795aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("Start memory dump command"); 796aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee WifiRequest request(familyId(), ifaceId()); 797aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 798aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result = request.create(GOOGLE_OUI, LOGGER_TRIGGER_MEM_DUMP); 799aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 800aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create trigger fw memory dump request; result = %d", result); 801aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 802aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 803aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 804aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = requestResponse(request); 805aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 806aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to register trigger memory dump response; result = %d", result); 807aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 808aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 809aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 810aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 811aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleResponse(WifiEvent& reply) { 812aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("In MemoryDumpCommand::handleResponse"); 813aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 814aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (reply.get_cmd() != NL80211_CMD_VENDOR) { 815aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 816aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 817aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 818aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 819aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 820aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int len = reply.get_vendor_data_len(); 821aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 822aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGD("len = %d", len); 823aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (vendor_data == NULL || len == 0) { 824aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("no vendor data in memory dump response; ignoring it"); 825aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 826aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 827aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 828aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 829aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) { 830aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuffSize = it.get_u32(); 831aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 832aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mBuff) 833aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee free(mBuff); 834aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuff = (char *)malloc(mBuffSize); 835aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (!mBuff) { 836aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Buffer allocation failed"); 837aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 838aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 839aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee WifiRequest request(familyId(), ifaceId()); 840aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP); 841aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 842aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to create get memory dump request; result = %d", result); 843aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee free(mBuff); 844aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 845aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 846aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 847aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 848aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize); 849aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 850aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get memory dump request; result = %d", result); 851aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 852aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 853b3b31174c61e38a970b956cb50cb66cd1903ca9bJerry Lee 854b3b31174c61e38a970b956cb50cb66cd1903ca9bJerry Lee result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff); 855aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 856aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to put get memory dump request; result = %d", result); 857aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return result; 858aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 859aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee request.attr_end(data); 860aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 861aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee result = requestResponse(request); 862aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (result != WIFI_SUCCESS) { 863aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGE("Failed to register get momory dump response; result = %d", result); 864aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 865aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) { 866aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGI("Initiating memory dump callback"); 867aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mHandler.on_firmware_memory_dump) { 868aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize); 869aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 870aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee if (mBuff) { 871aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee free(mBuff); 872aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee mBuff = NULL; 873aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 874aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } else { 875aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee ALOGW("Ignoring invalid attribute type = %d, size = %d", 876aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee it.get_type(), it.get_len()); 877aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 878aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 879aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_OK; 880aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 881aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 882aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee virtual int handleEvent(WifiEvent& event) { 883aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee /* NO events! */ 884aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee return NL_SKIP; 885aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee } 886aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee}; 887aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 888aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee/* API to collect a firmware memory dump for a given iface */ 889aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Leewifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface, 890aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee wifi_firmware_memory_dump_handler handler) 891aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee{ 892aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler); 8936af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 8946af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 8956af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 8966af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 897aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee} 898aa306e5f46b3e0e72d7917760b8af6aaebc35b1eJerry Lee 8997e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmaclass PacketFateCommand: public WifiCommand 9007e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma{ 9017e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma void *mReportBufs; 9027e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t mNoReqFates; 9037e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t *mNoProvidedFates; 9047e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PktFateReqType mReqType; 9057e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9067e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmapublic: 9077e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand(wifi_interface_handle handle) 9087e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START) 9097e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma { } 9107e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9117e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs, 9127e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t n_requested_fates, size_t *n_provided_fates) 9137e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs), 9147e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates), 9157e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma mReqType(TX_PACKET_FATE) 9167e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma { } 9177e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9187e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs, 9197e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t n_requested_fates, size_t *n_provided_fates) 9207e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs), 9217e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates), 9227e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma mReqType(RX_PACKET_FATE) 9237e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma { } 9247e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9257e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int createRequest(WifiRequest& request) { 9267e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (mReqType == TX_PACKET_FATE) { 9277e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGD("%s Get Tx packet fate request\n", __FUNCTION__); 9287e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return createTxPktFateRequest(request); 9297e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else if (mReqType == RX_PACKET_FATE) { 9307e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGD("%s Get Rx packet fate request\n", __FUNCTION__); 9317e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return createRxPktFateRequest(request); 9327e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else if (mReqType == PACKET_MONITOR_START) { 9337e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGD("%s Monitor packet fate request\n", __FUNCTION__); 9347e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return createMonitorPktFateRequest(request); 9357e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else { 9367e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGE("%s Unknown packet fate request\n", __FUNCTION__); 9377e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return WIFI_ERROR_NOT_SUPPORTED; 9387e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9397e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return WIFI_SUCCESS; 9407e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9417e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9427e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int createMonitorPktFateRequest(WifiRequest& request) { 9437e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING); 9447e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9457e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9467e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9477e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9487e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 9497e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma request.attr_end(data); 9507e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9517e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9527e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9537e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int createTxPktFateRequest(WifiRequest& request) { 9547e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES); 9557e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9567e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9577e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9587e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9597e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report))); 9607e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 9617e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates); 9627e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9637e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9647e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9657e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs); 9667e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9677e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9687e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9697e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma request.attr_end(data); 9707e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9717e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9727e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9737e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int createRxPktFateRequest(WifiRequest& request) { 9747e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES); 9757e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9767e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9777e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9787e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9797e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report))); 9807e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 9817e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates); 9827e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9837e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9847e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9857e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs); 9867e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9877e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9887e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9897e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma request.attr_end(data); 9907e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 9917e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 9927e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9937e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int start() { 9947e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGD("Start get packet fate command\n"); 9957e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma WifiRequest request(familyId(), ifaceId()); 9967e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 9977e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int result = createRequest(request); 9987e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result < 0) { 9997e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGE("Failed to create get pkt fate request; result = %d\n", result); 10007e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 10017e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10027e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10037e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma result = requestResponse(request); 10047e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (result != WIFI_SUCCESS) { 10057e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGE("Failed to register get pkt fate response; result = %d\n", result); 10067e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10077e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return result; 10087e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10097e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10107e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int handleResponse(WifiEvent& reply) { 10117e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGD("In GetPktFateCommand::handleResponse\n"); 10127e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10137e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (reply.get_cmd() != NL80211_CMD_VENDOR) { 10147e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGI("Ignoring reply with cmd = %d", reply.get_cmd()); 10157e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_SKIP; 10167e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10177e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10187e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int id = reply.get_vendor_id(); 10197e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int subcmd = reply.get_vendor_subcmd(); 10207e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 10217e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int len = reply.get_vendor_data_len(); 10227e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10237e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 10247e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10257e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (mReqType == TX_PACKET_FATE) { 10266af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma ALOGI("Response recieved for get TX pkt fate command\n"); 10277e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else if (mReqType == RX_PACKET_FATE) { 10286af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma ALOGI("Response recieved for get RX pkt fate command\n"); 10297e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else if (mReqType == PACKET_MONITOR_START) { 10306af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma ALOGI("Response recieved for monitor pkt fate command\n"); 10317e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_OK; 10327e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else { 10336af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma ALOGE("Response recieved for unknown pkt fate command\n"); 10347e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_SKIP; 10357e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10367e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10377e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (vendor_data == NULL || len == 0) { 10387e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n"); 10397e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_SKIP; 10407e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10417e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10427e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 10437e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) { 10447e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma *mNoProvidedFates = it.get_u32(); 10457e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGI("No: of pkt fates provided is %d\n", *mNoProvidedFates); 10467e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } else { 10477e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma ALOGE("Ignoring invalid attribute type = %d, size = %d\n", 10487e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma it.get_type(), it.get_len()); 10497e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10507e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10517e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10527e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_OK; 10537e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10547e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10557e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma int handleEvent(WifiEvent& event) { 10567e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma /* NO events to handle here! */ 10577e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma return NL_SKIP; 10587e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma } 10597e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma}; 10607e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10617e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmawifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle) 10627e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma{ 10637e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand *cmd = new PacketFateCommand(handle); 10646af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 10656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 10666af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 10676af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 10687e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma} 10697e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10707e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmawifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle, 10717e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma wifi_tx_report *tx_report_bufs, size_t n_requested_fates, 10727e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t *n_provided_fates) 10737e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma{ 10747e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs, 10756af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma n_requested_fates, n_provided_fates); 10766af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 10776af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 10786af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 10796af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 10807e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma} 10817e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma 10827e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharmawifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle, 10837e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma wifi_rx_report *rx_report_bufs, size_t n_requested_fates, 10847e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma size_t *n_provided_fates) 10857e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma{ 10867e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs, 10876af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma n_requested_fates, n_provided_fates); 10886af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 10896af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 10906af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 10916af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 10927e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma} 1093