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