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