1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Portions copyright (C) 2024 Broadcom Limited
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29 #include <errno.h>
30 
31 #include <linux/pkt_sched.h>
32 #include <netlink/object-api.h>
33 #include <netlink/netlink.h>
34 #include <netlink/socket.h>
35 #include <unistd.h>
36 #include <cutils/properties.h>
37 
38 
39 #include "nl80211_copy.h"
40 #include "sync.h"
41 
42 #define LOG_TAG  "WifiHAL"
43 
44 #include <log/log.h>
45 
46 #include <hardware_legacy/wifi_hal.h>
47 #include "common.h"
48 #include "cpp_bindings.h"
49 #include <sys/stat.h>
50 #include "brcm_version.h"
51 #define WIFI_HAL_EVENT_SOCK_PORT     645
52 
53 #define ARRAYSIZE(a)	(u8)(sizeof(a) / sizeof(a[0]))
54 typedef enum {
55     LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
56     LOGGER_TRIGGER_MEM_DUMP,
57     LOGGER_GET_MEM_DUMP,
58     LOGGER_GET_VER,
59     LOGGER_GET_RING_STATUS,
60     LOGGER_GET_RING_DATA,
61     LOGGER_GET_FEATURE,
62     LOGGER_RESET_LOGGING,
63     LOGGER_TRIGGER_DRIVER_MEM_DUMP,
64     LOGGER_GET_DRIVER_MEM_DUMP,
65     LOGGER_START_PKT_FATE_MONITORING,
66     LOGGER_GET_TX_PKT_FATES,
67     LOGGER_GET_RX_PKT_FATES,
68     LOGGER_GET_WAKE_REASON_STATS,
69     LOGGER_DEBUG_GET_DUMP,
70     LOGGER_FILE_DUMP_DONE_IND,
71     LOGGER_SET_HAL_START,
72     LOGGER_HAL_STOP,
73     LOGGER_SET_HAL_PID,
74     LOGGER_SET_TPUT_DEBUG_DUMP_CMD,
75     LOGGER_GET_BUF_RING_MAP
76 } DEBUG_SUB_COMMAND;
77 
78 #define MAX_NV_FILE 4
79 #define MAX_SKU_NAME_LEN 5
80 #define OTA_PATH "/data/vendor/firmware/wifi/"
81 #define OTA_CLM_FILE "bcmdhd_clm.blob"
82 #define OTA_TXCAP_BLOB_FILE "bcmdhd_txcap.blob"
83 #define OTA_NVRAM_FILE "bcmdhd.cal"
84 #define HW_DEV_PROP "ro.revision"
85 #define HW_SKU_PROP "ro.boot.hardware.sku"
86 
87 typedef enum {
88     NVRAM,
89     CLM_BLOB,
90     TXCAP_BLOB
91 } OTA_TYPE;
92 
93 char ota_nvram_ext[10];
94 typedef struct ota_info_buf {
95     u32 ota_clm_len;
96     const void *ota_clm_buf[1];
97     u32 ota_nvram_len;
98     const void *ota_nvram_buf[1];
99     u32 ota_txcap_len;
100     const void *ota_txcap_buf[1];
101 } ota_info_buf_t;
102 u32 applied_ota_version = 0;
103 
104 typedef enum {
105     LOGGER_ATTRIBUTE_INVALID			= 0,
106     LOGGER_ATTRIBUTE_DRIVER_VER			= 1,
107     LOGGER_ATTRIBUTE_FW_VER			= 2,
108     LOGGER_ATTRIBUTE_RING_ID			= 3,
109     LOGGER_ATTRIBUTE_RING_NAME			= 4,
110     LOGGER_ATTRIBUTE_RING_FLAGS			= 5,
111     LOGGER_ATTRIBUTE_LOG_LEVEL			= 6,
112     LOGGER_ATTRIBUTE_LOG_TIME_INTVAL		= 7,
113     LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE		= 8,
114     LOGGER_ATTRIBUTE_FW_DUMP_LEN		= 9,
115     LOGGER_ATTRIBUTE_FW_DUMP_DATA		= 10,
116     LOGGER_ATTRIBUTE_FW_ERR_CODE		= 11,
117     LOGGER_ATTRIBUTE_RING_DATA			= 12,
118     LOGGER_ATTRIBUTE_RING_STATUS		= 13,
119     LOGGER_ATTRIBUTE_RING_NUM			= 14,
120     LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN		= 15,
121     LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA		= 16,
122     LOGGER_ATTRIBUTE_PKT_FATE_NUM		= 17,
123     LOGGER_ATTRIBUTE_PKT_FATE_DATA		= 18,
124     LOGGER_ATTRIBUTE_HANG_REASON		= 19,
125     LOGGER_ATTRIBUTE_BUF_RING_NUM		= 20,
126     LOGGER_ATTRIBUTE_BUF_RING_MAP		= 21,
127     /* Add new attributes just above this */
128     LOGGER_ATTRIBUTE_MAX
129 } LOGGER_ATTRIBUTE;
130 
131 typedef enum {
132     DEBUG_OFF = 0,
133     DEBUG_NORMAL,
134     DEBUG_VERBOSE,
135     DEBUG_VERY,
136     DEBUG_VERY_VERY,
137 } LOGGER_LEVEL;
138 
139 typedef enum {
140     GET_FW_VER,
141     GET_DRV_VER,
142     GET_RING_DATA,
143     GET_RING_STATUS,
144     GET_FEATURE,
145     START_RING_LOG,
146     GET_BUF_RING_MAP,
147 } GetCmdType;
148 
149 typedef enum {
150     PACKET_MONITOR_START,
151     TX_PACKET_FATE,
152     RX_PACKET_FATE,
153 } PktFateReqType;
154 
155 enum wake_stat_attributes {
156     WAKE_STAT_ATTRIBUTE_INVALID,
157     WAKE_STAT_ATTRIBUTE_TOTAL,
158     WAKE_STAT_ATTRIBUTE_WAKE,
159     WAKE_STAT_ATTRIBUTE_COUNT,
160     WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED,
161     WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW,
162     WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE,
163     WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT,
164     WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED,
165     WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE,
166     WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT,
167     WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT,
168     WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT,
169     WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT,
170     WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT,
171     WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA,
172     WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA,
173     WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS,
174     WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
175     WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
176     WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT,
177     WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO,
178     WAKE_STAT_ATTRIBUTE_MAX
179 };
180 
181 typedef enum {
182     SET_HAL_START_ATTRIBUTE_DEINIT = 0x0001,
183     SET_HAL_START_ATTRIBUTE_PRE_INIT = 0x0002,
184     SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003
185 } SET_HAL_START_ATTRIBUTE;
186 
187 typedef enum {
188     OTA_DOWNLOAD_CLM_LENGTH_ATTR    = 0x0001,
189     OTA_DOWNLOAD_CLM_ATTR           = 0x0002,
190     OTA_DOWNLOAD_NVRAM_LENGTH_ATTR  = 0x0003,
191     OTA_DOWNLOAD_NVRAM_ATTR         = 0x0004,
192     OTA_SET_FORCE_REG_ON            = 0x0005,
193     OTA_CUR_NVRAM_EXT_ATTR          = 0x0006,
194     OTA_DOWNLOAD_TXCAP_BLOB_LENGTH_ATTR    = 0x0007,
195     OTA_DOWNLOAD_TXCAP_BLOB_ATTR           = 0x0008,
196 } OTA_DOWNLOAD_ATTRIBUTE;
197 
198 #define C2S(x)  case x: return #x;
199 static const char *DebugDumpToString(int mType);
DebugDumpToString(int mType)200 static const char *DebugDumpToString(int mType)
201 {
202     switch (mType) {
203         C2S(GET_FW_VER)
204         C2S(GET_DRV_VER)
205         C2S(GET_RING_DATA)
206         C2S(GET_RING_STATUS)
207         C2S(GET_FEATURE)
208         C2S(START_RING_LOG)
209         C2S(GET_BUF_RING_MAP)
210         default:
211             return "DUMP_TYPE_INVALID";
212     }
213 }
214 
215 #define HAL_START_REQUEST_ID 2
216 #define HAL_RESTART_ID 3
217 #define FILE_NAME_LEN 256
218 #define RING_NAME_LEN 32
219 #if defined(RING_DUMP)
220 /* Loglevel */
221 #define DUMP_DEBUG(x)
222 #define DUMP_INFO(x) ALOGI x
223 #define FILE_DUMP_REQUEST_ID 2
224 
225 static const char *EWP_EventAttrToString(int len_attr);
226 static const char *EWP_CmdAttrToString(int data_attr);
227 
228 typedef struct buf_data {
229     u32 ver; /* version of struct */
230     u32 len; /* Total len */
231     /* size of each buffer in case of split buffers (0 - single buffer). */
232     u32 buf_threshold;
233     const void *data_buf[1]; /* array of user space buffer pointers.*/
234 } buf_data_t;
235 
236 /* Attributes associated with GOOGLE_FILE_DUMP_EVENT */
237 typedef enum {
238     DUMP_LEN_ATTR_INVALID                       = 0,
239     DUMP_LEN_ATTR_MEMDUMP                       = 1,
240     DUMP_LEN_ATTR_SSSR_C0_BEFORE                = 2,
241     DUMP_LEN_ATTR_SSSR_C0_AFTER                 = 3,
242     DUMP_LEN_ATTR_SSSR_C1_BEFORE                = 4,
243     DUMP_LEN_ATTR_SSSR_C1_AFTER                 = 5,
244     DUMP_LEN_ATTR_SSSR_C2_BEFORE                = 6,
245     DUMP_LEN_ATTR_SSSR_C2_AFTER                 = 7,
246     DUMP_LEN_ATTR_SSSR_DIG_BEFORE               = 8,
247     DUMP_LEN_ATTR_SSSR_DIG_AFTER                = 9,
248     DUMP_LEN_ATTR_TIMESTAMP                     = 10,
249     DUMP_LEN_ATTR_GENERAL_LOG                   = 11,
250     DUMP_LEN_ATTR_ECNTRS                        = 12,
251     DUMP_LEN_ATTR_SPECIAL_LOG                   = 13,
252     DUMP_LEN_ATTR_DHD_DUMP                      = 14,
253     DUMP_LEN_ATTR_EXT_TRAP                      = 15,
254     DUMP_LEN_ATTR_HEALTH_CHK                    = 16,
255     DUMP_LEN_ATTR_PRESERVE_LOG                  = 17,
256     DUMP_LEN_ATTR_COOKIE                        = 18,
257     DUMP_LEN_ATTR_FLOWRING_DUMP                 = 19,
258     DUMP_LEN_ATTR_PKTLOG                        = 20,
259     DUMP_LEN_ATTR_PKTLOG_DEBUG                  = 21,
260     DUMP_FILENAME_ATTR_DEBUG_DUMP               = 22,
261     DUMP_FILENAME_ATTR_MEM_DUMP                 = 23,
262     DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP  = 24,
263     DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP   = 25,
264     DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP  = 26,
265     DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP   = 27,
266     DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP  = 28,
267     DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP   = 29,
268     DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP     = 30,
269     DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP      = 31,
270     DUMP_FILENAME_ATTR_PKTLOG_DUMP              = 32,
271     DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP        = 33,
272     DUMP_LEN_ATTR_STATUS_LOG                    = 34,
273     DUMP_LEN_ATTR_AXI_ERROR                     = 35,
274     DUMP_FILENAME_ATTR_AXI_ERROR_DUMP           = 36,
275     DUMP_LEN_ATTR_RTT_LOG                       = 37,
276     DUMP_LEN_ATTR_SDTC_ETB_DUMP                 = 38,
277     DUMP_FILENAME_ATTR_SDTC_ETB_DUMP            = 39,
278     DUMP_LEN_ATTR_PKTID_MAP_LOG                 = 40,
279     DUMP_LEN_ATTR_PKTID_UNMAP_LOG               = 41,
280     DUMP_LEN_ATTR_EWP_HW_INIT_LOG               = 42,
281     DUMP_LEN_ATTR_EWP_HW_MOD_DUMP               = 43,
282     DUMP_LEN_ATTR_EWP_HW_REG_DUMP               = 44,
283     DUMP_LEN_ATTR_WRAPPER_REG_DUMP              = 45,
284     /*  Please add new attributes from here to sync up old DHD */
285     DUMP_EVENT_ATTR_MAX                         = 46,
286 } EWP_DUMP_EVENT_ATTRIBUTE;
287 
288 /* Attributes associated with DEBUG_GET_DUMP_BUF */
289 typedef enum {
290     DUMP_BUF_ATTR_INVALID               = 0,
291     DUMP_BUF_ATTR_MEMDUMP               = 1,
292     DUMP_BUF_ATTR_SSSR_C0_BEFORE        = 2,
293     DUMP_BUF_ATTR_SSSR_C0_AFTER         = 3,
294     DUMP_BUF_ATTR_SSSR_C1_BEFORE        = 4,
295     DUMP_BUF_ATTR_SSSR_C1_AFTER         = 5,
296     DUMP_BUF_ATTR_SSSR_C2_BEFORE        = 6,
297     DUMP_BUF_ATTR_SSSR_C2_AFTER         = 7,
298     DUMP_BUF_ATTR_SSSR_DIG_BEFORE       = 8,
299     DUMP_BUF_ATTR_SSSR_DIG_AFTER        = 9,
300     DUMP_BUF_ATTR_TIMESTAMP             = 10,
301     DUMP_BUF_ATTR_GENERAL_LOG           = 11,
302     DUMP_BUF_ATTR_ECNTRS                = 12,
303     DUMP_BUF_ATTR_SPECIAL_LOG           = 13,
304     DUMP_BUF_ATTR_DHD_DUMP              = 14,
305     DUMP_BUF_ATTR_EXT_TRAP              = 15,
306     DUMP_BUF_ATTR_HEALTH_CHK            = 16,
307     DUMP_BUF_ATTR_PRESERVE_LOG          = 17,
308     DUMP_BUF_ATTR_COOKIE                = 18,
309     DUMP_BUF_ATTR_FLOWRING_DUMP         = 19,
310     DUMP_BUF_ATTR_PKTLOG                = 20,
311     DUMP_BUF_ATTR_PKTLOG_DEBUG          = 21,
312     DUMP_BUF_ATTR_STATUS_LOG            = 22,
313     DUMP_BUF_ATTR_AXI_ERROR             = 23,
314     DUMP_BUF_ATTR_RTT_LOG               = 24,
315     DUMP_BUF_ATTR_SDTC_ETB_DUMP         = 25,
316     DUMP_BUF_ATTR_PKTID_MAP_LOG         = 26,
317     DUMP_BUF_ATTR_PKTID_UNMAP_LOG       = 27,
318     DUMP_BUF_ATTR_EWP_HW_INIT_LOG       = 28,
319     DUMP_BUF_ATTR_EWP_HW_MOD_DUMP       = 29,
320     DUMP_BUF_ATTR_EWP_HW_REG_DUMP       = 30,
321     DUMP_BUF_ATTR_WRAPPER_REG_DUMP      = 31,
322     /*  Please add new attributes from here to sync up old DHD */
323     DUMP_BUF_ATTR_MAX                   = 32,
324 } EWP_DUMP_CMD_ATTRIBUTE;
325 
326 typedef enum {
327     DUMP_TYPE_MEM_DUMP                  = 0,
328     DUMP_TYPE_DEBUG_DUMP                = 1,
329     DUMP_TYPE_SSSR_CORE0_BEF_DUMP       = 2,
330     DUMP_TYPE_SSSR_CORE0_AFT_DUMP       = 3,
331     DUMP_TYPE_SSSR_CORE1_BEF_DUMP       = 4,
332     DUMP_TYPE_SSSR_CORE1_AFT_DUMP       = 5,
333     DUMP_TYPE_SSSR_CORE2_BEF_DUMP       = 6,
334     DUMP_TYPE_SSSR_CORE2_AFT_DUMP       = 7,
335     DUMP_TYPE_SSSR_DIG_BEF_DUMP         = 8,
336     DUMP_TYPE_SSSR_DIG_AFT_DUMP         = 9,
337     DUMP_TYPE_PKTLOG_DUMP               = 10,
338     DUMP_TYPE_PKTLOG_DEBUG_DUMP         = 11,
339     DUMP_TYPE_AXI_ERROR_DUMP            = 12,
340     DUMP_TYPE_D2H_MINI_DUMP             = 13,
341     DUMP_TYPE_SDTC_ETB_DUMP             = 14,
342     /*  Please add new attributes from here to sync up old DHD */
343     DUMP_TYPE_MAX                       = 15,
344 } EWP_DUMP_TYPE;
345 
346 /* Struct for table which has len_attr, data_attr and dump file type attr */
347 typedef struct logger_attr_entry {
348     u8 attr_type; /* Type of attribute */
349     u8 buf_attr; /* Buffer associated with the attribute */
350     u8 dump_type; /* Each attribute will be linked to a dump type */
351 } logger_attr_entry_t;
352 
353 logger_attr_entry_t attr_lookup_tbl[] = {
354     /* Mem Dump Block */
355     {DUMP_FILENAME_ATTR_MEM_DUMP, 0, DUMP_TYPE_MEM_DUMP},
356     {DUMP_LEN_ATTR_MEMDUMP, DUMP_BUF_ATTR_MEMDUMP, DUMP_TYPE_MEM_DUMP},
357     /* SSSR Dump Block */
358     {DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE0_BEF_DUMP},
359     {DUMP_LEN_ATTR_SSSR_C0_BEFORE, DUMP_BUF_ATTR_SSSR_C0_BEFORE, DUMP_TYPE_SSSR_CORE0_BEF_DUMP},
360 
361     {DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE0_AFT_DUMP},
362     {DUMP_LEN_ATTR_SSSR_C0_AFTER, DUMP_BUF_ATTR_SSSR_C0_AFTER, DUMP_TYPE_SSSR_CORE0_AFT_DUMP},
363 
364     {DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE1_BEF_DUMP},
365     {DUMP_LEN_ATTR_SSSR_C1_BEFORE, DUMP_BUF_ATTR_SSSR_C1_BEFORE, DUMP_TYPE_SSSR_CORE1_BEF_DUMP},
366 
367     {DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE1_AFT_DUMP},
368     {DUMP_LEN_ATTR_SSSR_C1_AFTER, DUMP_BUF_ATTR_SSSR_C1_AFTER, DUMP_TYPE_SSSR_CORE1_AFT_DUMP},
369 
370     {DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_CORE2_BEF_DUMP},
371     {DUMP_LEN_ATTR_SSSR_C2_BEFORE, DUMP_BUF_ATTR_SSSR_C2_BEFORE, DUMP_TYPE_SSSR_CORE2_BEF_DUMP},
372 
373     {DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP, 0, DUMP_TYPE_SSSR_CORE2_AFT_DUMP},
374     {DUMP_LEN_ATTR_SSSR_C2_AFTER, DUMP_BUF_ATTR_SSSR_C2_AFTER, DUMP_TYPE_SSSR_CORE2_AFT_DUMP},
375 
376     {DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP, 0, DUMP_TYPE_SSSR_DIG_BEF_DUMP},
377     {DUMP_LEN_ATTR_SSSR_DIG_BEFORE, DUMP_BUF_ATTR_SSSR_DIG_BEFORE, DUMP_TYPE_SSSR_DIG_BEF_DUMP},
378 
379     {DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP, 0, DUMP_TYPE_SSSR_DIG_AFT_DUMP},
380     {DUMP_LEN_ATTR_SSSR_DIG_AFTER, DUMP_BUF_ATTR_SSSR_DIG_AFTER, DUMP_TYPE_SSSR_DIG_AFT_DUMP},
381 
382     /* Debug Dump Block */
383     {DUMP_FILENAME_ATTR_DEBUG_DUMP, 0, DUMP_TYPE_DEBUG_DUMP},
384     {DUMP_LEN_ATTR_TIMESTAMP, DUMP_BUF_ATTR_TIMESTAMP, DUMP_TYPE_DEBUG_DUMP},
385     {DUMP_LEN_ATTR_GENERAL_LOG, DUMP_BUF_ATTR_GENERAL_LOG, DUMP_TYPE_DEBUG_DUMP},
386     {DUMP_LEN_ATTR_ECNTRS, DUMP_BUF_ATTR_ECNTRS, DUMP_TYPE_DEBUG_DUMP},
387     {DUMP_LEN_ATTR_SPECIAL_LOG, DUMP_BUF_ATTR_SPECIAL_LOG, DUMP_TYPE_DEBUG_DUMP},
388     {DUMP_LEN_ATTR_DHD_DUMP, DUMP_BUF_ATTR_DHD_DUMP, DUMP_TYPE_DEBUG_DUMP},
389     {DUMP_LEN_ATTR_EXT_TRAP, DUMP_BUF_ATTR_EXT_TRAP, DUMP_TYPE_DEBUG_DUMP},
390     {DUMP_LEN_ATTR_HEALTH_CHK, DUMP_BUF_ATTR_HEALTH_CHK, DUMP_TYPE_DEBUG_DUMP},
391     {DUMP_LEN_ATTR_PRESERVE_LOG, DUMP_BUF_ATTR_PRESERVE_LOG, DUMP_TYPE_DEBUG_DUMP},
392     {DUMP_LEN_ATTR_COOKIE, DUMP_BUF_ATTR_COOKIE, DUMP_TYPE_DEBUG_DUMP},
393     {DUMP_LEN_ATTR_FLOWRING_DUMP, DUMP_BUF_ATTR_FLOWRING_DUMP, DUMP_TYPE_DEBUG_DUMP},
394     {DUMP_LEN_ATTR_STATUS_LOG, DUMP_BUF_ATTR_STATUS_LOG, DUMP_TYPE_DEBUG_DUMP},
395     {DUMP_LEN_ATTR_RTT_LOG, DUMP_BUF_ATTR_RTT_LOG, DUMP_TYPE_DEBUG_DUMP},
396     {DUMP_LEN_ATTR_PKTID_MAP_LOG, DUMP_BUF_ATTR_PKTID_MAP_LOG, DUMP_TYPE_DEBUG_DUMP},
397     {DUMP_LEN_ATTR_PKTID_UNMAP_LOG, DUMP_BUF_ATTR_PKTID_UNMAP_LOG, DUMP_TYPE_DEBUG_DUMP},
398     {DUMP_LEN_ATTR_EWP_HW_INIT_LOG, DUMP_BUF_ATTR_EWP_HW_INIT_LOG, DUMP_TYPE_DEBUG_DUMP},
399     {DUMP_LEN_ATTR_EWP_HW_MOD_DUMP, DUMP_BUF_ATTR_EWP_HW_MOD_DUMP, DUMP_TYPE_DEBUG_DUMP},
400     {DUMP_LEN_ATTR_EWP_HW_REG_DUMP, DUMP_BUF_ATTR_EWP_HW_REG_DUMP, DUMP_TYPE_DEBUG_DUMP},
401     {DUMP_LEN_ATTR_WRAPPER_REG_DUMP, DUMP_BUF_ATTR_WRAPPER_REG_DUMP, DUMP_TYPE_DEBUG_DUMP},
402 
403     /* PKT log dump block */
404     {DUMP_FILENAME_ATTR_PKTLOG_DUMP, 0, DUMP_TYPE_PKTLOG_DUMP},
405     {DUMP_LEN_ATTR_PKTLOG, DUMP_BUF_ATTR_PKTLOG, DUMP_TYPE_PKTLOG_DUMP},
406     {DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP, 0, DUMP_TYPE_PKTLOG_DEBUG_DUMP},
407     {DUMP_LEN_ATTR_PKTLOG_DEBUG, DUMP_BUF_ATTR_PKTLOG_DEBUG, DUMP_TYPE_PKTLOG_DEBUG_DUMP},
408     /* AXI error log dump block */
409     {DUMP_FILENAME_ATTR_AXI_ERROR_DUMP, 0, DUMP_TYPE_AXI_ERROR_DUMP},
410     {DUMP_LEN_ATTR_AXI_ERROR, DUMP_BUF_ATTR_AXI_ERROR, DUMP_TYPE_AXI_ERROR_DUMP},
411     /* SDTC etb log dump block */
412     {DUMP_FILENAME_ATTR_SDTC_ETB_DUMP, 0, DUMP_TYPE_SDTC_ETB_DUMP},
413     {DUMP_LEN_ATTR_SDTC_ETB_DUMP, DUMP_BUF_ATTR_SDTC_ETB_DUMP, DUMP_TYPE_SDTC_ETB_DUMP},
414     {DUMP_EVENT_ATTR_MAX, 0, 0},
415 };
416 
EWP_EventAttrToString(int len_attr)417 static const char *EWP_EventAttrToString(int len_attr)
418 {
419     switch (len_attr) {
420         C2S(DUMP_LEN_ATTR_MEMDUMP)
421         C2S(DUMP_LEN_ATTR_SSSR_C0_BEFORE)
422         C2S(DUMP_LEN_ATTR_SSSR_C0_AFTER)
423         C2S(DUMP_LEN_ATTR_SSSR_C1_BEFORE)
424         C2S(DUMP_LEN_ATTR_SSSR_C1_AFTER)
425         C2S(DUMP_LEN_ATTR_SSSR_C2_BEFORE)
426         C2S(DUMP_LEN_ATTR_SSSR_C2_AFTER)
427         C2S(DUMP_LEN_ATTR_SSSR_DIG_BEFORE)
428         C2S(DUMP_LEN_ATTR_SSSR_DIG_AFTER)
429         C2S(DUMP_LEN_ATTR_TIMESTAMP)
430         C2S(DUMP_LEN_ATTR_GENERAL_LOG)
431         C2S(DUMP_LEN_ATTR_ECNTRS)
432         C2S(DUMP_LEN_ATTR_SPECIAL_LOG)
433         C2S(DUMP_LEN_ATTR_DHD_DUMP)
434         C2S(DUMP_LEN_ATTR_EXT_TRAP)
435         C2S(DUMP_LEN_ATTR_HEALTH_CHK)
436         C2S(DUMP_LEN_ATTR_PRESERVE_LOG)
437         C2S(DUMP_LEN_ATTR_COOKIE)
438         C2S(DUMP_LEN_ATTR_FLOWRING_DUMP)
439         C2S(DUMP_LEN_ATTR_PKTLOG)
440         C2S(DUMP_LEN_ATTR_PKTLOG_DEBUG)
441         C2S(DUMP_LEN_ATTR_STATUS_LOG)
442         C2S(DUMP_FILENAME_ATTR_DEBUG_DUMP)
443         C2S(DUMP_FILENAME_ATTR_MEM_DUMP)
444         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP)
445         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP)
446         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP)
447         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP)
448         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP)
449         C2S(DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP)
450         C2S(DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP)
451         C2S(DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP)
452         C2S(DUMP_FILENAME_ATTR_PKTLOG_DUMP)
453         C2S(DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP)
454         C2S(DUMP_LEN_ATTR_AXI_ERROR)
455         C2S(DUMP_FILENAME_ATTR_AXI_ERROR_DUMP)
456         C2S(DUMP_LEN_ATTR_RTT_LOG)
457         C2S(DUMP_FILENAME_ATTR_SDTC_ETB_DUMP)
458         C2S(DUMP_LEN_ATTR_SDTC_ETB_DUMP)
459         C2S(DUMP_LEN_ATTR_PKTID_MAP_LOG)
460         C2S(DUMP_LEN_ATTR_PKTID_UNMAP_LOG)
461         C2S(DUMP_LEN_ATTR_EWP_HW_INIT_LOG)
462         C2S(DUMP_LEN_ATTR_EWP_HW_MOD_DUMP)
463         C2S(DUMP_LEN_ATTR_EWP_HW_REG_DUMP)
464         C2S(DUMP_LEN_ATTR_WRAPPER_REG_DUMP)
465         default:
466             return "DUMP_LEN_ATTR_INVALID";
467     }
468 }
469 
EWP_CmdAttrToString(int attr)470 static const char *EWP_CmdAttrToString(int attr)
471 {
472     switch (attr) {
473         C2S(DUMP_BUF_ATTR_MEMDUMP)
474         C2S(DUMP_BUF_ATTR_SSSR_C0_BEFORE)
475         C2S(DUMP_BUF_ATTR_SSSR_C0_AFTER)
476         C2S(DUMP_BUF_ATTR_SSSR_C1_BEFORE)
477         C2S(DUMP_BUF_ATTR_SSSR_C1_AFTER)
478         C2S(DUMP_BUF_ATTR_SSSR_C2_BEFORE)
479         C2S(DUMP_BUF_ATTR_SSSR_C2_AFTER)
480         C2S(DUMP_BUF_ATTR_SSSR_DIG_BEFORE)
481         C2S(DUMP_BUF_ATTR_SSSR_DIG_AFTER)
482         C2S(DUMP_BUF_ATTR_TIMESTAMP)
483         C2S(DUMP_BUF_ATTR_GENERAL_LOG)
484         C2S(DUMP_BUF_ATTR_ECNTRS)
485         C2S(DUMP_BUF_ATTR_SPECIAL_LOG)
486         C2S(DUMP_BUF_ATTR_DHD_DUMP)
487         C2S(DUMP_BUF_ATTR_EXT_TRAP)
488         C2S(DUMP_BUF_ATTR_HEALTH_CHK)
489         C2S(DUMP_BUF_ATTR_PRESERVE_LOG)
490         C2S(DUMP_BUF_ATTR_COOKIE)
491         C2S(DUMP_BUF_ATTR_FLOWRING_DUMP)
492         C2S(DUMP_BUF_ATTR_PKTLOG)
493         C2S(DUMP_BUF_ATTR_PKTLOG_DEBUG)
494         C2S(DUMP_BUF_ATTR_STATUS_LOG)
495         C2S(DUMP_BUF_ATTR_AXI_ERROR)
496         C2S(DUMP_BUF_ATTR_RTT_LOG)
497         C2S(DUMP_BUF_ATTR_SDTC_ETB_DUMP)
498         C2S(DUMP_BUF_ATTR_PKTID_MAP_LOG)
499         C2S(DUMP_BUF_ATTR_PKTID_UNMAP_LOG)
500         C2S(DUMP_BUF_ATTR_EWP_HW_INIT_LOG)
501         C2S(DUMP_BUF_ATTR_EWP_HW_MOD_DUMP)
502         C2S(DUMP_BUF_ATTR_EWP_HW_REG_DUMP)
503         C2S(DUMP_BUF_ATTR_WRAPPER_REG_DUMP)
504         default:
505             return "DUMP_BUF_ATTR_INVALID";
506     }
507 }
508 
509 /* Return index for matching buffer attribute */
logger_attr_buffer_lookup(u8 attr)510 static int logger_attr_buffer_lookup(u8 attr) {
511     for (u8 i = 0; i < ARRAYSIZE(attr_lookup_tbl); i++) {
512         if (attr == attr_lookup_tbl[i].buf_attr) {
513             return i;
514         }
515     }
516     ALOGE("Lookup for buf attr = %s failed\n",
517     EWP_CmdAttrToString(attr));
518     return -1;
519 }
520 
521 /* Return index matching the length attribute */
logger_attr_lookup(u8 attr)522 static int logger_attr_lookup(u8 attr) {
523     for (u8 i = 0; i < ARRAYSIZE(attr_lookup_tbl); i++) {
524         if (attr == attr_lookup_tbl[i].attr_type) {
525             return i;
526         }
527     }
528     ALOGE("Lookup for len attr = %s failed\n",
529         EWP_EventAttrToString(attr));
530     return -1;
531 }
532 #endif /* RING_DUMP */
533 
534 #define DBGRING_NAME_MAX 32  //Copy from legacy hal
535 typedef struct wifi_buf_ring_map_entry {
536     uint32_t type;
537     uint32_t ring_id;
538     char ring_name[DBGRING_NAME_MAX];
539 } wifi_buf_ring_map_entry_t;
540 
541 typedef struct {
542     char hw_id[PROPERTY_VALUE_MAX];
543     char sku[MAX_SKU_NAME_LEN];
544 } sku_info_t;
545 
546 sku_info_t sku_table[] = {
547     // BCM4389
548     { {"G9S9B"}, {"MMW"} },
549     { {"G8V0U"}, {"MMW"} },
550     { {"GFQM1"}, {"MMW"} },
551     { {"GB62Z"}, {"MMW"} },
552     { {"GE2AE"}, {"MMW"} },
553     { {"GQML3"}, {"MMW"} },
554     { {"GB7N6"}, {"ROW"} },
555     { {"GLU0G"}, {"ROW"} },
556     { {"GNA8F"}, {"ROW"} },
557     { {"GX7AS"}, {"ROW"} },
558     { {"GP4BC"}, {"ROW"} },
559     { {"GVU6C"}, {"ROW"} },
560     { {"GR1YH"}, {"JPN"} },
561     { {"GF5KQ"}, {"JPN"} },
562     { {"GPQ72"}, {"JPN"} },
563     { {"GB17L"}, {"JPN"} },
564     { {"GFE4J"}, {"JPN"} },
565     { {"G03Z5"}, {"JPN"} },
566     // BCM4398
567     { {"GKWS6"}, {"MMW"} },
568     { {"G1MNW"}, {"MMW"} },
569     { {"GPJ41"}, {"ROW"} },
570     { {"GC3VE"}, {"ROW"} },
571     { {"GE9DP"}, {"JPN"} },
572     { {"GZPF0"}, {"JPN"} },
573     { {"G1AZG"}, {"EU"} },
574     { {"G9BQD"}, {"NA"} },
575     // BCM4383
576     { {"G8HHN"}, {"MMW"} },
577     { {"G6GPR"}, {"ROW"} },
578     { {"G576D"}, {"JPN"} },
579     { {"GKV4X"}, {"NA"} }
580 };
581 ///////////////////////////////////////////////////////////////////////////////
582 class DebugCommand : public WifiCommand
583 {
584     char *mBuff;
585     int *mBuffSize;
586     u32 *mNumRings;
587     wifi_ring_buffer_status *mStatus;
588     u32 *mNumMaps;
589     wifi_buf_ring_map_entry_t *mMaps;
590     unsigned int *mSupport;
591     u32 mVerboseLevel;
592     u32 mFlags;
593     u32 mMaxIntervalSec;
594     u32 mMinDataSize;
595     char *mRingName;
596     GetCmdType mType;
597 
598 public:
599 
600     // constructor for get version
DebugCommand(wifi_interface_handle iface,char * buffer,int * buffer_size,GetCmdType cmdType)601     DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size,
602             GetCmdType cmdType)
603         : WifiCommand("DebugCommand", iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType
604         (cmdType)
605     {
606         mNumRings =  NULL;
607         mStatus = NULL;
608         mSupport = NULL;
609         mVerboseLevel = 0;
610         mFlags = 0;
611         mMaxIntervalSec = 0;
612         mMinDataSize = 0;
613         mRingName = NULL;
614         memset(mBuff, 0, *mBuffSize);
615         mNumMaps = NULL;
616         mMaps = NULL;
617     }
618 
619     // constructor for ring data
DebugCommand(wifi_interface_handle iface,char * ring_name,GetCmdType cmdType)620     DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType)
621         : WifiCommand("DebugCommand", iface, 0), mRingName(ring_name), mType(cmdType)
622     {
623         mBuff = NULL;
624         mBuffSize = NULL;
625         mNumRings =  NULL;
626         mStatus = NULL;
627         mSupport = NULL;
628         mVerboseLevel = 0;
629         mFlags = 0;
630         mMaxIntervalSec = 0;
631         mMinDataSize = 0;
632         mNumMaps = NULL;
633         mMaps = NULL;
634     }
635 
636     // constructor for ring status
DebugCommand(wifi_interface_handle iface,u32 * num_rings,wifi_ring_buffer_status * status,GetCmdType cmdType)637     DebugCommand(wifi_interface_handle iface, u32 *num_rings,
638             wifi_ring_buffer_status *status, GetCmdType cmdType)
639         : WifiCommand("DebugCommand", iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType)
640     {
641         mBuff = NULL;
642         mBuffSize = NULL;
643         mSupport = NULL;
644         mVerboseLevel = 0;
645         mFlags = 0;
646         mMaxIntervalSec = 0;
647         mMinDataSize = 0;
648         mRingName = NULL;
649         memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings));
650         mNumMaps = NULL;
651         mMaps = NULL;
652     }
653 
654     // constructor for feature set
DebugCommand(wifi_interface_handle iface,unsigned int * support,GetCmdType cmdType)655     DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType)
656         : WifiCommand("DebugCommand", iface, 0), mSupport(support), mType(cmdType)
657     {
658         mBuff = NULL;
659         mBuffSize = NULL;
660         mNumRings =  NULL;
661         mStatus = NULL;
662         mVerboseLevel = 0;
663         mFlags = 0;
664         mMaxIntervalSec = 0;
665         mMinDataSize = 0;
666         mRingName = NULL;
667         mMaps = NULL;
668         mNumMaps = NULL;
669     }
670 
671     // constructor for buf ring map
DebugCommand(wifi_interface_handle iface,u32 * num_maps,wifi_buf_ring_map_entry_t * map,GetCmdType cmdType)672     DebugCommand(wifi_interface_handle iface, u32 *num_maps,
673             wifi_buf_ring_map_entry_t *map, GetCmdType cmdType)
674         : WifiCommand("DebugCommand", iface, 0), mNumMaps(num_maps), mMaps(map), mType(cmdType)
675     {
676         memset(mMaps, 0, sizeof(wifi_buf_ring_map_entry_t) * (*mNumMaps));
677         mBuff = NULL;
678         mBuffSize = NULL;
679         mNumRings =  NULL;
680         mStatus = NULL;
681         mVerboseLevel = 0;
682         mFlags = 0;
683         mMaxIntervalSec = 0;
684         mMinDataSize = 0;
685         mRingName = NULL;
686         mSupport = NULL;
687     }
688 
689     // constructor for ring params
DebugCommand(wifi_interface_handle iface,u32 verbose_level,u32 flags,u32 max_interval_sec,u32 min_data_size,char * ring_name,GetCmdType cmdType)690     DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags,
691             u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType)
692         : WifiCommand("DebugCommand", iface, 0), mVerboseLevel(verbose_level), mFlags(flags),
693         mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size),
694         mRingName(ring_name), mType(cmdType)
695     {
696         mBuff = NULL;
697         mBuffSize = NULL;
698         mNumRings =  NULL;
699         mStatus = NULL;
700         mSupport = NULL;
701         mMaps = NULL;
702         mNumMaps = NULL;
703     }
704 
createRingRequest(WifiRequest & request)705     int createRingRequest(WifiRequest& request) {
706         int result = request.create(GOOGLE_OUI, LOGGER_START_LOGGING);
707         if (result != WIFI_SUCCESS) {
708             ALOGE("Failed to create start ring logger request; result = %d", result);
709             return result;
710         }
711 
712         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
713 
714         result = request.put_u32(LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel);
715         if (result != WIFI_SUCCESS) {
716             ALOGE("Failed to put log level; result = %d", result);
717             return result;
718         }
719         result = request.put_u32(LOGGER_ATTRIBUTE_RING_FLAGS, mFlags);
720         if (result != WIFI_SUCCESS) {
721             ALOGE("Failed to put ring flags; result = %d", result);
722             return result;
723         }
724         result = request.put_u32(LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec);
725         if (result != WIFI_SUCCESS) {
726             ALOGE("Failed to put log time interval; result = %d", result);
727             return result;
728         }
729         result = request.put_u32(LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize);
730         if (result != WIFI_SUCCESS) {
731             ALOGE("Failed to put min data size; result = %d", result);
732             return result;
733         }
734         result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
735         if (result != WIFI_SUCCESS) {
736             ALOGE("Failed to put ringbuffer name; result = %d", result);
737             return result;
738         }
739         request.attr_end(data);
740 
741         return WIFI_SUCCESS;
742     }
743 
createRequest(WifiRequest & request)744     int createRequest(WifiRequest &request) {
745         int result;
746 
747         ALOGI("CreateRequest mType = %s", DebugDumpToString(mType));
748         switch (mType) {
749             case GET_FW_VER:
750             {
751                 result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
752                 if (result != WIFI_SUCCESS) {
753                     ALOGE("Failed to create get fw version request; result = %d", result);
754                     return result;
755                 }
756 
757                 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
758 
759                 // Driver expecting only attribute type, passing mbuff as data with
760                 // length 0 to avoid undefined state
761                 result = request.put(LOGGER_ATTRIBUTE_FW_VER, mBuff, 0);
762                 if (result != WIFI_SUCCESS) {
763                     ALOGE("Failed to put get fw version request; result = %d", result);
764                     return result;
765                 }
766                 request.attr_end(data);
767                 break;
768             }
769 
770             case GET_DRV_VER:
771             {
772                 result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
773                 if (result != WIFI_SUCCESS) {
774                     ALOGE("Failed to create get drv version request; result = %d", result);
775                     return result;
776                 }
777 
778                 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
779 
780                 // Driver expecting only attribute type, passing mbuff as data with
781                 // length 0 to avoid undefined state
782                 result = request.put(LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0);
783 
784                 if (result != WIFI_SUCCESS) {
785                     ALOGE("Failed to put get drv version request; result = %d", result);
786                     return result;
787                 }
788                 request.attr_end(data);
789                 break;
790             }
791 
792             case GET_RING_DATA:
793             {
794                 result = request.create(GOOGLE_OUI, LOGGER_GET_RING_DATA);
795                 if (result != WIFI_SUCCESS) {
796                     ALOGE("Failed to create get ring data request; result = %d", result);
797                     return result;
798                 }
799 
800                 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
801                 result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
802                 if (result != WIFI_SUCCESS) {
803                     ALOGE("Failed to put ring data request; result = %d", result);
804                     return result;
805                 }
806                 ALOGI("Success to put ring data request for RingName %s", mRingName);
807                 request.attr_end(data);
808                 break;
809             }
810 
811             case GET_RING_STATUS:
812             {
813                 result = request.create(GOOGLE_OUI, LOGGER_GET_RING_STATUS);
814                 if (result != WIFI_SUCCESS) {
815                     ALOGE("Failed to create get ring status request; result = %d", result);
816                     return result;
817                 }
818                 break;
819             }
820 
821             case GET_FEATURE:
822             {
823                 result = request.create(GOOGLE_OUI, LOGGER_GET_FEATURE);
824                 if (result != WIFI_SUCCESS) {
825                     ALOGE("Failed to create get feature request; result = %d", result);
826                     return result;
827                 }
828                 break;
829             }
830 
831             case GET_BUF_RING_MAP:
832             {
833                 result = request.create(GOOGLE_OUI, LOGGER_GET_BUF_RING_MAP);
834                 if (result != WIFI_SUCCESS) {
835                     ALOGE("Failed to create get ring status request; result = %d", result);
836                     return result;
837                 }
838                 break;
839             }
840 
841             case START_RING_LOG:
842                 result = createRingRequest(request);
843                 break;
844 
845             default:
846                 ALOGE("Unknown Debug command");
847                 result = WIFI_ERROR_UNKNOWN;
848         }
849         return result;
850     }
851 
start()852     int start() {
853         ALOGD("Start debug command: mType %s", DebugDumpToString(mType));
854         WifiRequest request(familyId(), ifaceId());
855         int result = createRequest(request);
856         if (result != WIFI_SUCCESS) {
857             ALOGE("Failed to create debug request; result = %d", result);
858             return result;
859         }
860 
861         result = requestResponse(request);
862         if (result != WIFI_SUCCESS) {
863             ALOGE("Failed to register debug response; result = %d", result);
864         }
865         return result;
866     }
867 
handleResponse(WifiEvent & reply)868     virtual int handleResponse(WifiEvent& reply) {
869         ALOGD("In DebugCommand::handleResponse, mType:%s\n", DebugDumpToString(mType));
870 
871         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
872             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
873             return NL_SKIP;
874         }
875 
876         switch (mType) {
877             case GET_DRV_VER:
878             case GET_FW_VER:
879             {
880                 void *data = reply.get_vendor_data();
881                 int len = reply.get_vendor_data_len();
882 
883                 ALOGD("len = %d, expected len = %d", len, *mBuffSize);
884                 memcpy(mBuff, data, min(len, *mBuffSize));
885                 if (*mBuffSize < len)
886                     return NL_SKIP;
887                 *mBuffSize = len;
888                 break;
889             }
890 
891             case START_RING_LOG:
892             case GET_RING_DATA:
893                 break;
894 
895             case GET_RING_STATUS:
896             {
897                 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
898                 int len = reply.get_vendor_data_len();
899                 wifi_ring_buffer_status *status(mStatus);
900 
901                 if (vendor_data == NULL || len == 0) {
902                     ALOGE("No Debug data found");
903                     return NL_SKIP;
904                 }
905 
906                 nl_iterator it(vendor_data);
907                 if (it.get_type() == LOGGER_ATTRIBUTE_RING_NUM) {
908                     unsigned int num_rings = it.get_u32();
909                     if (*mNumRings < num_rings) {
910                         ALOGE("Not enough status buffers provided, available: %d required: %d",
911                                 *mNumRings, num_rings);
912                     } else {
913                         *mNumRings = num_rings;
914                     }
915                 } else {
916                     ALOGE("Unknown attribute: %d expecting %d",
917                             it.get_type(), LOGGER_ATTRIBUTE_RING_NUM);
918                     return NL_SKIP;
919                 }
920 
921                 it.next();
922                 for (unsigned int i = 0; it.has_next() && i < *mNumRings; it.next()) {
923                     if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
924                         if (it.get_len() > sizeof(wifi_ring_buffer_status)) {
925                             ALOGE("ring status unexpected len = %d, dest len = %lu",
926                                 it.get_len(), sizeof(wifi_ring_buffer_status));
927                             return NL_SKIP;
928                         } else {
929                             memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status));
930                             i++;
931                             status++;
932                         }
933                     } else {
934                         ALOGW("Ignoring invalid attribute type = %d, size = %d",
935                                 it.get_type(), it.get_len());
936                     }
937                 }
938                 break;
939             }
940 
941             case GET_FEATURE:
942             {
943                 void *data = reply.get_vendor_data();
944                 int len = reply.get_vendor_data_len();
945 
946                 ALOGD("len = %d, expected len = %lu", len, sizeof(unsigned int));
947                 memcpy(mSupport, data, sizeof(unsigned int));
948                 break;
949             }
950 
951             case GET_BUF_RING_MAP:
952             {
953                 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
954                 int len = reply.get_vendor_data_len();
955                 wifi_buf_ring_map_entry_t *map(mMaps);
956 
957                 if (vendor_data == NULL || len == 0) {
958                     ALOGE("No Debug data found");
959                     return NL_SKIP;
960                 }
961 
962                 nl_iterator it(vendor_data);
963                 if (it.get_type() == LOGGER_ATTRIBUTE_BUF_RING_NUM) {
964                     unsigned int num_maps = it.get_u32();
965                     if (*mNumMaps < num_maps) {
966                         ALOGE("Not enough status buffers provided, available: %d required: %d",
967                             *mNumMaps, num_maps);
968                     } else {
969                         *mNumMaps = num_maps;
970                     }
971                 } else {
972                     ALOGE("Unknown attribute: %d expecting %d",
973                         it.get_type(), LOGGER_ATTRIBUTE_BUF_RING_NUM);
974                     return NL_SKIP;
975                 }
976 
977                 it.next();
978                 for (unsigned int i = 0; it.has_next() && i < *mNumMaps; it.next()) {
979                     if (it.get_type() == LOGGER_ATTRIBUTE_BUF_RING_MAP) {
980                         if (it.get_len() > sizeof(wifi_buf_ring_map_entry_t)) {
981                             ALOGE("GET_BUF_RING_MAP: unexpected len = %d, dest len = %lu",
982                                 it.get_len(), sizeof(wifi_buf_ring_map_entry_t));
983                             return NL_SKIP;
984                         } else {
985                             memcpy(map, it.get_data(), sizeof(wifi_buf_ring_map_entry_t));
986                         }
987                         i++;
988                         map++;
989                     } else {
990                         ALOGW("Ignoring invalid attribute type = %d, size = %d",
991                             it.get_type(), it.get_len());
992                     }
993                 }
994                 break;
995             }
996 
997             default:
998                 ALOGW("Unknown Debug command");
999         }
1000         return NL_OK;
1001     }
1002 
handleEvent(WifiEvent & event)1003     virtual int handleEvent(WifiEvent& event) {
1004         /* NO events! */
1005         return NL_SKIP;
1006     }
1007 };
1008 
1009 /* API to collect a firmware version string */
wifi_get_firmware_version(wifi_interface_handle iface,char * buffer,int buffer_size)1010 wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer,
1011         int buffer_size)
1012 {
1013     if (buffer && (buffer_size > 0)) {
1014         DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER);
1015         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1016         wifi_error result = (wifi_error)cmd->start();
1017         cmd->releaseRef();
1018         return result;
1019     } else {
1020         ALOGE("FW version buffer NULL");
1021         return  WIFI_ERROR_INVALID_ARGS;
1022     }
1023 }
1024 
1025 /* API to collect a driver version string */
wifi_get_driver_version(wifi_interface_handle iface,char * buffer,int buffer_size)1026 wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size)
1027 {
1028     if (buffer && (buffer_size > 0)) {
1029         DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER);
1030         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1031         wifi_error result = (wifi_error)cmd->start();
1032         cmd->releaseRef();
1033         return result;
1034     } else {
1035         ALOGE("Driver version buffer NULL");
1036         return  WIFI_ERROR_INVALID_ARGS;
1037     }
1038 }
1039 
1040 /* API to collect driver records */
wifi_get_ring_data(wifi_interface_handle iface,char * ring_name)1041 wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name)
1042 {
1043     DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA);
1044     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1045     wifi_error result = (wifi_error)cmd->start();
1046     cmd->releaseRef();
1047     return result;
1048 }
1049 
1050 /* API to get the status of all ring buffers supported by driver */
wifi_get_ring_buffers_status(wifi_interface_handle iface,u32 * num_rings,wifi_ring_buffer_status * status)1051 wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
1052         u32 *num_rings, wifi_ring_buffer_status *status)
1053 {
1054     if (status && num_rings) {
1055         DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS);
1056         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1057         wifi_error result = (wifi_error)cmd->start();
1058         cmd->releaseRef();
1059         return result;
1060     } else {
1061         ALOGE("Ring status buffer NULL");
1062         return  WIFI_ERROR_INVALID_ARGS;
1063     }
1064 }
1065 
1066 /* API to get supportable feature */
wifi_get_logger_supported_feature_set(wifi_interface_handle iface,unsigned int * support)1067 wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
1068         unsigned int *support)
1069 {
1070     if (support) {
1071         DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE);
1072         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1073         wifi_error result = (wifi_error)cmd->start();
1074         cmd->releaseRef();
1075         return result;
1076     } else {
1077         ALOGE("Get support buffer NULL");
1078         return  WIFI_ERROR_INVALID_ARGS;
1079     }
1080 }
1081 
wifi_start_logging(wifi_interface_handle iface,u32 verbose_level,u32 flags,u32 max_interval_sec,u32 min_data_size,char * ring_name)1082 wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level,
1083         u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name)
1084 {
1085     if (ring_name) {
1086         ALOGE("Ring name: level:%d sec:%d ring_name:%s",
1087                 verbose_level, max_interval_sec, ring_name);
1088         DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec,
1089                     min_data_size, ring_name, START_RING_LOG);
1090         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1091         wifi_error result = (wifi_error)cmd->start();
1092         cmd->releaseRef();
1093         return result;
1094     } else {
1095         ALOGE("Ring name NULL");
1096         return  WIFI_ERROR_INVALID_ARGS;
1097     }
1098 }
1099 
1100 typedef struct {
1101     u32 magic;
1102     int num_entries;
1103 } __attribute__((packed)) wifi_ring_buffer_entry_pack;
1104 
1105 #define WIFI_RING_BUFFER_PACK_MAGIC 0xDBAADBAA
1106 
1107 ///////////////////////////////////////////////////////////////////////////////
1108 class SetLogHandler : public WifiCommand
1109 {
1110     wifi_ring_buffer_data_handler mHandler;
1111 
1112 public:
SetLogHandler(wifi_interface_handle iface,int id,wifi_ring_buffer_data_handler handler)1113     SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler)
1114         : WifiCommand("SetLogHandler", iface, id), mHandler(handler)
1115     { }
1116 
start()1117     int start() {
1118         ALOGV("Register loghandler");
1119         int result;
1120         uint32_t event_sock_pid = getpid() + (WIFI_HAL_EVENT_SOCK_PORT << 22);
1121 
1122         WifiRequest request(familyId(), ifaceId());
1123 
1124         /* set hal event socket port to driver */
1125         result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_PID);
1126         if (result != WIFI_SUCCESS) {
1127             ALOGV("Failed to set Hal preInit; result = %d", result);
1128             return result;
1129         }
1130         registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
1131 
1132         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1133         result = request.put_u32(SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID, event_sock_pid);
1134         if (result != WIFI_SUCCESS) {
1135             unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
1136             ALOGV("Hal preInit Failed to put pic = %d", result);
1137             return result;
1138         }
1139 
1140         if (result != WIFI_SUCCESS) {
1141             unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
1142             ALOGV("Hal preInit Failed to put pid= %d", result);
1143             return result;
1144         }
1145 
1146         request.attr_end(data);
1147 
1148         result = requestResponse(request);
1149         if (result != WIFI_SUCCESS) {
1150             unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
1151             ALOGE("Failed to register set Hal preInit; result = %d", result);
1152             return result;
1153         }
1154         return result;
1155     }
1156 
cancel()1157     virtual int cancel() {
1158         /* Send a command to driver to stop generating logging events */
1159         ALOGV("Clear loghandler");
1160 
1161         /* unregister event handler */
1162         unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
1163         wifi_unregister_cmd(wifiHandle(), id());
1164 
1165         WifiRequest request(familyId(), ifaceId());
1166         int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING);
1167         if (result != WIFI_SUCCESS) {
1168             ALOGE("failed to create reset request; result = %d", result);
1169             return result;
1170         }
1171 
1172         result = requestResponse(request);
1173         if (result != WIFI_SUCCESS) {
1174             ALOGE("failed to request reset; result = %d", result);
1175             return result;
1176         }
1177 
1178         ALOGD("Success to clear loghandler");
1179         return WIFI_SUCCESS;
1180     }
1181 
handleEvent(WifiEvent & event)1182     virtual int handleEvent(WifiEvent& event) {
1183         char *buffer = NULL;
1184         int buffer_size = 0;
1185 
1186         // ALOGD("In SetLogHandler::handleEvent");
1187         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1188         int len = event.get_vendor_data_len();
1189         int event_id = event.get_vendor_subcmd();
1190         // ALOGI("Got Logger event: %d", event_id);
1191 
1192         if (vendor_data == NULL || len == 0) {
1193             ALOGE("No Debug data found");
1194             return NL_SKIP;
1195         }
1196 
1197         if (event_id == GOOGLE_DEBUG_RING_EVENT) {
1198             wifi_ring_buffer_status status;
1199             memset(&status, 0, sizeof(status));
1200 
1201             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1202                 if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
1203                     if (it.get_len() > sizeof(wifi_ring_buffer_status)) {
1204                         ALOGE("SetLogHandler: ring status unexpected len = %d, dest len = %lu",
1205                            it.get_len(), sizeof(wifi_ring_buffer_status));
1206                         return NL_SKIP;
1207                     } else {
1208                         memcpy(&status, it.get_data(), sizeof(wifi_ring_buffer_status));
1209                     }
1210                 } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
1211                     buffer_size = it.get_len();
1212                     buffer = (char *)it.get_data();
1213                     ALOGV("SetLogHandler: ring data size = %d", buffer_size);
1214                 } else {
1215                     ALOGW("Ignoring invalid attribute type = %d, size = %d",
1216                             it.get_type(), it.get_len());
1217                 }
1218             }
1219 
1220             // ALOGI("Retrieved Debug data");
1221             if (mHandler.on_ring_buffer_data) {
1222                 /* Skip msg header. Retrieved log */
1223                 char *pBuff;
1224                 int num_entries;
1225                 int cur_off = 0;
1226                 wifi_ring_buffer_entry_pack *pack_hdr =
1227                     (wifi_ring_buffer_entry_pack *)buffer;
1228                 wifi_ring_buffer_entry *entry_hdr =
1229                     (wifi_ring_buffer_entry *)(buffer + sizeof(*pack_hdr));
1230                 cur_off += sizeof(*pack_hdr);
1231 
1232                 if (pack_hdr->magic != WIFI_RING_BUFFER_PACK_MAGIC) {
1233                     ALOGE("SetLogHandler: magic code is not matched "
1234                         "magic:%u ring_name:%s\n", pack_hdr->magic, status.name);
1235                     return NL_SKIP;
1236                 }
1237 
1238                 num_entries = pack_hdr->num_entries;
1239 
1240                 while (num_entries > 0) {
1241                     /* Check for accesses that exceed the total buffer size */
1242                     if (cur_off + sizeof(*entry_hdr) + entry_hdr->entry_size > buffer_size) {
1243                         ALOGE("SetLogHandler: detected invalid access "
1244                             "num_entries:%d cur_num:%d buffer_size:%d cur_off:%d "
1245                             "hdrsize:%lu entry_size:%d ring_name:%s\n",
1246                             pack_hdr->num_entries, num_entries, buffer_size, cur_off,
1247                             sizeof(*entry_hdr), entry_hdr->entry_size, status.name);
1248                         return NL_SKIP;
1249                     }
1250 
1251                     /* Copy buffer without hdr to the ringbuffer in LegacyHAL */
1252                     pBuff = (char *)entry_hdr + sizeof(*entry_hdr);
1253                     (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff,
1254                         entry_hdr->entry_size, &status);
1255 
1256                     cur_off += sizeof(*entry_hdr) + entry_hdr->entry_size;
1257 
1258                     /* jump to next entry_hdr */
1259                     entry_hdr = (wifi_ring_buffer_entry *)((char *)entry_hdr + sizeof(*entry_hdr) + entry_hdr->entry_size);
1260 
1261                     num_entries--;
1262                 }
1263 
1264             }
1265         } else {
1266             ALOGE("Unknown Event");
1267             return NL_SKIP;
1268         }
1269         return NL_OK;
1270     }
1271 };
1272 
wifi_set_log_handler(wifi_request_id id,wifi_interface_handle iface,wifi_ring_buffer_data_handler handler)1273 wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
1274         wifi_ring_buffer_data_handler handler)
1275 {
1276     wifi_handle handle = getWifiHandle(iface);
1277     ALOGE("Loghandler start, handle = %p", handle);
1278 
1279     SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
1280     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1281     wifi_error result = wifi_register_cmd(handle, id, cmd);
1282     if (result != WIFI_SUCCESS) {
1283         cmd->releaseRef();
1284         return result;
1285     }
1286     result = (wifi_error)cmd->start();
1287     if (result != WIFI_SUCCESS) {
1288         wifi_unregister_cmd(handle, id);
1289         cmd->releaseRef();
1290         return result;
1291     }
1292 
1293 #ifdef RING_DUMP
1294     wifi_start_ring_dump(iface, handler);
1295 #endif /* RING_DUMP */
1296     return result;
1297 }
1298 
wifi_reset_log_handler(wifi_request_id id,wifi_interface_handle iface)1299 wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface)
1300 {
1301     wifi_handle handle = getWifiHandle(iface);
1302     ALOGE("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle);
1303 
1304 #ifdef RING_DUMP
1305     wifi_stop_ring_dump(iface);
1306 #endif /* RING_DUMP */
1307 
1308     if (id == -1) {
1309         wifi_ring_buffer_data_handler handler;
1310         memset(&handler, 0, sizeof(handler));
1311 
1312         SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
1313         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1314         cmd->cancel();
1315         cmd->releaseRef();
1316 
1317         return WIFI_SUCCESS;
1318     }
1319 
1320     return wifi_get_cancel_cmd(id, iface);
1321 }
1322 
1323 ///////////////////////////////////////////////////////////////////////////////
1324 class SetAlertHandler : public WifiCommand
1325 {
1326     wifi_alert_handler mHandler;
1327     int mBuffSize;
1328     char *mBuff;
1329     int mErrCode;
1330 
1331 public:
SetAlertHandler(wifi_interface_handle iface,int id,wifi_alert_handler handler)1332     SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler)
1333         : WifiCommand("SetAlertHandler", iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL),
1334             mErrCode(0)
1335     { }
1336 
start()1337     int start() {
1338         ALOGV("Start Alerting");
1339         registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
1340         return WIFI_SUCCESS;
1341     }
1342 
cancel()1343     virtual int cancel() {
1344         ALOGV("Clear alerthandler");
1345 
1346         /* unregister alert handler */
1347         unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
1348         wifi_unregister_cmd(wifiHandle(), id());
1349         ALOGD("Success to clear alerthandler");
1350         return WIFI_SUCCESS;
1351     }
1352 
handleResponse(WifiEvent & reply)1353     virtual int handleResponse(WifiEvent& reply) {
1354         ALOGD("In SetAlertHandler::handleResponse");
1355 
1356         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1357             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1358             return NL_SKIP;
1359         }
1360 
1361         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1362         int len = reply.get_vendor_data_len();
1363 
1364         ALOGD("len = %d", len);
1365         if (vendor_data == NULL || len == 0) {
1366             ALOGE("no vendor data in memory dump response; ignoring it");
1367             return NL_SKIP;
1368         }
1369 
1370         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1371             if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
1372                 ALOGI("Initiating alert callback");
1373                 if (mHandler.on_alert) {
1374                     (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode);
1375                 }
1376                 if (mBuff) {
1377                     free(mBuff);
1378                     mBuff = NULL;
1379                 }
1380             }
1381         }
1382         return NL_OK;
1383     }
1384 
handleEvent(WifiEvent & event)1385     virtual int handleEvent(WifiEvent& event) {
1386         char *buffer = NULL;
1387         int buffer_size = 0;
1388         bool is_err_alert = false;
1389 
1390         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1391         int len = event.get_vendor_data_len();
1392         int event_id = event.get_vendor_subcmd();
1393         ALOGI("Got event: %d", event_id);
1394 
1395         if (vendor_data == NULL || len == 0) {
1396             ALOGE("No Debug data found");
1397             return NL_SKIP;
1398         }
1399 
1400         if (event_id == GOOGLE_DEBUG_MEM_DUMP_EVENT) {
1401             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1402                 if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
1403                     mBuffSize = it.get_u32();
1404                 } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
1405                     buffer_size = it.get_len();
1406                     buffer = (char *)it.get_data();
1407                 } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_ERR_CODE) {
1408                     /* Error code is for error alert event only */
1409                     mErrCode = it.get_u32();
1410                     is_err_alert = true;
1411                 } else {
1412                     ALOGW("Ignoring invalid attribute type = %d, size = %d",
1413                             it.get_type(), it.get_len());
1414                 }
1415             }
1416 
1417             if (is_err_alert) {
1418                 mBuffSize = sizeof(mErrCode);
1419                 if (mBuff) free(mBuff);
1420                 mBuff = (char *)malloc(mBuffSize);
1421                 if (!mBuff) {
1422                   ALOGE("Buffer allocation failed");
1423                   return NL_SKIP;
1424                 }
1425                 memcpy(mBuff, (char *)&mErrCode, mBuffSize);
1426                 ALOGI("Initiating alert callback");
1427                 if (mHandler.on_alert) {
1428                   (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode);
1429                 }
1430                 if (mBuff) {
1431                   free(mBuff);
1432                   mBuff = NULL;
1433                 }
1434                 mBuffSize = 0;
1435                 return NL_OK;
1436             }
1437 
1438             if (mBuffSize) {
1439                 ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size);
1440                 if (mBuff) free(mBuff);
1441                 mBuff = (char *)malloc(mBuffSize + buffer_size);
1442                 if (!mBuff) {
1443                     ALOGE("Buffer allocation failed");
1444                     return NL_SKIP;
1445                 }
1446                 memcpy(mBuff, buffer, buffer_size);
1447 
1448                 WifiRequest request(familyId(), ifaceId());
1449                 int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
1450                 if (result != WIFI_SUCCESS) {
1451                     ALOGE("Failed to create get memory dump request; result = %d", result);
1452                     free(mBuff);
1453                     return NL_SKIP;
1454                 }
1455                 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1456                 result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
1457                 if (result != WIFI_SUCCESS) {
1458                     ALOGE("Failed to put get memory dump request; result = %d", result);
1459                     return result;
1460                 }
1461 
1462                 result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA,
1463                          (uint64_t)(mBuff+buffer_size));
1464                 if (result != WIFI_SUCCESS) {
1465                     ALOGE("Failed to put get memory dump request; result = %d", result);
1466                     return result;
1467                 }
1468 
1469                 request.attr_end(data);
1470                 mBuffSize += buffer_size;
1471 
1472                 result = requestResponse(request);
1473 
1474                 if (result != WIFI_SUCCESS) {
1475                     ALOGE("Failed to register get momory dump response; result = %d", result);
1476                 }
1477             } else {
1478                 ALOGE("dump event missing dump length attribute");
1479                 return NL_SKIP;
1480             }
1481         }
1482         return NL_OK;
1483     }
1484 };
1485 
1486 class SetRestartHandler : public WifiCommand
1487 {
1488     wifi_subsystem_restart_handler mHandler;
1489     char *mBuff;
1490 public:
SetRestartHandler(wifi_handle handle,wifi_request_id id,wifi_subsystem_restart_handler handler)1491     SetRestartHandler(wifi_handle handle, wifi_request_id id, wifi_subsystem_restart_handler handler)
1492         : WifiCommand("SetRestartHandler", handle, id), mHandler(handler), mBuff(NULL)
1493     { }
start()1494     int start() {
1495         ALOGI("Start Restart Handler handler");
1496         registerVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED);
1497         return WIFI_SUCCESS;
1498     }
cancel()1499     virtual int cancel() {
1500         ALOGI("Clear Restart Handler");
1501 
1502         /* unregister alert handler */
1503         unregisterVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED);
1504         wifi_unregister_cmd(wifiHandle(), id());
1505         ALOGI("Success to clear restarthandler");
1506         return WIFI_SUCCESS;
1507     }
1508 
handleResponse(WifiEvent & reply)1509     virtual int handleResponse(WifiEvent& reply) {
1510         /* Nothing to do on response! */
1511         return NL_OK;
1512     }
1513 
handleEvent(WifiEvent & event)1514     virtual int handleEvent(WifiEvent& event) {
1515         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1516         int len = event.get_vendor_data_len();
1517         int event_id = event.get_vendor_subcmd();
1518         ALOGI("Got event: %d", event_id);
1519 
1520         if (vendor_data == NULL || len == 0) {
1521             ALOGE("No Debug data found");
1522             return NL_SKIP;
1523         }
1524         if (event_id == BRCM_VENDOR_EVENT_HANGED) {
1525             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1526                 if (it.get_type() == LOGGER_ATTRIBUTE_HANG_REASON) {
1527                     mBuff = (char *)it.get_data();
1528                 } else {
1529                     ALOGI("Ignoring invalid attribute type = %d, size = %d",
1530                             it.get_type(), it.get_len());
1531                 }
1532             }
1533 
1534             if (*mHandler.on_subsystem_restart) {
1535                 (*mHandler.on_subsystem_restart)(mBuff);
1536                 ALOGI("Hang event received. Trigger SSR handler:%p",
1537                     mHandler.on_subsystem_restart);
1538             } else {
1539                 ALOGI("No Restart handler registered");
1540             }
1541         }
1542         return NL_OK;
1543     }
1544 };
1545 
1546 ///////////////////////////////////////////////////////////////////////////////
1547 class SubSystemRestart : public WifiCommand
1548 {
1549     public:
SubSystemRestart(wifi_interface_handle iface)1550     SubSystemRestart(wifi_interface_handle iface)
1551         : WifiCommand("SubSystemRestart", iface, 0)
1552     { }
1553 
createRequest(WifiRequest & request)1554     int createRequest(WifiRequest& request) {
1555         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_TRIGGER_SSR);
1556         if (result < 0) {
1557             return result;
1558         }
1559 
1560         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1561 
1562         request.attr_end(data);
1563         return WIFI_SUCCESS;
1564     }
1565 
create()1566     int create() {
1567         WifiRequest request(familyId(), ifaceId());
1568 
1569         int result = createRequest(request);
1570         if (result < 0) {
1571             ALOGE("Failed to create ssr request result = %d\n", result);
1572             return result;
1573         }
1574 
1575         result = requestResponse(request);
1576         if (result != WIFI_SUCCESS) {
1577             ALOGE("Failed to register ssr response; result = %d\n", result);
1578         }
1579         return result;
1580     }
1581 
1582     protected:
handleResponse(WifiEvent & reply)1583     int handleResponse(WifiEvent& reply) {
1584         /* Nothing to do on response! */
1585         return NL_OK;
1586     }
1587 
handleEvent(WifiEvent & event)1588     int handleEvent(WifiEvent& event) {
1589         /* NO events to handle here! */
1590         return NL_SKIP;
1591     }
1592 
1593 };
1594 ///////////////////////////////////////////////////////////////////////////////
1595 class HalInit : public WifiCommand
1596 {
1597     int mErrCode;
1598 
1599     public:
HalInit(wifi_interface_handle iface,int id)1600     HalInit(wifi_interface_handle iface, int id)
1601         : WifiCommand("HalInit", iface, id), mErrCode(0)
1602     { }
1603 
start()1604     int start() {
1605         ALOGE("Start Set Hal");
1606         WifiRequest request(familyId(), ifaceId());
1607 
1608         int result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_START);
1609         if (result != WIFI_SUCCESS) {
1610             ALOGE("Failed to set hal start; result = %d", result);
1611             return result;
1612         }
1613 
1614         result = requestResponse(request);
1615         if (result != WIFI_SUCCESS) {
1616             ALOGE("Failed to register set hal start response; result = %d", result);
1617         }
1618         return result;
1619     }
1620 
1621 
cancel()1622     virtual int cancel() {
1623         ALOGE("Cancel: Stop Hal");
1624         WifiRequest request(familyId(), ifaceId());
1625 
1626         int result = request.create(GOOGLE_OUI, LOGGER_HAL_STOP);
1627         if (result != WIFI_SUCCESS) {
1628             ALOGE("Failed to stop hal ; result = %d", result);
1629             return result;
1630         }
1631 
1632         result = requestResponse(request);
1633         if (result != WIFI_SUCCESS) {
1634             ALOGE("Failed to register set hal start response; result = %d", result);
1635         }
1636         wifi_unregister_cmd(wifiHandle(), id());
1637         ALOGE("Stop HAL Successfully Completed, mErrCode = %d\n", mErrCode);
1638         return result;
1639     }
1640 
preInit()1641     int preInit() {
1642         ALOGE("Hal preInit");
1643         WifiRequest request(familyId(), ifaceId());
1644 
1645         int result = request.create(GOOGLE_OUI, LOGGER_SET_HAL_START);
1646         if (result != WIFI_SUCCESS) {
1647             ALOGE("Failed to set Hal preInit; result = %d", result);
1648             return result;
1649         }
1650 
1651         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1652         result = request.put_string(SET_HAL_START_ATTRIBUTE_PRE_INIT, (char *)HAL_VERSION);
1653         if (result != WIFI_SUCCESS) {
1654             ALOGE("Hal preInit Failed to put data= %d", result);
1655             return result;
1656         }
1657         request.attr_end(data);
1658 
1659         result = requestResponse(request);
1660         if (result != WIFI_SUCCESS) {
1661             ALOGE("Failed to register set Hal preInit; result = %d", result);
1662         }
1663         return result;
1664     }
1665 
handleResponse(WifiEvent & reply)1666     virtual int handleResponse(WifiEvent& reply) {
1667         ALOGE("In SetHalStarted::handleResponse");
1668 
1669         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1670             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1671             return NL_SKIP;
1672         }
1673         return NL_OK;
1674     }
1675 
handleEvent(WifiEvent & event)1676     virtual int handleEvent(WifiEvent& event) {
1677         /* NO events! */
1678         return NL_SKIP;
1679     }
1680 };
1681 
1682 #ifdef RING_DUMP
1683 ///////////////////////////////////////////////////////////////////////////////
1684 class RingDump : public WifiCommand
1685 {
1686     int mLargestBuffSize;
1687     char *mBuff;
1688     int mErrCode;
1689     int mNumMaps;
1690     wifi_buf_ring_map_entry_t *mMap;
1691     int attr_type_len[DUMP_EVENT_ATTR_MAX];
1692     char *ring_name[DUMP_BUF_ATTR_MAX];
1693     wifi_ring_buffer_data_handler mHandle;
1694 
1695 public:
RingDump(wifi_interface_handle iface,int id,int num_maps,wifi_buf_ring_map_entry_t * map,wifi_ring_buffer_data_handler ring_handle)1696     RingDump(wifi_interface_handle iface, int id, int num_maps, wifi_buf_ring_map_entry_t *map,
1697         wifi_ring_buffer_data_handler ring_handle)
1698         : WifiCommand("RingDump", iface, id), mLargestBuffSize(0), mBuff(NULL),
1699         mErrCode(0), mNumMaps(num_maps), mMap(map), mHandle(ring_handle)
1700     {
1701         memset(attr_type_len, 0, sizeof(attr_type_len));
1702         for (int i = 0; i < DUMP_BUF_ATTR_MAX; i++) {
1703             ring_name[i] = NULL;
1704         }
1705     }
RingDump(wifi_interface_handle iface,int id)1706     RingDump(wifi_interface_handle iface, int id)
1707         : WifiCommand("RingDump", iface, id), mLargestBuffSize(0), mBuff(NULL),
1708         mErrCode(0)
1709     {
1710         mMap = NULL;
1711         mNumMaps = 0;
1712         memset(&mHandle, 0, sizeof(wifi_ring_buffer_data_handler));
1713         for (int i = 0; i < DUMP_BUF_ATTR_MAX; i++) {
1714             ring_name[i] = NULL;
1715         }
1716     }
1717 
start()1718     int start() {
1719         DUMP_INFO(("Start Ring Dump Map_cnt %d, register the event\n", mNumMaps));
1720         registerVendorHandler(GOOGLE_OUI, GOOGLE_FILE_DUMP_EVENT);
1721 
1722         //Set ringname to buf hashmap
1723         for (int i = 0; i < mNumMaps; i++) {
1724             int type = mMap[i].type;
1725             ring_name[type] = (char *)malloc(DBGRING_NAME_MAX);
1726             memset(ring_name[type], 0, DBGRING_NAME_MAX);
1727             memcpy(ring_name[type], mMap[i].ring_name, strlen(mMap[i].ring_name));
1728             DUMP_DEBUG(("Set ringname Buf:%s Ringname:%s len:%lu",
1729                 EWP_CmdAttrToString(type), ring_name[type], strlen(mMap[i].ring_name)));
1730         }
1731         return WIFI_SUCCESS;
1732     }
1733 
freeup()1734     virtual int freeup() {
1735         DUMP_DEBUG(("freeup:Enter\n"));
1736         if (mBuff) {
1737             free(mBuff);
1738             mBuff = NULL;
1739             DUMP_INFO(("freed allocated memory and the handler\n"));
1740         }
1741         return WIFI_SUCCESS;
1742     }
1743 
cancel()1744     virtual int cancel() {
1745         /* unregister file dump handler */
1746         unregisterVendorHandler(GOOGLE_OUI, GOOGLE_FILE_DUMP_EVENT);
1747         wifi_unregister_cmd(wifiHandle(), id());
1748 
1749         /* Free up the ring names allocated */
1750         for (u8 i = 0; i < DUMP_BUF_ATTR_MAX; i++) {
1751             if (ring_name[i]) {
1752                 free(ring_name[i]);
1753                 ring_name[i] = NULL;
1754             }
1755         }
1756         memset(&mHandle, 0, sizeof(wifi_ring_buffer_data_handler));
1757 
1758         DUMP_INFO(("Stop Ring Dump Successfully Completed, mErrCode = %d\n", mErrCode));
1759         return WIFI_SUCCESS;
1760     }
1761 
handleResponse(WifiEvent & reply)1762     virtual int handleResponse(WifiEvent& reply) {
1763         DUMP_DEBUG(("RingDump::handleResponse\n"));
1764         int buf_attr = DUMP_BUF_ATTR_INVALID;
1765         int len_attr = DUMP_LEN_ATTR_INVALID;
1766         int index = -1;
1767 
1768         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1769             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1770             return NL_SKIP;
1771         }
1772 
1773         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1774         int len = reply.get_vendor_data_len();
1775 
1776         if (vendor_data == NULL || len == 0) {
1777             ALOGE("no vendor data in memory dump response; ignoring it");
1778             return NL_SKIP;
1779         }
1780 
1781         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1782             buf_attr = it.get_type();
1783             switch (buf_attr) {
1784                 case DUMP_BUF_ATTR_MEMDUMP:
1785                 case DUMP_BUF_ATTR_TIMESTAMP:
1786                 case DUMP_BUF_ATTR_ECNTRS:
1787                 case DUMP_BUF_ATTR_DHD_DUMP:
1788                 case DUMP_BUF_ATTR_EXT_TRAP:
1789                 case DUMP_BUF_ATTR_HEALTH_CHK:
1790                 case DUMP_BUF_ATTR_COOKIE:
1791                 case DUMP_BUF_ATTR_FLOWRING_DUMP:
1792                 case DUMP_BUF_ATTR_STATUS_LOG:
1793                 case DUMP_BUF_ATTR_RTT_LOG:
1794                 case DUMP_BUF_ATTR_PKTID_MAP_LOG:
1795                 case DUMP_BUF_ATTR_PKTID_UNMAP_LOG: {
1796                     if (it.get_u32()) {
1797                         ALOGE("Copying data to userspace failed, status = %d\n", it.get_u32());
1798                         return WIFI_ERROR_UNKNOWN;
1799                     }
1800                     index = logger_attr_buffer_lookup(buf_attr);
1801                     if (index == -1) {
1802                         ALOGE("Invalid index. buf attr = %s\n", EWP_CmdAttrToString(buf_attr));
1803                         return WIFI_ERROR_UNKNOWN;
1804                     }
1805                     len_attr = attr_lookup_tbl[index].attr_type;
1806                     if (len_attr == DUMP_EVENT_ATTR_MAX) {
1807                         ALOGE("Invalid len attr = %s\n", EWP_EventAttrToString(len_attr));
1808                         return WIFI_ERROR_UNKNOWN;
1809                     }
1810                     if (!mBuff || attr_type_len[len_attr] <= 0) {
1811                         return WIFI_ERROR_UNKNOWN;
1812                     }
1813 
1814                     if (!ring_name[buf_attr]) {
1815                         ALOGE("Not allocated buf attr = %s\n", EWP_CmdAttrToString(buf_attr));
1816                         return WIFI_ERROR_UNKNOWN;
1817                     }
1818                     DUMP_INFO(("RingDump:: buf_attr:%s size = %d ring_name:%s\n",
1819                         EWP_CmdAttrToString(buf_attr), attr_type_len[len_attr],
1820                         ring_name[buf_attr]));
1821                     if (mHandle.on_ring_buffer_data) {
1822                         /* on_ring_buffer_data callback requires status memory
1823                          * so should pass status memory */
1824                         wifi_ring_buffer_status status;
1825                         memset(&status, 0, sizeof(status));
1826                         /* Skip msg header. Retrieved log */
1827                         (*mHandle.on_ring_buffer_data)(ring_name[buf_attr], mBuff,
1828                             attr_type_len[len_attr], &status);
1829                     } else {
1830                         DUMP_INFO(("RingDump: Retrieved Invalid mHandle\n"));
1831                         break;
1832                     }
1833                     ALOGI("Notified RingDump data of buf attr = %s\n", EWP_CmdAttrToString(buf_attr));
1834                     if (mBuff) {
1835                         memset(mBuff, 0, mLargestBuffSize);
1836                     }
1837                     break;
1838                 }
1839                 default: {
1840                     DUMP_DEBUG(("Ignoring invalid attribute buf_attr = %d, size = %d",
1841                         buf_attr, it.get_len()));
1842                     break;
1843                 }
1844             }
1845         }
1846         return NL_OK;
1847     }
1848 
request_logger_dump(WifiRequest & request,buf_data_t * buf,int len_attr)1849     virtual int request_logger_dump(WifiRequest& request,
1850             buf_data_t *buf, int len_attr) {
1851 
1852         int result = 0;
1853         int buf_attr = DUMP_BUF_ATTR_INVALID;
1854         int index = -1;
1855         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1856 
1857         index = logger_attr_lookup(len_attr);
1858         if (index == -1) {
1859             ALOGE("Invalid index\n");
1860             return WIFI_ERROR_UNKNOWN;
1861         }
1862         buf_attr = attr_lookup_tbl[index].buf_attr;
1863 
1864         if (buf_attr != DUMP_BUF_ATTR_INVALID) {
1865             result = request.put(buf_attr, buf, sizeof(buf_data_t));
1866             if (result != WIFI_SUCCESS) {
1867                 ALOGE("Failed to put get memory dump request; result = %d", result);
1868                 return result;
1869             }
1870         } else {
1871             ALOGE("Invalid buf attr = %s, index = %d\n",
1872                 EWP_CmdAttrToString(buf_attr), index);
1873             return WIFI_ERROR_UNKNOWN;
1874         }
1875         DUMP_INFO(("Trigger get ring dump for buf attr = %s\n",
1876                 EWP_CmdAttrToString(buf_attr)));
1877 
1878         request.attr_end(data);
1879         return result;
1880     }
1881 
handleEvent(WifiEvent & event)1882     virtual int handleEvent(WifiEvent& event) {
1883         mLargestBuffSize = 0;
1884         mBuff = NULL;
1885         memset(attr_type_len, 0, sizeof(attr_type_len));
1886         u8 i = 0;
1887         int result = 0;
1888         int mActualBuffSize = 0;
1889         int index = -1;
1890 
1891         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1892         int len = event.get_vendor_data_len();
1893         int event_id = event.get_vendor_subcmd();
1894         int req_attr_cnt = 0;
1895         int req_attr[DUMP_EVENT_ATTR_MAX];
1896         int buf_attr = DUMP_BUF_ATTR_INVALID;
1897 
1898         if (vendor_data == NULL || len == 0) {
1899             ALOGE("No Debug data found");
1900             return NL_SKIP;
1901         }
1902         DUMP_INFO(("Ring Dump handler. Got event: %d", event_id));
1903 
1904         buf_data_t buf;
1905 
1906         memset(&buf, 0, sizeof(buf_data_t));
1907         buf.ver = 0;
1908         buf.buf_threshold = 0;
1909 
1910         if (event_id == GOOGLE_FILE_DUMP_EVENT) {
1911             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1912                 int attr = it.get_type();
1913                 switch (attr) {
1914                     case DUMP_LEN_ATTR_MEMDUMP:
1915                     case DUMP_LEN_ATTR_TIMESTAMP:
1916                     case DUMP_LEN_ATTR_ECNTRS:
1917                     case DUMP_LEN_ATTR_DHD_DUMP:
1918                     case DUMP_LEN_ATTR_EXT_TRAP:
1919                     case DUMP_LEN_ATTR_HEALTH_CHK:
1920                     case DUMP_LEN_ATTR_COOKIE:
1921                     case DUMP_LEN_ATTR_FLOWRING_DUMP:
1922                     case DUMP_LEN_ATTR_STATUS_LOG:
1923                     case DUMP_LEN_ATTR_RTT_LOG:
1924                     case DUMP_LEN_ATTR_PKTID_MAP_LOG:
1925                     case DUMP_LEN_ATTR_PKTID_UNMAP_LOG: {
1926                         mActualBuffSize = it.get_u32();
1927                         DUMP_DEBUG(("len attr %s, len %d\n",
1928                             EWP_EventAttrToString(attr), mActualBuffSize));
1929                         if (mActualBuffSize > mLargestBuffSize) {
1930                             mLargestBuffSize = mActualBuffSize;
1931                         }
1932                         attr_type_len[attr] = mActualBuffSize;
1933 
1934                         /* Store the order in which attributes are received
1935                          * so that file dump can be done in the same order
1936                          */
1937                         req_attr[req_attr_cnt++] = attr;
1938                         break;
1939                     }
1940                     default: {
1941                         ALOGE("RingDump: Ignoring invalid attribute type = %d, size = %d",
1942                             attr, it.get_len());
1943                             break;
1944                         }
1945                 }
1946             }
1947             /* Allocation for the largest buffer size to use it recursively for other buf attr. */
1948             if (mLargestBuffSize) {
1949                 DUMP_INFO(("Max dump size: %d", mLargestBuffSize));
1950                 mBuff = (char *)malloc(mLargestBuffSize);
1951                 if (!mBuff) {
1952                     ALOGE("Buffer allocation failed");
1953                     return NL_SKIP;
1954                 }
1955                 memset(mBuff, 0, mLargestBuffSize);
1956             }
1957 
1958             WifiRequest request(familyId(), ifaceId());
1959             result = request.create(GOOGLE_OUI, LOGGER_DEBUG_GET_DUMP);
1960             if (result != WIFI_SUCCESS) {
1961                 ALOGE("Failed to create get memory dump request; result = %d", result);
1962                 freeup();
1963                 goto exit;
1964             }
1965 
1966             /* Requesting logger dump for each received attr */
1967             for (i = 0; i < req_attr_cnt; i++) {
1968                 int attr = req_attr[i];
1969 
1970                 if (attr_type_len[attr] == 0) {
1971                     continue;
1972                 }
1973 
1974                 index = logger_attr_lookup(attr);
1975                 if (index == -1) {
1976                     ALOGE("Invalid index\n");
1977                     return WIFI_ERROR_UNKNOWN;
1978                 }
1979 
1980                 buf_attr = attr_lookup_tbl[index].buf_attr;
1981                 if (!ring_name[buf_attr]) {
1982                     ALOGE("Failed to find ringname index:%d buf_attr:%d", index, buf_attr);
1983                     continue;
1984                 }
1985 
1986                 buf.len = attr_type_len[attr];
1987                 buf.data_buf[0] = mBuff;
1988                 DUMP_DEBUG(("buf len = %d, buf ptr= %p for attr = %s\n",
1989                     buf.len, buf.data_buf[0], EWP_EventAttrToString(attr)));
1990                 result = request_logger_dump(request, &buf, attr);
1991                 if (result != WIFI_SUCCESS) {
1992                     /* Proceeding further for other attributes */
1993                     ALOGE("Failed to request the ring dump for attr = %s; result = %d",
1994                         EWP_EventAttrToString(attr), result);
1995                     continue;
1996                 }
1997                 result = requestResponse(request);
1998                 if (result != WIFI_SUCCESS) {
1999                     ALOGE("Failed to register get ring dump response for attr = %s; result = %d",
2000                         EWP_EventAttrToString(attr), result);
2001                         /* Proceeding further for other attributes */
2002                         continue;
2003                 }
2004                 ALOGI("Success to send up the ring dump response for attr = %s; result = %d",
2005                     EWP_EventAttrToString(attr), result);
2006             }
2007 
2008             ALOGI("RingDump response is sent, proceed to done indication");
2009             WifiRequest request2(familyId(), ifaceId());
2010             result = request2.create(GOOGLE_OUI, LOGGER_FILE_DUMP_DONE_IND);
2011             if (result != WIFI_SUCCESS) {
2012                 ALOGE("Failed to indicate FILE_DUMP_DONE_IND; result = %d", result);
2013                 freeup();
2014                 goto exit;
2015             }
2016             result = requestResponse(request2);
2017             if (result != WIFI_SUCCESS) {
2018                 ALOGE("Failed to register file done ind response; result = %d", result);
2019             }
2020             freeup();
2021         } else {
2022             ALOGE("dump event missing dump length attribute");
2023             return NL_SKIP;
2024         }
2025     exit:
2026         if (result != WIFI_SUCCESS) {
2027             return NL_SKIP;
2028         }
2029         return NL_OK;
2030     }
2031 };
2032 ///////////////////////////////////////////////////////////////////////////////
2033 #endif /* RING_DUMP */
2034 
wifi_start_hal(wifi_interface_handle iface)2035 wifi_error wifi_start_hal(wifi_interface_handle iface)
2036 {
2037     wifi_handle handle = getWifiHandle(iface);
2038     ALOGV("HAL INIT start, handle = %p", handle);
2039 
2040     HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID);
2041     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2042     wifi_error result = wifi_register_cmd(handle, HAL_START_REQUEST_ID, cmd);
2043     if (result != WIFI_SUCCESS) {
2044         cmd->releaseRef();
2045         return result;
2046     }
2047     result = (wifi_error)cmd->start();
2048     if (result != WIFI_SUCCESS) {
2049         wifi_unregister_cmd(handle, HAL_START_REQUEST_ID);
2050         cmd->releaseRef();
2051         return result;
2052     }
2053     return result;
2054 }
2055 
wifi_hal_preInit(wifi_interface_handle iface)2056 wifi_error wifi_hal_preInit(wifi_interface_handle iface)
2057 {
2058     wifi_handle handle = getWifiHandle(iface);
2059     ALOGV("wifi_hal_preInit, handle = %p", handle);
2060 
2061     HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID);
2062     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2063     wifi_error result = wifi_register_cmd(handle, HAL_START_REQUEST_ID, cmd);
2064     if (result != WIFI_SUCCESS) {
2065         cmd->releaseRef();
2066         return result;
2067     }
2068     result = (wifi_error)cmd->preInit();
2069     if (result != WIFI_SUCCESS) {
2070         wifi_unregister_cmd(handle, HAL_START_REQUEST_ID);
2071         cmd->releaseRef();
2072         return result;
2073     }
2074     return result;
2075 }
2076 
2077 #ifdef RING_DUMP
wifi_start_ring_dump(wifi_interface_handle iface,wifi_ring_buffer_data_handler ring_handle)2078 wifi_error wifi_start_ring_dump(wifi_interface_handle iface,
2079     wifi_ring_buffer_data_handler ring_handle)
2080 {
2081     wifi_handle handle = getWifiHandle(iface);
2082     DUMP_INFO(("start ring dump, handle = %p, ring_handle = %p", handle, ring_handle));
2083     wifi_buf_ring_map_entry_t map[DUMP_BUF_ATTR_MAX];
2084     unsigned int num_maps = DUMP_BUF_ATTR_MAX;
2085     wifi_error result;
2086 
2087     /* Get mapping table from driver */
2088     DebugCommand *debug_cmd = new DebugCommand(iface, &num_maps, map, GET_BUF_RING_MAP);
2089     NULL_CHECK_RETURN(debug_cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2090     result = (wifi_error)debug_cmd->start();
2091     debug_cmd->releaseRef();
2092 
2093     /* Set ringname to corresponding buf attr */
2094     DUMP_INFO(("Cached ring_handle: %p for RingDump", ring_handle));
2095     RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID, num_maps, map, ring_handle);
2096     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2097     result = wifi_register_cmd(handle, FILE_DUMP_REQUEST_ID, cmd);
2098     if (result != WIFI_SUCCESS) {
2099         cmd->releaseRef();
2100         return result;
2101     }
2102 
2103     result = (wifi_error)cmd->start();
2104     if (result != WIFI_SUCCESS) {
2105         wifi_unregister_cmd(handle, FILE_DUMP_REQUEST_ID);
2106         cmd->releaseRef();
2107         return result;
2108     }
2109     return result;
2110 }
2111 
wifi_stop_ring_dump(wifi_interface_handle iface)2112 wifi_error wifi_stop_ring_dump(wifi_interface_handle iface)
2113 {
2114     RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID);
2115     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2116     DUMP_INFO(("stop ring dump"));
2117     cmd->cancel();
2118     cmd->releaseRef();
2119     return WIFI_SUCCESS;
2120 }
2121 #endif /* RING_DUMP */
2122 
wifi_stop_hal(wifi_interface_handle iface)2123 wifi_error wifi_stop_hal(wifi_interface_handle iface)
2124 {
2125     HalInit *cmd = new HalInit(iface, HAL_START_REQUEST_ID);
2126     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2127     cmd->cancel();
2128     cmd->releaseRef();
2129     return WIFI_SUCCESS;
2130 }
2131 
2132 
wifi_set_subsystem_restart_handler(wifi_handle handle,wifi_subsystem_restart_handler handler)2133 wifi_error wifi_set_subsystem_restart_handler(wifi_handle handle,
2134                                               wifi_subsystem_restart_handler handler)
2135 {
2136     hal_info *info = NULL;
2137 
2138     info = (hal_info *)handle;
2139     if (info == NULL) {
2140         ALOGE("Could not find hal info\n");
2141         return WIFI_ERROR_UNKNOWN;
2142     }
2143 
2144     SetRestartHandler *cmd = new SetRestartHandler(handle, HAL_RESTART_ID, handler);
2145     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2146     wifi_error result = wifi_register_cmd(handle, HAL_RESTART_ID, cmd);
2147     if (result != WIFI_SUCCESS) {
2148         cmd->releaseRef();
2149         return result;
2150     }
2151 
2152     result = (wifi_error)cmd->start();
2153     if (result != WIFI_SUCCESS) {
2154         wifi_unregister_cmd(handle, HAL_RESTART_ID);
2155         cmd->releaseRef();
2156         return result;
2157     }
2158 
2159     /* Cache the handler to use it for trigger subsystem restart */
2160     ALOGI("Register SSR handler");
2161     info->restart_handler = handler;
2162     return result;
2163 }
2164 
wifi_trigger_subsystem_restart(wifi_handle handle)2165 wifi_error wifi_trigger_subsystem_restart(wifi_handle handle)
2166 {
2167     wifi_error result = WIFI_SUCCESS;
2168     hal_info *info = NULL;
2169     char error_str[20];
2170     SubSystemRestart *cmd = NULL;
2171     wifi_interface_handle *ifaceHandles = NULL;
2172     wifi_interface_handle wlan0Handle;
2173     int numIfaceHandles = 0;
2174 
2175     info = (hal_info *)handle;
2176     if (handle == NULL || info == NULL) {
2177         ALOGE("Could not find hal info\n");
2178         result = WIFI_ERROR_UNKNOWN;
2179         goto exit;
2180     }
2181 
2182     ALOGI("Trigger subsystem restart\n");
2183 
2184     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2185 
2186     cmd = new SubSystemRestart(wlan0Handle);
2187     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2188 
2189     result = (wifi_error)cmd->create();
2190     if (result != WIFI_SUCCESS) {
2191         cmd->releaseRef();
2192         strncpy(error_str, "WIFI_ERROR_UNKNOWN", sizeof(error_str));
2193         ALOGE("Failed to create SSR");
2194         goto exit;
2195     }
2196 
2197     strncpy(error_str, "WIFI_SUCCESS", sizeof(error_str));
2198 
2199 exit:
2200     if (info->restart_handler.on_subsystem_restart) {
2201         ALOGI("Trigger ssr handler registered handler:%p",
2202             info->restart_handler.on_subsystem_restart);
2203         (info->restart_handler.on_subsystem_restart)(error_str);
2204     } else {
2205         ALOGI("No trigger ssr handler registered");
2206     }
2207 
2208     return result;
2209 }
2210 
wifi_set_alert_handler(wifi_request_id id,wifi_interface_handle iface,wifi_alert_handler handler)2211 wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
2212         wifi_alert_handler handler)
2213 {
2214     wifi_handle handle = getWifiHandle(iface);
2215     ALOGV("Alerthandler start, handle = %p", handle);
2216 
2217     SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
2218     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2219     wifi_error result = wifi_register_cmd(handle, id, cmd);
2220     if (result != WIFI_SUCCESS) {
2221         cmd->releaseRef();
2222         return result;
2223     }
2224     result = (wifi_error)cmd->start();
2225     if (result != WIFI_SUCCESS) {
2226         wifi_unregister_cmd(handle, id);
2227         cmd->releaseRef();
2228         return result;
2229     }
2230     return result;
2231 }
2232 
wifi_reset_alert_handler(wifi_request_id id,wifi_interface_handle iface)2233 wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface)
2234 {
2235     wifi_handle handle = getWifiHandle(iface);
2236     ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle);
2237 
2238     if (id == -1) {
2239         wifi_alert_handler handler;
2240         memset(&handler, 0, sizeof(handler));
2241 
2242         SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
2243         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2244         cmd->cancel();
2245         cmd->releaseRef();
2246         return WIFI_SUCCESS;
2247     }
2248 
2249     return wifi_get_cancel_cmd(id, iface);
2250 }
2251 
2252 ///////////////////////////////////////////////////////////////////////////////
2253 class MemoryDumpCommand: public WifiCommand
2254 {
2255     wifi_firmware_memory_dump_handler mHandler;
2256     int mBuffSize;
2257     char *mBuff;
2258 
2259 public:
MemoryDumpCommand(wifi_interface_handle iface,wifi_firmware_memory_dump_handler handler)2260     MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler)
2261         : WifiCommand("MemoryDumpCommand", iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL)
2262     { }
2263 
start()2264     int start() {
2265         ALOGD("Start memory dump command");
2266         WifiRequest request(familyId(), ifaceId());
2267 
2268         int result = request.create(GOOGLE_OUI, LOGGER_TRIGGER_MEM_DUMP);
2269         if (result != WIFI_SUCCESS) {
2270             ALOGE("Failed to create trigger fw memory dump request; result = %d", result);
2271             return result;
2272         }
2273 
2274         result = requestResponse(request);
2275         if (result != WIFI_SUCCESS) {
2276             ALOGE("Failed to register trigger memory dump response; result = %d", result);
2277         }
2278         return result;
2279     }
2280 
handleResponse(WifiEvent & reply)2281     virtual int handleResponse(WifiEvent& reply) {
2282         ALOGD("In MemoryDumpCommand::handleResponse");
2283 
2284         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2285             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2286             return NL_SKIP;
2287         }
2288 
2289         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2290         int len = reply.get_vendor_data_len();
2291 
2292         ALOGD("len = %d", len);
2293         if (vendor_data == NULL || len == 0) {
2294             ALOGE("no vendor data in memory dump response; ignoring it");
2295             return NL_SKIP;
2296         }
2297 
2298         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2299             if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
2300                 mBuffSize = it.get_u32();
2301 
2302                 if (mBuff)
2303                     free(mBuff);
2304                 mBuff = (char *)malloc(mBuffSize);
2305                 if (!mBuff) {
2306                     ALOGE("Buffer allocation failed");
2307                     return NL_SKIP;
2308                 }
2309                 WifiRequest request(familyId(), ifaceId());
2310                 int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
2311                 if (result != WIFI_SUCCESS) {
2312                     ALOGE("Failed to create get memory dump request; result = %d", result);
2313                     free(mBuff);
2314                     return NL_SKIP;
2315                 }
2316 
2317                 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2318                 result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
2319                 if (result != WIFI_SUCCESS) {
2320                     ALOGE("Failed to put get memory dump request; result = %d", result);
2321                     return result;
2322                 }
2323 
2324                 result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff);
2325                 if (result != WIFI_SUCCESS) {
2326                     ALOGE("Failed to put get memory dump request; result = %d", result);
2327                     return result;
2328                 }
2329                 request.attr_end(data);
2330 
2331                 result = requestResponse(request);
2332                 if (result != WIFI_SUCCESS) {
2333                     ALOGE("Failed to register get momory dump response; result = %d", result);
2334                 }
2335             } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
2336                 ALOGI("Initiating memory dump callback");
2337                 if (mHandler.on_firmware_memory_dump) {
2338                     (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize);
2339                 }
2340                 if (mBuff) {
2341                     free(mBuff);
2342                     mBuff = NULL;
2343                 }
2344             } else {
2345                 ALOGW("Ignoring invalid attribute type = %d, size = %d",
2346                         it.get_type(), it.get_len());
2347             }
2348         }
2349         return NL_OK;
2350     }
2351 
handleEvent(WifiEvent & event)2352     virtual int handleEvent(WifiEvent& event) {
2353         /* NO events! */
2354         return NL_SKIP;
2355     }
2356 };
2357 
2358 /* API to collect a firmware memory dump for a given iface */
wifi_get_firmware_memory_dump(wifi_interface_handle iface,wifi_firmware_memory_dump_handler handler)2359 wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface,
2360         wifi_firmware_memory_dump_handler handler)
2361 {
2362     MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler);
2363     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2364     wifi_error result = (wifi_error)cmd->start();
2365     cmd->releaseRef();
2366     return result;
2367 }
2368 
2369 class PacketFateCommand: public WifiCommand
2370 {
2371     void *mReportBufs;
2372     size_t mNoReqFates;
2373     size_t *mNoProvidedFates;
2374     PktFateReqType mReqType;
2375 
2376 public:
PacketFateCommand(wifi_interface_handle handle)2377     PacketFateCommand(wifi_interface_handle handle)
2378         : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START)
2379     {
2380         mReportBufs = NULL;
2381         mNoReqFates = 0;
2382         mNoProvidedFates = NULL;
2383     }
2384 
PacketFateCommand(wifi_interface_handle handle,wifi_tx_report * tx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)2385     PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs,
2386             size_t n_requested_fates, size_t *n_provided_fates)
2387         : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs),
2388                   mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
2389                   mReqType(TX_PACKET_FATE)
2390     { }
2391 
PacketFateCommand(wifi_interface_handle handle,wifi_rx_report * rx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)2392     PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs,
2393             size_t n_requested_fates, size_t *n_provided_fates)
2394         : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs),
2395                   mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
2396                   mReqType(RX_PACKET_FATE)
2397     { }
2398 
createRequest(WifiRequest & request)2399     int createRequest(WifiRequest& request) {
2400         if (mReqType == TX_PACKET_FATE) {
2401             ALOGD("%s Get Tx packet fate request\n", __FUNCTION__);
2402             return createTxPktFateRequest(request);
2403         } else if (mReqType == RX_PACKET_FATE) {
2404             ALOGD("%s Get Rx packet fate request\n", __FUNCTION__);
2405             return createRxPktFateRequest(request);
2406         } else if (mReqType == PACKET_MONITOR_START) {
2407             ALOGD("%s Monitor packet fate request\n", __FUNCTION__);
2408             return createMonitorPktFateRequest(request);
2409         } else {
2410             ALOGE("%s Unknown packet fate request\n", __FUNCTION__);
2411             return WIFI_ERROR_NOT_SUPPORTED;
2412         }
2413         return WIFI_SUCCESS;
2414     }
2415 
createMonitorPktFateRequest(WifiRequest & request)2416     int createMonitorPktFateRequest(WifiRequest& request) {
2417         int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING);
2418         if (result < 0) {
2419             ALOGE("Failed to create monitorPktFate result:%d\n", result);
2420             return result;
2421         }
2422 
2423         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2424         request.attr_end(data);
2425         return result;
2426     }
2427 
createTxPktFateRequest(WifiRequest & request)2428     int createTxPktFateRequest(WifiRequest& request) {
2429         int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES);
2430         if (result < 0) {
2431             ALOGE("Failed to create TxPktFate result:%d\n", result);
2432             return result;
2433         }
2434 
2435         memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report)));
2436         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2437         result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
2438         if (result < 0) {
2439             ALOGE("Failed to set TxPktFate num result:%d mNoReqFates:%d\n", result, mNoReqFates);
2440             return result;
2441         }
2442         result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
2443         if (result < 0) {
2444             ALOGE("Failed to set TxPktFate buf result:%d\n", result);
2445             return result;
2446         }
2447         request.attr_end(data);
2448         return result;
2449     }
2450 
createRxPktFateRequest(WifiRequest & request)2451     int createRxPktFateRequest(WifiRequest& request) {
2452         int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES);
2453         if (result < 0) {
2454             ALOGE("Failed to create RxPktFate result:%d\n", result);
2455             return result;
2456         }
2457 
2458         memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report)));
2459         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2460         result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
2461         if (result < 0) {
2462             ALOGE("Failed to set RxPktFate num result:%d mNoReqFates:%d\n", result, mNoReqFates);
2463             return result;
2464         }
2465         result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
2466         if (result < 0) {
2467             ALOGE("Failed to set RxPktFate buf result:%d\n", result);
2468             return result;
2469         }
2470         request.attr_end(data);
2471         return result;
2472     }
2473 
start()2474     int start() {
2475         ALOGD("Start get packet fate command\n");
2476         WifiRequest request(familyId(), ifaceId());
2477 
2478         int result = createRequest(request);
2479         if (result < 0) {
2480             ALOGE("Failed to create get pkt fate request; result = %d\n", result);
2481             return result;
2482         }
2483 
2484         result = requestResponse(request);
2485         if (result != WIFI_SUCCESS) {
2486             ALOGE("Failed to register get pkt fate response; result = %d\n", result);
2487         }
2488         return result;
2489     }
2490 
handleResponse(WifiEvent & reply)2491     int handleResponse(WifiEvent& reply) {
2492         ALOGD("In GetPktFateCommand::handleResponse\n");
2493 
2494         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2495             ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());
2496             return NL_SKIP;
2497         }
2498 
2499         int id = reply.get_vendor_id();
2500         int subcmd = reply.get_vendor_subcmd();
2501         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2502         int len = reply.get_vendor_data_len();
2503 
2504         ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
2505 
2506         if (mReqType == TX_PACKET_FATE) {
2507             ALOGI("Response recieved for get TX pkt fate command\n");
2508         } else if (mReqType == RX_PACKET_FATE) {
2509             ALOGI("Response recieved for get RX pkt fate command\n");
2510         } else if (mReqType == PACKET_MONITOR_START) {
2511             ALOGI("Response recieved for monitor pkt fate command\n");
2512             return NL_OK;
2513         } else {
2514             ALOGE("Response recieved for unknown pkt fate command\n");
2515             return NL_SKIP;
2516         }
2517 
2518         if (vendor_data == NULL || len == 0) {
2519             ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");
2520             return NL_SKIP;
2521         }
2522 
2523         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2524             if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) {
2525                 *mNoProvidedFates = it.get_u32();
2526                 ALOGI("No: of pkt fates provided is %zu\n", *mNoProvidedFates);
2527             } else {
2528                 ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
2529                         it.get_type(), it.get_len());
2530             }
2531         }
2532 
2533         return NL_OK;
2534     }
2535 
handleEvent(WifiEvent & event)2536     int handleEvent(WifiEvent& event) {
2537         /* NO events to handle here! */
2538         return NL_SKIP;
2539     }
2540 };
2541 
2542 class GetWakeReasonCountCommand : public WifiCommand {
2543     WLAN_DRIVER_WAKE_REASON_CNT *mWakeReasonCnt;
2544     void *mCmdEventWakeCount;
2545     public:
GetWakeReasonCountCommand(wifi_interface_handle handle,WLAN_DRIVER_WAKE_REASON_CNT * wlanDriverWakeReasonCount)2546     GetWakeReasonCountCommand(wifi_interface_handle handle,
2547         WLAN_DRIVER_WAKE_REASON_CNT *wlanDriverWakeReasonCount) :
2548         WifiCommand("GetWakeReasonCountCommand", handle, 0),
2549         mWakeReasonCnt(wlanDriverWakeReasonCount)
2550     {
2551         mCmdEventWakeCount = mWakeReasonCnt->cmd_event_wake_cnt;
2552     }
2553 
createRequest(WifiRequest & request)2554     int createRequest(WifiRequest& request) {
2555         int result = request.create(GOOGLE_OUI, LOGGER_GET_WAKE_REASON_STATS);
2556         if (result < 0) {
2557             return result;
2558         }
2559 
2560         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2561 
2562         request.attr_end(data);
2563         return WIFI_SUCCESS;
2564     }
2565 
start()2566     int start() {
2567         ALOGD("Start get wake stats command\n");
2568         WifiRequest request(familyId(), ifaceId());
2569 
2570         int result = createRequest(request);
2571         if (result < 0) {
2572             ALOGE("Failed to create request result = %d\n", result);
2573             return result;
2574         }
2575 
2576         result = requestResponse(request);
2577         if (result != WIFI_SUCCESS) {
2578             ALOGE("Failed to register wake stats  response; result = %d\n", result);
2579         }
2580         return result;
2581     }
2582 
2583     protected:
handleResponse(WifiEvent & reply)2584     int handleResponse(WifiEvent& reply) {
2585         ALOGE("In GetWakeReasonCountCommand::handleResponse");
2586 
2587         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2588             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2589             return NL_SKIP;
2590         }
2591 
2592         int id = reply.get_vendor_id();
2593         int subcmd = reply.get_vendor_subcmd();
2594 
2595         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2596         int len = reply.get_vendor_data_len();
2597 
2598         ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
2599         if (vendor_data == NULL || len == 0) {
2600             ALOGE("no vendor data in GetGetWakeReasonCountCommand response; ignoring it");
2601             return NL_SKIP;
2602         }
2603 
2604         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2605             switch (it.get_type()) {
2606                 case WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW:
2607                     mWakeReasonCnt->total_driver_fw_local_wake =
2608                         it.get_u32();
2609                     break;
2610                 case WAKE_STAT_ATTRIBUTE_TOTAL:
2611                     mWakeReasonCnt->total_cmd_event_wake =
2612                         it.get_u32();
2613                     break;
2614                 case WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED:
2615                     mWakeReasonCnt->cmd_event_wake_cnt_used =
2616                         it.get_u32();
2617                     break;
2618                 case WAKE_STAT_ATTRIBUTE_WAKE:
2619                     memcpy(mCmdEventWakeCount, it.get_data(),
2620                             (mWakeReasonCnt->cmd_event_wake_cnt_used * sizeof(int)));
2621                     break;
2622                 case WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE:
2623                     mWakeReasonCnt->total_rx_data_wake =
2624                         it.get_u32();
2625                     break;
2626                 case WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT:
2627                     mWakeReasonCnt->rx_wake_details.rx_unicast_cnt =
2628                         it.get_u32();
2629                     break;
2630                 case WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT:
2631                     mWakeReasonCnt->rx_wake_details.rx_multicast_cnt =
2632                         it.get_u32();
2633                     break;
2634                 case WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT:
2635                     mWakeReasonCnt->rx_wake_details.rx_broadcast_cnt =
2636                         it.get_u32();
2637                     break;
2638                 case WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT:
2639                     mWakeReasonCnt->rx_wake_pkt_classification_info.icmp_pkt =
2640                         it.get_u32();
2641                     break;
2642                 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT:
2643                     mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_pkt =
2644                         it.get_u32();
2645                     break;
2646                 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA:
2647                     mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_ra =
2648                         it.get_u32();
2649                     break;
2650                 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA:
2651                     mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_na =
2652                         it.get_u32();
2653                     break;
2654                 case WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS:
2655                     mWakeReasonCnt->rx_wake_pkt_classification_info.icmp6_ns =
2656                         it.get_u32();
2657                     break;
2658                 case WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT:
2659                     mWakeReasonCnt->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt =
2660                         it.get_u32();
2661                     break;
2662                 case WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT:
2663                     mWakeReasonCnt->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt =
2664                         it.get_u32();
2665                     break;
2666                 case WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT:
2667                     mWakeReasonCnt->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt =
2668                         it.get_u32();
2669                     break;
2670                 default:
2671                     break;
2672             }
2673 
2674         }
2675         return NL_OK;
2676     }
2677 };
2678 
wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)2679 wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)
2680 {
2681     PacketFateCommand *cmd = new PacketFateCommand(handle);
2682     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2683     wifi_error result = (wifi_error)cmd->start();
2684     cmd->releaseRef();
2685     return result;
2686 }
2687 
wifi_get_tx_pkt_fates(wifi_interface_handle handle,wifi_tx_report * tx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)2688 wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
2689         wifi_tx_report *tx_report_bufs, size_t n_requested_fates,
2690         size_t *n_provided_fates)
2691 {
2692     PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs,
2693                 n_requested_fates, n_provided_fates);
2694     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2695     wifi_error result = (wifi_error)cmd->start();
2696     cmd->releaseRef();
2697     return result;
2698 }
2699 
wifi_get_rx_pkt_fates(wifi_interface_handle handle,wifi_rx_report * rx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)2700 wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
2701         wifi_rx_report *rx_report_bufs, size_t n_requested_fates,
2702         size_t *n_provided_fates)
2703 {
2704     PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs,
2705                 n_requested_fates, n_provided_fates);
2706     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2707     wifi_error result = (wifi_error)cmd->start();
2708     cmd->releaseRef();
2709     return result;
2710 }
2711 
wifi_get_wake_reason_stats(wifi_interface_handle handle,WLAN_DRIVER_WAKE_REASON_CNT * wifi_wake_reason_cnt)2712 wifi_error wifi_get_wake_reason_stats(wifi_interface_handle handle,
2713         WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
2714 {
2715     GetWakeReasonCountCommand *cmd =
2716         new GetWakeReasonCountCommand(handle, wifi_wake_reason_cnt);
2717     wifi_error result = (wifi_error)cmd->start();
2718     cmd->releaseRef();
2719     return result;
2720 }
2721 
2722 ///////////////////////////////////////////////////////////////////////////////
2723 class OtaUpdateCommand : public WifiCommand
2724 {
2725     int mErrCode;
2726 
2727     public:
OtaUpdateCommand(wifi_interface_handle iface)2728     OtaUpdateCommand(wifi_interface_handle iface)
2729         : WifiCommand("OtaUpdateCommand", iface, 0), mErrCode(0)
2730     { }
2731 
start()2732     int start() {
2733         ALOGE("Start OtaUpdateCommand");
2734         WifiRequest request(familyId(), ifaceId());
2735 
2736         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_GET_OTA_CURRUNT_INFO);
2737         if (result != WIFI_SUCCESS) {
2738             ALOGE("Failed to set hal start; result = %d", result);
2739             return result;
2740         }
2741 
2742         result = requestResponse(request);
2743         if (result != WIFI_SUCCESS) {
2744             ALOGE("Failed to register set hal start response; result = %d", result);
2745         }
2746         return result;
2747     }
2748 
otaDownload(ota_info_buf_t * buf,uint32_t ota_version)2749     int otaDownload(ota_info_buf_t* buf, uint32_t ota_version) {
2750         u32 force_reg_on = false;
2751         WifiRequest request(familyId(), ifaceId());
2752         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_OTA_UPDATE);
2753 
2754         ALOGE("Download the OTA configuration");
2755         if (result != WIFI_SUCCESS) {
2756             ALOGE("Failed to set Hal preInit; result = %d", result);
2757             return result;
2758         }
2759 
2760         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2761 
2762         result = request.put_u32(OTA_DOWNLOAD_CLM_LENGTH_ATTR, buf->ota_clm_len);
2763         if (result != WIFI_SUCCESS) {
2764             ALOGE("otaDownload Failed to put data= %d", result);
2765             return result;
2766         }
2767 
2768         result = request.put(OTA_DOWNLOAD_CLM_ATTR, buf->ota_clm_buf, sizeof(*buf->ota_clm_buf));
2769         if (result != WIFI_SUCCESS) {
2770             ALOGE("otaDownload Failed to put data= %d", result);
2771             return result;
2772         }
2773 
2774         result = request.put_u32(OTA_DOWNLOAD_NVRAM_LENGTH_ATTR, buf->ota_nvram_len);
2775         if (result != WIFI_SUCCESS) {
2776             ALOGE("otaDownload Failed to put data= %d", result);
2777             return result;
2778         }
2779 
2780         result = request.put(OTA_DOWNLOAD_NVRAM_ATTR,
2781                 buf->ota_nvram_buf, sizeof(*buf->ota_nvram_buf));
2782         if (result != WIFI_SUCCESS) {
2783             ALOGE("otaDownload Failed to put data= %d", result);
2784             return result;
2785         }
2786 
2787         if (applied_ota_version != ota_version) {
2788             force_reg_on = true;
2789             applied_ota_version = ota_version;
2790         }
2791         result = request.put_u32(OTA_SET_FORCE_REG_ON, force_reg_on);
2792         if (result != WIFI_SUCCESS) {
2793             ALOGE("otaDownload Failed to put data= %d", result);
2794             return result;
2795         }
2796 
2797         result = request.put_u32(OTA_DOWNLOAD_TXCAP_BLOB_LENGTH_ATTR, buf->ota_txcap_len);
2798         if (result != WIFI_SUCCESS) {
2799             ALOGE("otaDownload Failed to put data= %d", result);
2800             return result;
2801         }
2802 
2803         result = request.put(OTA_DOWNLOAD_TXCAP_BLOB_ATTR,
2804             buf->ota_txcap_buf, sizeof(*buf->ota_txcap_buf));
2805         if (result != WIFI_SUCCESS) {
2806             ALOGE("otaDownload Failed to put data= %d", result);
2807             return result;
2808         }
2809 
2810         request.attr_end(data);
2811 
2812         result = requestResponse(request);
2813         if (result != WIFI_SUCCESS) {
2814             ALOGE("Failed to register set otaDownload; result = %d, %d\n", result, mErrCode);
2815         }
2816 
2817         return result;
2818     }
2819 
handleResponse(WifiEvent & reply)2820     virtual int handleResponse(WifiEvent& reply) {
2821         ALOGD("In OtaUpdateCommand::handleResponse");
2822 
2823         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2824             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2825             return NL_SKIP;
2826         }
2827 
2828         int id = reply.get_vendor_id();
2829         int subcmd = reply.get_vendor_subcmd();
2830         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2831         int len = reply.get_vendor_data_len();
2832 
2833         ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
2834 
2835         if (vendor_data == NULL || len == 0) {
2836             ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");
2837             return NL_SKIP;
2838         }
2839 
2840         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
2841             switch (it.get_type()) {
2842                 case OTA_CUR_NVRAM_EXT_ATTR:
2843                     strncpy(ota_nvram_ext, (char*)it.get_string(), it.get_len());
2844                     ALOGI("Current Nvram ext [%s]\n", ota_nvram_ext);
2845                     break;
2846                 default:
2847                     ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
2848                             it.get_type(), it.get_len());
2849                     break;
2850             }
2851         }
2852         return NL_OK;
2853     }
2854 
handleEvent(WifiEvent & event)2855     virtual int handleEvent(WifiEvent& event) {
2856         /* NO events! */
2857         return NL_SKIP;
2858     }
2859 };
2860 
read_ota_file(char * file,char ** buffer,uint32_t * size)2861 wifi_error read_ota_file(char* file, char** buffer, uint32_t* size)
2862 {
2863     FILE* fp = NULL;
2864     int file_size, count;
2865     char* buf;
2866 
2867     fp = fopen(file, "r");
2868     if (fp == NULL) {
2869         ALOGI("File [%s] doesn't exist.", file);
2870         return WIFI_ERROR_NOT_AVAILABLE;
2871     }
2872 
2873     fseek(fp, 0, SEEK_END);
2874     file_size = ftell(fp);
2875     if (file_size == -1L) {
2876         ALOGI("File [%s] size error not valid");
2877         fclose(fp);
2878         return WIFI_ERROR_NOT_AVAILABLE;
2879     }
2880 
2881     buf = (char *)malloc(file_size + 1);
2882     if (buf == NULL) {
2883         fclose(fp);
2884         return WIFI_ERROR_UNKNOWN;
2885     }
2886     memset(buf, 0, file_size + 1);
2887     fseek(fp, 0, SEEK_SET);
2888     count = fread(buf, file_size, 1, fp);
2889     if (!count) {
2890         ALOGE("fread fail.");
2891         free(buf);
2892         fclose(fp);
2893         return WIFI_ERROR_UNKNOWN;
2894     }
2895 
2896     *buffer = (char*) buf;
2897     *size = file_size;
2898     fclose(fp);
2899     return WIFI_SUCCESS;
2900 }
2901 
check_multiple_nvram_clm(uint32_t type,char * hw_revision,char * hw_sku,char ** buffer,uint32_t * buffer_len)2902 wifi_error check_multiple_nvram_clm(uint32_t type, char* hw_revision, char* hw_sku,
2903         char** buffer, uint32_t* buffer_len)
2904 {
2905     char file_name[MAX_NV_FILE][FILE_NAME_LEN];
2906     char nvram_clmblob_default_file[FILE_NAME_LEN] = {0,};
2907     wifi_error result = WIFI_SUCCESS;
2908 
2909     if (type == CLM_BLOB) {
2910         sprintf(nvram_clmblob_default_file, "%s%s", OTA_PATH, OTA_CLM_FILE);
2911     }
2912     else if (type == NVRAM) {
2913         sprintf(nvram_clmblob_default_file, "%s%s", OTA_PATH, OTA_NVRAM_FILE);
2914     }
2915     else if (type == TXCAP_BLOB) {
2916         sprintf(nvram_clmblob_default_file, "%s%s", OTA_PATH, OTA_TXCAP_BLOB_FILE);
2917     }
2918 
2919     for (unsigned int i = 0; i < MAX_NV_FILE; i++) {
2920         memset(file_name[i], 0, FILE_NAME_LEN);
2921     }
2922 
2923     sprintf(file_name[0], "%s_%s_%s", nvram_clmblob_default_file, hw_revision, hw_sku);
2924     sprintf(file_name[1], "%s_%s", nvram_clmblob_default_file, hw_revision);
2925     sprintf(file_name[2], "%s_%s", nvram_clmblob_default_file, hw_sku);
2926     sprintf(file_name[3], "%s", nvram_clmblob_default_file);
2927 
2928     for (unsigned int i = 0; i < MAX_NV_FILE; i++) {
2929         result = read_ota_file(file_name[i], buffer, buffer_len);
2930         if (result == WIFI_SUCCESS) {
2931             ALOGI("[OTA] %s PATH %s", type == NVRAM ? "NVRAM" : "CLM", file_name[i]);
2932             break;
2933         }
2934     }
2935     return result;
2936 }
2937 
wifi_hal_ota_update(wifi_interface_handle iface,uint32_t ota_version)2938 wifi_error wifi_hal_ota_update(wifi_interface_handle iface, uint32_t ota_version)
2939 {
2940     wifi_handle handle = getWifiHandle(iface);
2941     wifi_error result = WIFI_SUCCESS;
2942     ota_info_buf_t buf;
2943     char *buffer_nvram = NULL;
2944     char *buffer_clm = NULL;
2945     char *buffer_txcap_blob = NULL;
2946     char prop_revision_buf[PROPERTY_VALUE_MAX] = {0,};
2947     char prop_sku_buf[PROPERTY_VALUE_MAX] = {0,};
2948     char sku_name[MAX_SKU_NAME_LEN] = {0,};
2949 
2950     OtaUpdateCommand *cmd = new OtaUpdateCommand(iface);
2951     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2952 
2953     ALOGD("wifi_hal_ota_update, handle = %p, ota_version %d\n", handle, ota_version);
2954 
2955     result = (wifi_error)cmd->start();
2956     if (result != WIFI_SUCCESS) {
2957         cmd->releaseRef();
2958         return result;
2959     }
2960 
2961     property_get(HW_DEV_PROP, prop_revision_buf, NULL);
2962     property_get(HW_SKU_PROP, prop_sku_buf, NULL);
2963 
2964     strncpy(sku_name, "NA", MAX_SKU_NAME_LEN);
2965     for (int i = 0; i < ARRAYSIZE(sku_table); i ++) {
2966         if (strcmp(prop_sku_buf, sku_table[i].hw_id) == 0) {
2967             strncpy(sku_name, sku_table[i].sku, MAX_SKU_NAME_LEN);
2968             break;
2969         }
2970     }
2971     ALOGD("prop_sku_buf is %s, sku_name is %s", prop_sku_buf, sku_name);
2972 
2973     check_multiple_nvram_clm(CLM_BLOB, prop_revision_buf, sku_name, &buffer_clm, &buf.ota_clm_len);
2974     if (buffer_clm == NULL) {
2975         ALOGE("buffer_clm is null");
2976         goto exit;
2977     }
2978     buf.ota_clm_buf[0] = buffer_clm;
2979 
2980     check_multiple_nvram_clm(TXCAP_BLOB, prop_revision_buf, sku_name,
2981         &buffer_txcap_blob, &buf.ota_txcap_len);
2982     if (buffer_txcap_blob == NULL) {
2983         ALOGE("buffer_txcap_blob is null");
2984         goto exit;
2985     }
2986     buf.ota_txcap_buf[0] = buffer_txcap_blob;
2987 
2988     check_multiple_nvram_clm(NVRAM, prop_revision_buf, sku_name,
2989             &buffer_nvram, &buf.ota_nvram_len);
2990     if (buffer_nvram == NULL) {
2991         ALOGE("buffer_nvram is null");
2992         goto exit;
2993     }
2994     buf.ota_nvram_buf[0] = buffer_nvram;
2995     cmd->otaDownload(&buf, ota_version);
2996 
2997 exit:
2998     if (buffer_clm != NULL) {
2999         free(buffer_clm);
3000     }
3001     if (buffer_nvram != NULL) {
3002         free(buffer_nvram);
3003     }
3004     if (buffer_txcap_blob != NULL) {
3005         free(buffer_txcap_blob);
3006     }
3007 
3008     cmd->releaseRef();
3009 
3010     return result;
3011 }
3012