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