[9610] wlbt: Move around code to fix compilation error (Android P)
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / wifi_logger.cpp
CommitLineData
cdc775c7
HG
1#include <stdint.h>\r
2#include <fcntl.h>\r
3#include <sys/socket.h>\r
4#include <netlink/genl/genl.h>\r
5#include <netlink/genl/family.h>\r
6#include <netlink/genl/ctrl.h>\r
7#include <linux/rtnetlink.h>\r
8#include <netpacket/packet.h>\r
9#include <linux/filter.h>\r
10#include <linux/errqueue.h>\r
11\r
12#include <linux/pkt_sched.h>\r
13#include <netlink/object-api.h>\r
14#include <netlink/netlink.h>\r
15#include <netlink/socket.h>\r
16#include <netlink-private/object-api.h>\r
17#include <netlink-private/types.h>\r
18\r
19#include "nl80211_copy.h"\r
20#include "sync.h"\r
21\r
22#define LOG_TAG "WifiHAL"\r
23\r
24#include <utils/Log.h>\r
25\r
26#include "wifi_hal.h"\r
27#include "common.h"\r
28#include "cpp_bindings.h"\r
29\r
73e453d8 30/* using namespace android; */\r
cdc775c7
HG
31\r
32typedef enum {\r
33 ENHANCE_LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,\r
34 ENHANCE_LOGGER_TRIGGER_FW_MEM_DUMP,\r
35 ENHANCE_LOGGER_GET_FW_MEM_DUMP,\r
36 ENHANCE_LOGGER_GET_VER,\r
37 ENHANCE_LOGGER_GET_RING_STATUS,\r
38 ENHANCE_LOGGER_GET_RING_DATA,\r
39 ENHANCE_LOGGER_GET_FEATURE,\r
40 ENHANCE_LOGGER_RESET_LOGGING,\r
41 ENHANCE_LOGGER_TRIGGER_DRIVER_MEM_DUMP,\r
42 ENHANCE_LOGGER_GET_DRIVER_MEM_DUMP,\r
43 ENHANCE_LOGGER_START_PKT_FATE_MONITORING,\r
44 ENHANCE_LOGGER_GET_TX_PKT_FATES,\r
45 ENHANCE_LOGGER_GET_RX_PKT_FATES,\r
46 ENHANCE_LOGGER_GET_WAKE_REASON_STATS,\r
47} DEBUG_SUB_COMMAND;\r
48\r
49typedef enum {\r
50 ENHANCE_LOGGER_ATTRIBUTE_DRIVER_VER,\r
51 ENHANCE_LOGGER_ATTRIBUTE_FW_VER,\r
52 ENHANCE_LOGGER_ATTRIBUTE_RING_ID,\r
53 ENHANCE_LOGGER_ATTRIBUTE_RING_NAME,\r
54 ENHANCE_LOGGER_ATTRIBUTE_RING_FLAGS,\r
55 ENHANCE_LOGGER_ATTRIBUTE_LOG_LEVEL,\r
56 ENHANCE_LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,\r
57 ENHANCE_LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,\r
58 ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN,\r
59 ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA,\r
60 // LOGGER_ATTRIBUTE_FW_ERR_CODE,\r
61 ENHANCE_LOGGER_ATTRIBUTE_RING_DATA,\r
62 ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS,\r
63 ENHANCE_LOGGER_ATTRIBUTE_RING_NUM,\r
64 ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,\r
65 ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,\r
66 ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM,\r
67 ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_DATA,\r
68 //Attributes for data used by wake stats subcmd.\r
69 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_INVALID = 0,\r
70 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_CMD_EVENT_WAKE,\r
71 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR,\r
72 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ,\r
73 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE,\r
74 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR,\r
75 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ,\r
76 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_RX_DATA_WAKE,\r
77 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_UNICAST_CNT,\r
78 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_MULTICAST_CNT,\r
79 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_BROADCAST_CNT,\r
80 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP_PKT,\r
81 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_PKT,\r
82 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RA,\r
83 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NA,\r
84 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NS,\r
85 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP4_RX_MULTICAST_CNT,\r
86 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RX_MULTICAST_CNT,\r
87 ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT,\r
88} ENHANCE_LOGGER_ATTRIBUTE;\r
89\r
90typedef enum {\r
91 DEBUG_OFF = 0,\r
92 DEBUG_NORMAL,\r
93 DEBUG_VERBOSE,\r
94 DEBUG_VERY,\r
95 DEBUG_VERY_VERY,\r
96} ENHANCE_LOGGER_LEVEL;\r
97\r
98typedef enum {\r
99 GET_FW_VER,\r
100 GET_DRV_VER,\r
101 GET_RING_DATA,\r
102 GET_RING_STATUS,\r
103 GET_FEATURE,\r
104 START_RING_LOG,\r
105 GET_FW_DUMP,\r
106 GET_DRIVER_DUMP,\r
107} GetCmdType;\r
108\r
109typedef enum {\r
110 PACKET_MONITOR_START,\r
111 TX_PACKET_FATE,\r
112 RX_PACKET_FATE,\r
113} PktFateReqType;\r
114\r
115class DebugCommand : public WifiCommand\r
116{\r
49d0342d 117 char *mBuff = NULL;\r
118 int *mBuffSize = NULL;\r
119 u32 *mNumRings = NULL;\r
120 wifi_ring_buffer_status *mStatus = NULL;\r
121 unsigned int *mSupport = NULL;\r
122 u32 mVerboseLevel = 0;\r
123 u32 mFlags = 0;\r
124 u32 mMaxIntervalSec = 0;\r
125 u32 mMinDataSize = 0;\r
126 char *mRingName = NULL;\r
cdc775c7
HG
127 GetCmdType mType;\r
128\r
129public:\r
130\r
131 // constructor for get version\r
132 DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size,\r
133 GetCmdType cmdType)\r
134 : WifiCommand(iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType\r
135 (cmdType)\r
136 {\r
137 memset(mBuff, 0, *mBuffSize);\r
138 }\r
139\r
140 // constructor for ring data\r
141 DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType)\r
142 : WifiCommand(iface, 0), mRingName(ring_name), mType(cmdType)\r
143 { }\r
144\r
145 // constructor for ring status\r
146 DebugCommand(wifi_interface_handle iface, u32 *num_rings,\r
147 wifi_ring_buffer_status *status, GetCmdType cmdType)\r
148 : WifiCommand(iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType)\r
149 {\r
150 memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings));\r
151 }\r
152\r
153 // constructor for feature set\r
154 DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType)\r
155 : WifiCommand(iface, 0), mSupport(support), mType(cmdType)\r
156 { }\r
157\r
158 // constructor for ring params\r
159 DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags,\r
160 u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType)\r
161 : WifiCommand(iface, 0), mVerboseLevel(verbose_level), mFlags(flags),\r
162 mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size),\r
163 mRingName(ring_name), mType(cmdType)\r
164 { }\r
165\r
166 int createRingRequest(WifiRequest& request) {\r
167 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_START_LOGGING);\r
168 if (result != WIFI_SUCCESS) {\r
169 ALOGE("Failed to create start ring logger request; result = %d", result);\r
170 return result;\r
171 }\r
172\r
173 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
174\r
175 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel);\r
176 if (result != WIFI_SUCCESS) {\r
177 ALOGE("Failed to put log level; result = %d", result);\r
178 return result;\r
179 }\r
180 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_RING_FLAGS, mFlags);\r
181 if (result != WIFI_SUCCESS) {\r
182 ALOGE("Failed to put ring flags; result = %d", result);\r
183 return result;\r
184 }\r
185 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec);\r
186 if (result != WIFI_SUCCESS) {\r
187 ALOGE("Failed to put log time interval; result = %d", result);\r
188 return result;\r
189 }\r
190 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize);\r
191 if (result != WIFI_SUCCESS) {\r
192 ALOGE("Failed to put min data size; result = %d", result);\r
193 return result;\r
194 }\r
195 result = request.put_string(ENHANCE_LOGGER_ATTRIBUTE_RING_NAME, mRingName);\r
196 if (result != WIFI_SUCCESS) {\r
197 ALOGE("Failed to put ringbuffer name; result = %d", result);\r
198 return result;\r
199 }\r
200 request.attr_end(data);\r
201\r
202 return WIFI_SUCCESS;\r
203 }\r
204\r
205 int createRequest(WifiRequest &request) {\r
206 int result;\r
207\r
208 switch (mType) {\r
209 case GET_FW_VER:\r
210 {\r
211 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_VER);\r
212 if (result != WIFI_SUCCESS) {\r
213 ALOGE("Failed to create get fw version request; result = %d", result);\r
214 return result;\r
215 }\r
216\r
217 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
218\r
219 // Driver expecting only attribute type, passing mbuff as data with\r
220 // length 0 to avoid undefined state\r
221 result = request.put(ENHANCE_LOGGER_ATTRIBUTE_FW_VER, mBuff, 0);\r
222 if (result != WIFI_SUCCESS) {\r
223 ALOGE("Failed to put get fw version request; result = %d", result);\r
224 return result;\r
225 }\r
226 request.attr_end(data);\r
227 break;\r
228 }\r
229\r
230 case GET_DRV_VER:\r
231 {\r
232 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_VER);\r
233 if (result != WIFI_SUCCESS) {\r
234 ALOGE("Failed to create get drv version request; result = %d", result);\r
235 return result;\r
236 }\r
237\r
238 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
239\r
240 // Driver expecting only attribute type, passing mbuff as data with\r
241 // length 0 to avoid undefined state\r
242 result = request.put(ENHANCE_LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0);\r
243\r
244 if (result != WIFI_SUCCESS) {\r
245 ALOGE("Failed to put get drv version request; result = %d", result);\r
246 return result;\r
247 }\r
248 request.attr_end(data);\r
249 break;\r
250 }\r
251\r
252 case GET_RING_DATA:\r
253 {\r
254 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_RING_DATA);\r
255 if (result != WIFI_SUCCESS) {\r
256 ALOGE("Failed to create get ring data request; result = %d", result);\r
257 return result;\r
258 }\r
259\r
260 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
261 result = request.put_string(ENHANCE_LOGGER_ATTRIBUTE_RING_NAME, mRingName);\r
262 if (result != WIFI_SUCCESS) {\r
263 ALOGE("Failed to put ring data request; result = %d", result);\r
264 return result;\r
265 }\r
266 request.attr_end(data);\r
267 break;\r
268 }\r
269\r
270 case GET_RING_STATUS:\r
271 {\r
272 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_RING_STATUS);\r
273 if (result != WIFI_SUCCESS) {\r
274 ALOGE("Failed to create get ring status request; result = %d", result);\r
275 return result;\r
276 }\r
277 break;\r
278 }\r
279\r
280 case GET_FEATURE:\r
281 {\r
282 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_FEATURE);\r
283 if (result != WIFI_SUCCESS) {\r
284 ALOGE("Failed to create get feature request; result = %d", result);\r
285 return result;\r
286 }\r
287 break;\r
288 }\r
289\r
290 case START_RING_LOG:\r
291 result = createRingRequest(request);\r
292 break;\r
293\r
294 default:\r
295 ALOGE("Unknown Debug command");\r
296 result = WIFI_ERROR_UNKNOWN;\r
297 }\r
298 return result;\r
299 }\r
300\r
301 int start() {\r
302 // ALOGD("Start debug command");\r
303 WifiRequest request(familyId(), ifaceId());\r
304 int result = createRequest(request);\r
305 if (result != WIFI_SUCCESS) {\r
306 ALOGE("Failed to create debug request; result = %d", result);\r
307 return result;\r
308 }\r
309\r
310 result = requestResponse(request);\r
311 if (result != WIFI_SUCCESS) {\r
312 ALOGE("Failed to register debug response; result = %d", result);\r
313 }\r
314 return result;\r
315 }\r
316\r
317 virtual int handleResponse(WifiEvent& reply) {\r
318 ALOGD("In DebugCommand::handleResponse");\r
319\r
320 if (reply.get_cmd() != NL80211_CMD_VENDOR) {\r
321 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());\r
322 return NL_SKIP;\r
323 }\r
324\r
325 switch (mType) {\r
326 case GET_DRV_VER:\r
327 case GET_FW_VER:\r
328 {\r
329 void *data = reply.get_vendor_data();\r
330 int len = reply.get_vendor_data_len();\r
331\r
332 ALOGD("len = %d, expected len = %d", len, *mBuffSize);\r
333 memcpy(mBuff, data, min(len, *mBuffSize));\r
334 if (*mBuffSize < len)\r
335 return NL_SKIP;\r
336 *mBuffSize = len;\r
337 break;\r
338 }\r
339\r
340 case START_RING_LOG:\r
341 case GET_RING_DATA:\r
342 break;\r
343\r
344 case GET_RING_STATUS:\r
345 {\r
346 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
347 int len = reply.get_vendor_data_len();\r
348 wifi_ring_buffer_status *status(mStatus);\r
349\r
350 if (vendor_data == NULL || len == 0) {\r
351 ALOGE("No Debug data found");\r
352 return NL_SKIP;\r
353 }\r
354\r
355 nl_iterator it(vendor_data);\r
356 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_NUM) {\r
357 unsigned int num_rings = it.get_u32();\r
358 if (*mNumRings < num_rings) {\r
359 ALOGE("Not enough status buffers provided, available: %d required: %d",\r
360 *mNumRings, num_rings);\r
361 } else {\r
362 *mNumRings = num_rings;\r
363 }\r
364 } else {\r
365 ALOGE("Unknown attribute: %d expecting %d",\r
366 it.get_type(), ENHANCE_LOGGER_ATTRIBUTE_RING_NUM);\r
367 return NL_SKIP;\r
368 }\r
369\r
370 it.next();\r
371 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS) {\r
372 memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status) * (*mNumRings));\r
373 } else {\r
374 ALOGW("Ignoring invalid attribute type = %d, size = %d",\r
375 it.get_type(), it.get_len());\r
376 }\r
377 break;\r
378 }\r
379\r
380 case GET_FEATURE:\r
381 {\r
382 void *data = reply.get_vendor_data();\r
383 int len = reply.get_vendor_data_len();\r
384\r
385 ALOGD("len = %d, expected len = %d", len, sizeof(unsigned int));\r
386 memcpy(mSupport, data, sizeof(unsigned int));\r
387 break;\r
388 }\r
389\r
390 default:\r
391 ALOGW("Unknown Debug command");\r
392 }\r
393 return NL_OK;\r
394 }\r
395\r
396 virtual int handleEvent(WifiEvent& event) {\r
397 /* NO events! */\r
398 return NL_SKIP;\r
399 }\r
400};\r
401\r
402/* API to get supportable feature */\r
403wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,\r
404 unsigned int *support)\r
405{\r
406 if (support) {\r
407 DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE);\r
408 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
409 wifi_error result = (wifi_error)cmd->start();\r
410 cmd->releaseRef();\r
411 return result;\r
412 } else {\r
413 ALOGE("Get support buffer NULL");\r
414 return WIFI_ERROR_INVALID_ARGS;\r
415 }\r
416}\r
417\r
418/* API to get the status of all ring buffers supported by driver */\r
419wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,\r
420 u32 *num_rings, wifi_ring_buffer_status *status)\r
421{\r
422 if (status && num_rings) {\r
423 DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS);\r
424 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
425 wifi_error result = (wifi_error)cmd->start();\r
426 cmd->releaseRef();\r
427 return result;\r
428 } else {\r
429 ALOGE("Ring status buffer NULL");\r
430 return WIFI_ERROR_INVALID_ARGS;\r
431 }\r
432}\r
433\r
434/* API to collect driver records */\r
435wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name)\r
436{\r
437 DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA);\r
438 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
439 wifi_error result = (wifi_error)cmd->start();\r
440 cmd->releaseRef();\r
441 return result;\r
442}\r
443\r
444wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level,\r
445 u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name)\r
446{\r
447 if (ring_name) {\r
448 DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec,\r
449 min_data_size, ring_name, START_RING_LOG);\r
450 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
451 wifi_error result = (wifi_error)cmd->start();\r
452 cmd->releaseRef();\r
453 return result;\r
454 } else {\r
455 ALOGE("Ring name NULL");\r
456 return WIFI_ERROR_INVALID_ARGS;\r
457 }\r
458}\r
459\r
460/* API to collect a firmware version string */\r
461wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer,\r
462 int buffer_size)\r
463{\r
464 if (buffer && (buffer_size > 0)) {\r
465 DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER);\r
466 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
467 wifi_error result = (wifi_error)cmd->start();\r
468 cmd->releaseRef();\r
469 return result;\r
470 } else {\r
471 ALOGE("FW version buffer NULL");\r
472 return WIFI_ERROR_INVALID_ARGS;\r
473 }\r
474}\r
475\r
476/* API to collect a driver version string */\r
477wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size)\r
478{\r
479 if (buffer && (buffer_size > 0)) {\r
480 DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER);\r
481 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
482 wifi_error result = (wifi_error)cmd->start();\r
483 cmd->releaseRef();\r
484 return result;\r
485 } else {\r
486 ALOGE("Driver version buffer NULL");\r
487 return WIFI_ERROR_INVALID_ARGS;\r
488 }\r
489}\r
490\r
491\r
492///////////////////////////////////////////////////////////////////////////////\r
493class SetLogHandler : public WifiCommand\r
494{\r
495 wifi_ring_buffer_data_handler mHandler;\r
496\r
497public:\r
498 SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler)\r
499 : WifiCommand(iface, id), mHandler(handler)\r
500 { }\r
501\r
502 int start() {\r
503 ALOGV("Register loghandler");\r
504 registerVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_RING_EVENT);\r
505 return WIFI_SUCCESS;\r
506 }\r
507\r
508 virtual int cancel() {\r
509 /* Send a command to driver to stop generating logging events */\r
510 ALOGV("Clear loghandler");\r
511\r
512 /* unregister event handler */\r
513 unregisterVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_RING_EVENT);\r
514\r
515 WifiRequest request(familyId(), ifaceId());\r
516 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_RESET_LOGGING);\r
517 if (result != WIFI_SUCCESS) {\r
518 ALOGE("failed to create reset request; result = %d", result);\r
519 return result;\r
520 }\r
521\r
522 result = requestResponse(request);\r
523 if (result != WIFI_SUCCESS) {\r
524 ALOGE("failed to request reset; result = %d", result);\r
525 return result;\r
526 }\r
527\r
528 ALOGD("Success to clear loghandler");\r
529 return WIFI_SUCCESS;\r
530 }\r
531\r
532 virtual int handleEvent(WifiEvent& event) {\r
533 char *buffer = NULL;\r
534 int buffer_size = 0;\r
535\r
536 // ALOGD("In SetLogHandler::handleEvent");\r
537 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
538 int len = event.get_vendor_data_len();\r
539 int event_id = event.get_vendor_subcmd();\r
540 // ALOGI("Got Logger event: %d", event_id);\r
541\r
542 if (vendor_data == NULL || len == 0) {\r
543 ALOGE("No Debug data found");\r
544 return NL_SKIP;\r
545 }\r
546\r
547 if(event_id == ENHANCE_LOGGER_RING_EVENT) {\r
548 wifi_ring_buffer_status status;\r
549 memset(&status, 0, sizeof(status));\r
550\r
551 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
552 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS) {\r
553 memcpy(&status, it.get_data(), sizeof(status));\r
554 } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_DATA) {\r
555 buffer_size = it.get_len();\r
556 buffer = (char *)it.get_data();\r
557 } else {\r
558 ALOGW("Ignoring invalid attribute type = %d, size = %d",\r
559 it.get_type(), it.get_len());\r
560 }\r
561 }\r
562\r
563 // ALOGI("Retrieved Debug data");\r
564 if (mHandler.on_ring_buffer_data) {\r
565 (*mHandler.on_ring_buffer_data)((char *)status.name, buffer, buffer_size,\r
566 &status);\r
567 }\r
568 } else {\r
569 ALOGE("Unknown Event");\r
570 return NL_SKIP;\r
571 }\r
572 return NL_OK;\r
573 }\r
574};\r
575\r
576wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,\r
577 wifi_ring_buffer_data_handler handler)\r
578{\r
579 wifi_handle handle = getWifiHandle(iface);\r
580 ALOGV("Loghandler start, handle = %p", handle);\r
581\r
582 SetLogHandler *cmd = new SetLogHandler(iface, id, handler);\r
583 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
584 wifi_error result = wifi_register_cmd(handle, id, cmd);\r
585 if (result != WIFI_SUCCESS) {\r
586 cmd->releaseRef();\r
587 return result;\r
588 }\r
589 result = (wifi_error)cmd->start();\r
590 if (result != WIFI_SUCCESS) {\r
591 wifi_unregister_cmd(handle, id);\r
592 cmd->releaseRef();\r
593 return result;\r
594 }\r
595 return result;\r
596}\r
597\r
598wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface)\r
599{\r
600 wifi_handle handle = getWifiHandle(iface);\r
601 ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle);\r
602\r
603 if (id == -1) {\r
604 wifi_ring_buffer_data_handler handler;\r
605 memset(&handler, 0, sizeof(handler));\r
606\r
607 SetLogHandler *cmd = new SetLogHandler(iface, id, handler);\r
608 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
609 cmd->cancel();\r
610 cmd->releaseRef();\r
611 return WIFI_SUCCESS;\r
612 }\r
613\r
614 return wifi_cancel_cmd(id, iface);\r
615}\r
616\r
617///////////////////////////////////////////////////////////////////////////////\r
618class SetAlertHandler : public WifiCommand\r
619{\r
620 wifi_alert_handler mHandler;\r
621 int mBuffSize;\r
622 char *mBuff;\r
623 int mErrCode;\r
624\r
625public:\r
626 SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler)\r
627 : WifiCommand(iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL),\r
628 mErrCode(0)\r
629 { }\r
630\r
631 int start() {\r
632 ALOGV("Start Alerting");\r
633 registerVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_MEM_DUMP_EVENT);\r
634 return WIFI_SUCCESS;\r
635 }\r
636\r
637 virtual int cancel() {\r
638 ALOGV("Clear alerthandler");\r
639\r
640 /* unregister alert handler */\r
641 unregisterVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_MEM_DUMP_EVENT);\r
642 wifi_unregister_cmd(wifiHandle(), id());\r
643 ALOGD("Success to clear alerthandler");\r
644 return WIFI_SUCCESS;\r
645 }\r
646\r
647 virtual int handleResponse(WifiEvent& reply) {\r
648 ALOGD("In SetAlertHandler::handleResponse");\r
649\r
650 if (reply.get_cmd() != NL80211_CMD_VENDOR) {\r
651 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());\r
652 return NL_SKIP;\r
653 }\r
654\r
655 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
656 int len = reply.get_vendor_data_len();\r
657\r
658 ALOGD("len = %d", len);\r
659 if (vendor_data == NULL || len == 0) {\r
660 ALOGE("no vendor data in memory dump response; ignoring it");\r
661 return NL_SKIP;\r
662 }\r
663\r
664 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
665 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA) {\r
666 ALOGI("Initiating alert callback");\r
667 if (mHandler.on_alert) {\r
668 (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode);\r
669 }\r
670 if (mBuff) {\r
671 free(mBuff);\r
672 mBuff = NULL;\r
673 }\r
674 }\r
675 }\r
676 return NL_OK;\r
677 }\r
678\r
679 virtual int handleEvent(WifiEvent& event) {\r
680 wifi_ring_buffer_id ring_id;\r
681 char *buffer = NULL;\r
682 int buffer_size = 0;\r
683\r
684\r
685 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
686 int len = event.get_vendor_data_len();\r
687 int event_id = event.get_vendor_subcmd();\r
688 ALOGI("Got event: %d", event_id);\r
689\r
690 if (vendor_data == NULL || len == 0) {\r
691 ALOGE("No Debug data found");\r
692 return NL_SKIP;\r
693 }\r
694\r
695 if (event_id == ENHANCE_LOGGER_MEM_DUMP_EVENT) {\r
696 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
697 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN) {\r
698 mBuffSize = it.get_u32();\r
699 } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_DATA) {\r
700 buffer_size = it.get_len();\r
701 buffer = (char *)it.get_data();\r
702 /*\r
703 } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_ERR_CODE) {\r
704 mErrCode = it.get_u32();\r
705 */\r
706 } else {\r
707 ALOGW("Ignoring invalid attribute type = %d, size = %d",\r
708 it.get_type(), it.get_len());\r
709 }\r
710 }\r
711 if (mBuffSize) {\r
712 ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size);\r
713 if (mBuff) free(mBuff);\r
714 mBuff = (char *)malloc(mBuffSize + buffer_size);\r
715 if (!mBuff) {\r
716 ALOGE("Buffer allocation failed");\r
717 return NL_SKIP;\r
718 }\r
719 memcpy(mBuff, buffer, buffer_size);\r
720\r
721 WifiRequest request(familyId(), ifaceId());\r
722 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_MEM_DUMP_EVENT);\r
723 if (result != WIFI_SUCCESS) {\r
724 ALOGE("Failed to create get memory dump request; result = %d", result);\r
725 free(mBuff);\r
726 return NL_SKIP;\r
727 }\r
728 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
729 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);\r
730 if (result != WIFI_SUCCESS) {\r
731 ALOGE("Failed to put get memory dump request; result = %d", result);\r
732 return result;\r
733 }\r
734\r
735 result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA,\r
736 (uint64_t)(mBuff+buffer_size));\r
737 if (result != WIFI_SUCCESS) {\r
738 ALOGE("Failed to put get memory dump request; result = %d", result);\r
739 return result;\r
740 }\r
741\r
742 request.attr_end(data);\r
743 mBuffSize += buffer_size;\r
744\r
745 result = requestResponse(request);\r
746\r
747 if (result != WIFI_SUCCESS) {\r
748 ALOGE("Failed to register get momory dump response; result = %d", result);\r
749 }\r
750 } else {\r
751 ALOGE("dump event missing dump length attribute");\r
752 return NL_SKIP;\r
753 }\r
754 }\r
755 return NL_OK;\r
756 }\r
757};\r
758\r
759wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,\r
760 wifi_alert_handler handler)\r
761{\r
762 wifi_handle handle = getWifiHandle(iface);\r
763 ALOGV("Alerthandler start, handle = %p", handle);\r
764\r
765 SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);\r
766 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
767 wifi_error result = wifi_register_cmd(handle, id, cmd);\r
768 if (result != WIFI_SUCCESS) {\r
769 cmd->releaseRef();\r
770 return result;\r
771 }\r
772 result = (wifi_error)cmd->start();\r
773 if (result != WIFI_SUCCESS) {\r
774 wifi_unregister_cmd(handle, id);\r
775 cmd->releaseRef();\r
776 return result;\r
777 }\r
778 return result;\r
779}\r
780\r
781wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface)\r
782{\r
783 wifi_handle handle = getWifiHandle(iface);\r
784 ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle);\r
785\r
786 if (id == -1) {\r
787 wifi_alert_handler handler;\r
788 memset(&handler, 0, sizeof(handler));\r
789\r
790 SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);\r
791 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
792 cmd->cancel();\r
793 cmd->releaseRef();\r
794 return WIFI_SUCCESS;\r
795 }\r
796\r
797 return wifi_cancel_cmd(id, iface);\r
798}\r
799\r
800\r
801class PacketFateCommand: public WifiCommand\r
802{\r
49d0342d 803 void *mReportBufs = NULL;\r
804 size_t mNoReqFates = 0;\r
805 size_t *mNoProvidedFates = NULL;\r
cdc775c7
HG
806 PktFateReqType mReqType;\r
807\r
808public:\r
809 PacketFateCommand(wifi_interface_handle handle)\r
810 : WifiCommand(handle, 0), mReqType(PACKET_MONITOR_START)\r
811 { }\r
812\r
813 PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs,\r
814 size_t n_requested_fates, size_t *n_provided_fates)\r
815 : WifiCommand(handle, 0), mReportBufs(tx_report_bufs),\r
816 mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),\r
817 mReqType(TX_PACKET_FATE)\r
818 { }\r
819\r
820 PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs,\r
821 size_t n_requested_fates, size_t *n_provided_fates)\r
822 : WifiCommand(handle, 0), mReportBufs(rx_report_bufs),\r
823 mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),\r
824 mReqType(RX_PACKET_FATE)\r
825 { }\r
826\r
827 int createRequest(WifiRequest& request) {\r
828 if (mReqType == TX_PACKET_FATE) {\r
829 ALOGD("%s Get Tx packet fate request\n", __FUNCTION__);\r
830 return createTxPktFateRequest(request);\r
831 } else if (mReqType == RX_PACKET_FATE) {\r
832 ALOGD("%s Get Rx packet fate request\n", __FUNCTION__);\r
833 return createRxPktFateRequest(request);\r
834 } else if (mReqType == PACKET_MONITOR_START) {\r
835 ALOGD("%s Monitor packet fate request\n", __FUNCTION__);\r
836 return createMonitorPktFateRequest(request);\r
837 } else {\r
838 ALOGE("%s Unknown packet fate request\n", __FUNCTION__);\r
839 return WIFI_ERROR_NOT_SUPPORTED;\r
840 }\r
841 return WIFI_SUCCESS;\r
842 }\r
843\r
844 int createMonitorPktFateRequest(WifiRequest& request) {\r
845 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_START_PKT_FATE_MONITORING);\r
846 if (result < 0) {\r
847 return result;\r
848 }\r
849\r
850 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
851 request.attr_end(data);\r
852 return result;\r
853 }\r
854\r
855 int createTxPktFateRequest(WifiRequest& request) {\r
856 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_TX_PKT_FATES);\r
857 if (result < 0) {\r
858 return result;\r
859 }\r
860\r
861 memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report)));\r
862 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
863 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);\r
864 if (result < 0) {\r
865 return result;\r
866 }\r
867 result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);\r
868 if (result < 0) {\r
869 return result;\r
870 }\r
871 request.attr_end(data);\r
872 return result;\r
873 }\r
874\r
875 int createRxPktFateRequest(WifiRequest& request) {\r
876 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_RX_PKT_FATES);\r
877 if (result < 0) {\r
878 return result;\r
879 }\r
880\r
881 memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report)));\r
882 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
883 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);\r
884 if (result < 0) {\r
885 return result;\r
886 }\r
887 result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);\r
888 if (result < 0) {\r
889 return result;\r
890 }\r
891 request.attr_end(data);\r
892 return result;\r
893 }\r
894\r
895 int start() {\r
896 ALOGD("Start get packet fate command\n");\r
897 WifiRequest request(familyId(), ifaceId());\r
898\r
899 int result = createRequest(request);\r
900 if (result < 0) {\r
901 ALOGE("Failed to create get pkt fate request; result = %d\n", result);\r
902 return result;\r
903 }\r
904\r
905 result = requestResponse(request);\r
906 if (result != WIFI_SUCCESS) {\r
907 ALOGE("Failed to register get pkt fate response; result = %d\n", result);\r
908 }\r
909 return result;\r
910 }\r
911\r
912 int handleResponse(WifiEvent& reply) {\r
913 ALOGD("In GetPktFateCommand::handleResponse\n");\r
914\r
915 if (reply.get_cmd() != NL80211_CMD_VENDOR) {\r
916 ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());\r
917 return NL_SKIP;\r
918 }\r
919\r
920 int id = reply.get_vendor_id();\r
921 int subcmd = reply.get_vendor_subcmd();\r
922 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
923 int len = reply.get_vendor_data_len();\r
924\r
925 ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);\r
926\r
927 if (mReqType == TX_PACKET_FATE) {\r
928 ALOGI("Response recieved for get TX pkt fate command\n");\r
929 } else if (mReqType == RX_PACKET_FATE) {\r
930 ALOGI("Response recieved for get RX pkt fate command\n");\r
931 } else if (mReqType == PACKET_MONITOR_START) {\r
932 ALOGI("Response recieved for monitor pkt fate command\n");\r
933 return NL_OK;\r
934 } else {\r
935 ALOGE("Response recieved for unknown pkt fate command\n");\r
936 return NL_SKIP;\r
937 }\r
938\r
939 if (vendor_data == NULL || len == 0) {\r
940 ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");\r
941 return NL_SKIP;\r
942 }\r
943\r
944 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
945 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM) {\r
946 *mNoProvidedFates = it.get_u32();\r
947 ALOGI("No: of pkt fates provided is %d\n", *mNoProvidedFates);\r
948 } else {\r
949 ALOGE("Ignoring invalid attribute type = %d, size = %d\n",\r
950 it.get_type(), it.get_len());\r
951 }\r
952 }\r
953\r
954 return NL_OK;\r
955 }\r
956\r
957 int handleEvent(WifiEvent& event) {\r
958 /* NO events to handle here! */\r
959 return NL_SKIP;\r
960 }\r
961};\r
962\r
963wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)\r
964{\r
965 PacketFateCommand *cmd = new PacketFateCommand(handle);\r
966 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
967 wifi_error result = (wifi_error)cmd->start();\r
968 cmd->releaseRef();\r
969 return result;\r
970}\r
971\r
972wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,\r
973 wifi_tx_report *tx_report_bufs, size_t n_requested_fates,\r
974 size_t *n_provided_fates)\r
975{\r
976 PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs,\r
977 n_requested_fates, n_provided_fates);\r
978 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
979 wifi_error result = (wifi_error)cmd->start();\r
980 cmd->releaseRef();\r
b562d5aa 981 memset(tx_report_bufs, 0, (n_requested_fates * sizeof(wifi_tx_report)));\r
cdc775c7
HG
982 return result;\r
983}\r
984\r
985wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,\r
986 wifi_rx_report *rx_report_bufs, size_t n_requested_fates,\r
987 size_t *n_provided_fates)\r
988{\r
989 PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs,\r
990 n_requested_fates, n_provided_fates);\r
991 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
992 wifi_error result = (wifi_error)cmd->start();\r
993 cmd->releaseRef();\r
b562d5aa 994 memset(rx_report_bufs, 0, (n_requested_fates * sizeof(wifi_rx_report)));\r
cdc775c7
HG
995 return result;\r
996}\r
997\r
998class MemoryDumpCommand: public WifiCommand\r
999{\r
1000 wifi_firmware_memory_dump_handler mHandler;\r
1001 wifi_driver_memory_dump_callbacks mcallback;\r
1002 int mBuffSize;\r
1003 char *mBuff;\r
1004 GetCmdType mType;\r
0f3dba80 1005\r
cdc775c7
HG
1006public:\r
1007 MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler, GetCmdType cmdtype )\r
1008 : WifiCommand(iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL), mType(cmdtype)\r
0f3dba80
MG
1009 {\r
1010 memset(&mcallback, 0, sizeof(wifi_driver_memory_dump_callbacks));\r
1011 }\r
cdc775c7
HG
1012\r
1013 MemoryDumpCommand(wifi_interface_handle iface, wifi_driver_memory_dump_callbacks callback, GetCmdType cmdtype)\r
1014 : WifiCommand(iface, 0), mcallback(callback), mBuffSize(0), mBuff(NULL), mType(cmdtype)\r
49d0342d 1015 {\r
0f3dba80
MG
1016 memset(&mHandler, 0, sizeof(wifi_firmware_memory_dump_handler));\r
1017 }\r
cdc775c7
HG
1018\r
1019 int createRequest(WifiRequest &request) {\r
1020 int result;\r
1021\r
1022 switch (mType) {\r
1023 case GET_FW_DUMP:\r
1024 {\r
1025 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_TRIGGER_FW_MEM_DUMP);\r
1026 if (result != WIFI_SUCCESS) {\r
1027 ALOGE("Failed to create trigger fw memory dump request; result = %d", result);\r
1028 return result;\r
1029 }\r
1030 break;\r
1031 }\r
1032 case GET_DRIVER_DUMP :\r
1033 {\r
1034 result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_TRIGGER_DRIVER_MEM_DUMP);\r
1035 if (result != WIFI_SUCCESS) {\r
1036 ALOGE("Failed to create trigger driver memory dump request; result = %d", result);\r
1037 return result;\r
1038 }\r
1039 break;\r
1040 }\r
1041 default:\r
1042 ALOGE("Unknown Debug command");\r
1043 result = WIFI_ERROR_UNKNOWN;\r
1044 }\r
1045 return result;\r
1046 }\r
1047 int start() {\r
1048 ALOGD("Start memory dump command");\r
1049 WifiRequest request(familyId(), ifaceId());\r
1050\r
1051 int result = createRequest(request);\r
1052 if (result != WIFI_SUCCESS) {\r
1053 ALOGE("Failed to create trigger memory dump request; result = %d", result);\r
1054 return result;\r
1055 }\r
1056\r
1057 result = requestResponse(request);\r
1058 if (result != WIFI_SUCCESS) {\r
1059 ALOGE("Failed to register trigger memory dump response; result = %d", result);\r
1060 }\r
1061 return result;\r
1062 }\r
1063\r
1064 virtual int handleResponse(WifiEvent& reply) {\r
1065 ALOGD("In MemoryDumpCommand::handleResponse");\r
1066\r
1067 if (reply.get_cmd() != NL80211_CMD_VENDOR) {\r
1068 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());\r
1069 return NL_SKIP;\r
1070 }\r
1071\r
1072 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
1073 int len = reply.get_vendor_data_len();\r
1074\r
1075 ALOGD("len = %d", len);\r
1076 if (vendor_data == NULL || len == 0) {\r
1077 ALOGE("no vendor data in memory dump response; ignoring it");\r
1078 return NL_SKIP;\r
1079 }\r
1080 switch(mType) {\r
1081 case GET_FW_DUMP:\r
1082 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
1083 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN) {\r
1084 mBuffSize = it.get_u32();\r
1085 if (mBuff)\r
1086 free(mBuff);\r
1087 mBuff = (char *)malloc(mBuffSize);\r
1088 if (!mBuff) {\r
1089 ALOGE("Buffer allocation failed");\r
1090 return NL_SKIP;\r
1091 }\r
1092 WifiRequest request(familyId(), ifaceId());\r
1093 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_FW_MEM_DUMP);\r
1094 if (result != WIFI_SUCCESS) {\r
1095 ALOGE("Failed to create get fw memory dump request; result = %d", result);\r
1096 free(mBuff);\r
1097 return NL_SKIP;\r
1098 }\r
1099 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
1100 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);\r
1101 if (result != WIFI_SUCCESS) {\r
1102 ALOGE("Failed to put get fw memory dump request; result = %d", result);\r
1103 return result;\r
1104 }\r
1105 result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff);\r
1106 if (result != WIFI_SUCCESS) {\r
1107 ALOGE("Failed to put get fw memory dump request; result = %d", result);\r
1108 return result;\r
1109 }\r
1110 request.attr_end(data);\r
1111 result = requestResponse(request);\r
1112 if (result != WIFI_SUCCESS) {\r
1113 ALOGE("Failed to register get fw momory dump response; result = %d", result);\r
1114 }\r
1115 } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA) {\r
1116 ALOGI("Initiating memory dump callback");\r
1117 if (mHandler.on_firmware_memory_dump) {\r
1118 (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize);\r
1119 }\r
1120 if (mBuff) {\r
1121 free(mBuff);\r
1122 mBuff = NULL;\r
1123 }\r
1124 } else {\r
1125 ALOGW("Ignoring invalid attribute type = %d, size = %d",\r
1126 it.get_type(), it.get_len());\r
1127 }\r
1128 }\r
1129 case GET_DRIVER_DUMP :\r
1130 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {\r
1131 if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN) {\r
1132 mBuffSize = it.get_u32();\r
1133 if (mBuff)\r
1134 free(mBuff);\r
1135 mBuff = (char *)malloc(mBuffSize);\r
1136 if (!mBuff) {\r
1137 ALOGE("Buffer allocation failed");\r
1138 return NL_SKIP;\r
1139 }\r
1140 WifiRequest request(familyId(), ifaceId());\r
1141 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_DRIVER_MEM_DUMP);\r
1142 if (result != WIFI_SUCCESS) {\r
1143 ALOGE("Failed to create get driver memory dump request; result = %d", result);\r
1144 free(mBuff);\r
1145 return NL_SKIP;\r
1146 }\r
1147 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
1148 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN, mBuffSize);\r
1149 if (result != WIFI_SUCCESS) {\r
1150 ALOGE("Failed to put get driver memory dump request; result = %d", result);\r
1151 return result;\r
1152 }\r
1153 result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA, (uint64_t)mBuff);\r
1154 if (result != WIFI_SUCCESS) {\r
1155 ALOGE("Failed to put get driver memory dump request; result = %d", result);\r
1156 return result;\r
1157 }\r
1158 request.attr_end(data);\r
1159 result = requestResponse(request);\r
1160 if (result != WIFI_SUCCESS) {\r
1161 ALOGE("Failed to register get driver momory dump response; result = %d", result);\r
1162 }\r
1163 } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA) {\r
1164 ALOGI("Initiating memory dump callback");\r
1165 if (mcallback.on_driver_memory_dump) {\r
1166 (*mcallback.on_driver_memory_dump)(mBuff, mBuffSize);\r
1167 }\r
1168 if (mBuff) {\r
1169 free(mBuff);\r
1170 mBuff = NULL;\r
1171 }\r
1172 } else {\r
1173 ALOGW("Ignoring invalid attribute type = %d, size = %d",\r
1174 it.get_type(), it.get_len());\r
1175 }\r
1176 }\r
1177 }\r
1178 return NL_OK;\r
1179 }\r
1180\r
1181 virtual int handleEvent(WifiEvent& event) {\r
1182 /* NO events! */\r
1183 return NL_SKIP;\r
1184 }\r
1185};\r
1186\r
1187/* API to collect a firmware memory dump for a given iface */\r
1188wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface,\r
1189 wifi_firmware_memory_dump_handler handler)\r
1190{\r
1191 MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler, GET_FW_DUMP);\r
1192 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
1193 wifi_error result = (wifi_error)cmd->start();\r
1194 cmd->releaseRef();\r
1195 return result;\r
1196}\r
1197\r
1198wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface,\r
1199 wifi_driver_memory_dump_callbacks callbacks)\r
1200{\r
1201 MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, callbacks, GET_DRIVER_DUMP);\r
1202 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
1203 wifi_error result = (wifi_error)cmd->start();\r
1204 cmd->releaseRef();\r
1205 return result;\r
1206}\r
1207class WifiLoggerCommand: public WifiCommand\r
1208{\r
1209 WLAN_DRIVER_WAKE_REASON_CNT *mGetWakeStats;\r
1210\r
1211public:\r
1212 WifiLoggerCommand(wifi_interface_handle handle, WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)\r
1213 : WifiCommand(handle, 0), mGetWakeStats(wifi_wake_reason_cnt)\r
1214 { }\r
1215\r
1216 int createRequest(WifiRequest& request) {\r
1217 int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_WAKE_REASON_STATS);\r
1218 if (result < 0) {\r
1219 return result;\r
1220 }\r
1221\r
1222 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);\r
1223\r
1224 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ, mGetWakeStats->cmd_event_wake_cnt_sz);\r
1225 if (result != WIFI_SUCCESS) {\r
1226 ALOGE("Failed to put wake_cnt_sz; result = %d", result);\r
1227 return result;\r
1228 }\r
1229 result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ, mGetWakeStats->driver_fw_local_wake_cnt_sz);\r
1230 if (result != WIFI_SUCCESS) {\r
1231 ALOGE("Failed to put driver_fw_local_wake_cnt; result = %d", result);\r
1232 return result;\r
1233 }\r
1234 request.attr_end(data);\r
1235 return result;\r
1236 }\r
1237\r
1238 int start() {\r
1239 ALOGD("Start get wake reason stats command\n");\r
1240 WifiRequest request(familyId(), ifaceId());\r
1241 int result = createRequest(request);\r
1242 if (result < 0) {\r
1243 ALOGE("Failed to create get wake reason stats request; result = %d\n", result);\r
1244 return result;\r
1245 }\r
1246 result = requestResponse(request);\r
1247 if (result != WIFI_SUCCESS) {\r
1248 ALOGE("Failed to register get wake reason stats response; result = %d\n", result);\r
1249 }\r
1250 return result;\r
1251 }\r
1252\r
1253 int handleResponse(WifiEvent& reply) {\r
1254 int len = 0;\r
1255 ALOGD("In WifiLoggerCommand::handleResponse\n");\r
1256\r
1257 if (reply.get_cmd() != NL80211_CMD_VENDOR) {\r
1258 ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());\r
1259 return NL_SKIP;\r
1260 }\r
1261 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);\r
1262 len = reply.get_vendor_data_len();\r
1263 if (vendor_data == NULL || len == 0) {\r
1264 ALOGE("No Debug data found");\r
1265 return NL_SKIP;\r
1266 }\r
1267 nl_iterator it(vendor_data);\r
1268\r
1269 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_CMD_EVENT_WAKE) {\r
1270 ALOGE("TOTAL_CMD_EVENT_WAKE not found %d", it.get_type());\r
1271 return NL_SKIP;\r
1272 }\r
1273\r
1274 mGetWakeStats->total_cmd_event_wake = it.get_u32();\r
1275 it.next();\r
1276\r
1277 if(mGetWakeStats->total_cmd_event_wake && mGetWakeStats->cmd_event_wake_cnt) {\r
1278 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR) {\r
1279 ALOGE("CMD_EVENT_WAKE_CNT_PTR not found %d", it.get_type());\r
1280 return NL_SKIP;\r
1281 }\r
1282\r
1283 len = it.get_len();\r
1284 mGetWakeStats->cmd_event_wake_cnt_used = (len < mGetWakeStats->cmd_event_wake_cnt_sz) ? len : mGetWakeStats->cmd_event_wake_cnt_sz;\r
1285 memcpy(mGetWakeStats->cmd_event_wake_cnt, it.get_data(), mGetWakeStats->cmd_event_wake_cnt_used * sizeof(int));\r
1286 } else {\r
1287 mGetWakeStats->cmd_event_wake_cnt_used = 0;\r
1288 }\r
1289\r
1290 it.next();\r
1291\r
1292 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE) {\r
1293 ALOGE("TOTAL_DRIVER_FW_LOCAL_WAKE not found %d", it.get_type());\r
1294 return NL_SKIP;\r
1295 }\r
1296\r
1297 mGetWakeStats->total_driver_fw_local_wake = it.get_u32();\r
1298 it.next();\r
1299\r
1300 if(mGetWakeStats->total_driver_fw_local_wake && mGetWakeStats->driver_fw_local_wake_cnt) {\r
1301 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR) {\r
1302 ALOGE("DRIVER_FW_LOCAL_WAKE_CNT_PTR not found %d", it.get_type());\r
1303 return NL_SKIP;\r
1304 }\r
1305\r
1306 len = it.get_len();\r
1307 mGetWakeStats->driver_fw_local_wake_cnt_used= (len < mGetWakeStats->driver_fw_local_wake_cnt_sz) ? len : mGetWakeStats->driver_fw_local_wake_cnt_sz;\r
1308 memcpy(mGetWakeStats->driver_fw_local_wake_cnt, it.get_data(), mGetWakeStats->driver_fw_local_wake_cnt_used * sizeof(int));\r
1309 } else {\r
1310 mGetWakeStats->driver_fw_local_wake_cnt_used= 0;\r
1311 }\r
1312\r
1313 it.next();\r
1314\r
1315 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_RX_DATA_WAKE) {\r
1316 ALOGE("TOTAL_RX_DATA_WAKE not found %d", it.get_type());\r
1317 return NL_SKIP;\r
1318 }\r
1319\r
1320 mGetWakeStats->total_rx_data_wake = it.get_u32();\r
1321 it.next();\r
1322\r
1323 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_UNICAST_CNT) {\r
1324 ALOGE("RX_UNICAST_CNT not found %d", it.get_type());\r
1325 return NL_SKIP;\r
1326 }\r
1327\r
1328 mGetWakeStats->rx_wake_details.rx_unicast_cnt = it.get_u32();\r
1329 it.next();\r
1330\r
1331 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_MULTICAST_CNT) {\r
1332 ALOGE("RX_MULTICAST_CNT not found %d", it.get_type());\r
1333 return NL_SKIP;\r
1334 }\r
1335\r
1336 mGetWakeStats->rx_wake_details.rx_multicast_cnt = it.get_u32();\r
1337 it.next();\r
1338\r
1339 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_BROADCAST_CNT) {\r
1340 ALOGE("RX_BROADCAST_CNT not found %d", it.get_type());\r
1341 return NL_SKIP;\r
1342 }\r
1343\r
1344 mGetWakeStats->rx_wake_details.rx_broadcast_cnt = it.get_u32();\r
1345 it.next();\r
1346\r
1347 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP_PKT) {\r
1348 ALOGE("ICMP_PKT not found %d", it.get_type());\r
1349 return NL_SKIP;\r
1350 }\r
1351\r
1352 mGetWakeStats->rx_wake_pkt_classification_info .icmp_pkt = it.get_u32();\r
1353 it.next();\r
1354\r
1355 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_PKT) {\r
1356 ALOGE("ICMP6_PKT not found %d", it.get_type());\r
1357 return NL_SKIP;\r
1358 }\r
1359\r
1360 mGetWakeStats->rx_wake_pkt_classification_info .icmp6_pkt = it.get_u32();\r
1361 it.next();\r
1362\r
1363 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RA) {\r
1364 ALOGE("ICMP6_RA not found %d", it.get_type());\r
1365 return NL_SKIP;\r
1366 }\r
1367\r
1368 mGetWakeStats->rx_wake_pkt_classification_info .icmp6_ra = it.get_u32();\r
1369 it.next();\r
1370\r
1371 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NA) {\r
1372 ALOGE("ICMP6_NA not found %d", it.get_type());\r
1373 return NL_SKIP;\r
1374 }\r
1375\r
1376 mGetWakeStats->rx_wake_pkt_classification_info .icmp6_na = it.get_u32();\r
1377 it.next();\r
1378\r
1379 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NS) {\r
1380 ALOGE("ICMP6_NS not found %d", it.get_type());\r
1381 return NL_SKIP;\r
1382 }\r
1383\r
1384 mGetWakeStats->rx_wake_pkt_classification_info .icmp6_ns = it.get_u32();\r
1385 it.next();\r
1386\r
1387 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP4_RX_MULTICAST_CNT) {\r
1388 ALOGE("ICMP4_RX_MULTICAST_CNT not found %d", it.get_type());\r
1389 return NL_SKIP;\r
1390 }\r
1391\r
1392 mGetWakeStats->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt = it.get_u32();\r
1393 it.next();\r
1394\r
1395 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RX_MULTICAST_CNT) {\r
1396 ALOGE("ICMP6_RX_MULTICAST_CNT not found %d", it.get_type());\r
1397 return NL_SKIP;\r
1398 }\r
1399\r
1400 mGetWakeStats->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt = it.get_u32();\r
1401 it.next();\r
1402\r
1403 if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT) {\r
1404 ALOGE("OTHER_RX_MULTICAST_CNT not found %d", it.get_type());\r
1405 return NL_SKIP;\r
1406 }\r
1407\r
1408 mGetWakeStats->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt = it.get_u32();\r
1409\r
1410 return NL_OK;\r
1411 }\r
1412\r
1413 int handleEvent(WifiEvent& event) {\r
1414 /* NO events to handle here! */\r
1415 return NL_SKIP;\r
1416 }\r
1417};\r
1418\r
1419 /* Function to get wake lock stats */\r
1420wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,\r
1421 WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)\r
1422{\r
1423 if(wifi_wake_reason_cnt) {\r
1424 WifiLoggerCommand *cmd = new WifiLoggerCommand(iface,wifi_wake_reason_cnt);\r
1425 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);\r
1426 wifi_error result = (wifi_error)cmd->start();\r
1427 cmd->releaseRef();\r
1428 return result;\r
1429 } else {\r
1430 ALOGE("Reason cnt NULL");\r
1431 return WIFI_ERROR_INVALID_ARGS;\r
1432 }\r
1433}\r
1434\r