WifiLogger.java revision 956fd40b6145c4aba9160e10bfc1ea609873ce8d
1a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle/*
2a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * Copyright (C) 2010 The Android Open Source Project
3a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle *
4a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * Licensed under the Apache License, Version 2.0 (the "License");
5a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * you may not use this file except in compliance with the License.
6a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * You may obtain a copy of the License at
7a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle *
8a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle *      http://www.apache.org/licenses/LICENSE-2.0
9a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle *
10a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * Unless required by applicable law or agreed to in writing, software
11a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * distributed under the License is distributed on an "AS IS" BASIS,
12a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * See the License for the specific language governing permissions and
14a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle * limitations under the License.
15a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle */
16a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
17a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwallepackage com.android.server.wifi;
18a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport android.util.Base64;
20a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport android.util.Log;
21a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
22b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawalimport com.android.internal.annotations.VisibleForTesting;
23b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawalimport com.android.server.wifi.util.ByteArrayRingBuffer;
24d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawalimport com.android.server.wifi.util.StringUtil;
25b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal
267e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.BufferedReader;
270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.ByteArrayOutputStream;
28a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.FileDescriptor;
290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.IOException;
307e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.InputStreamReader;
31a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.PrintWriter;
32d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawalimport java.nio.charset.Charset;
337e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.util.ArrayList;
340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.Calendar;
35ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawalimport java.util.Collections;
36ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawalimport java.util.Comparator;
370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.HashMap;
380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.zip.Deflater;
39a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
40a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle/**
41d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal * Tracks various logs for framework.
42a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle */
43eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeclass WifiLogger extends BaseWifiLogger {
44d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    /**
45d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal     * Thread-safety:
46d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal     * 1) All non-private methods are |synchronized|.
47d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal     * 2) Callbacks into WifiLogger use non-private (and hence, synchronized) methods. See, e.g,
48d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal     *    onRingBufferData(), onWifiAlert().
49d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal     */
50a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
51a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    private static final String TAG = "WifiLogger";
526414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande    private static final boolean DBG = false;
530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** log level flags; keep these consistent with wifi_logger.h */
550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** No logs whatsoever */
570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_NO_LOG = 0;
580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** No logs whatsoever */
590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_NORMAL_LOG = 1;
600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** Be careful since this one can affect performance and power */
610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_LOG_WITH_WAKEUP  = 2;
620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** Be careful since this one can affect performance and power and memory */
630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_DETAILED_LOG_WITH_WAKEUP  = 3;
640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** ring buffer flags; keep these consistent with wifi_logger.h */
660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_BINARY_ENTRIES     = 0x00000001;
670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_ASCII_ENTRIES      = 0x00000002;
680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES = 0x00000004;
690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** various reason codes */
710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_NONE                      = 0;
720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_ASSOC_FAILURE             = 1;
730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_AUTH_FAILURE              = 2;
740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_AUTOROAM_FAILURE          = 3;
750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_DHCP_FAILURE              = 4;
760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_UNEXPECTED_DISCONNECT     = 5;
770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_SCAN_FAILURE              = 6;
789a41261e4f688411a7038781ca959b2007965f06Vinit Deshpande    public static final int REPORT_REASON_USER_ACTION               = 7;
790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** number of bug reports to hold */
810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int MAX_BUG_REPORTS                         = 4;
820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** number of alerts to hold */
840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int MAX_ALERT_REPORTS                       = 1;
850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** minimum wakeup interval for each of the log levels */
870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static final int MinWakeupIntervals[] = new int[] { 0, 3600, 60, 10 };
880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** minimum buffer size for each of the log levels */
890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static final int MinBufferSizes[] = new int[] { 0, 16384, 16384, 65536 };
900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
91d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    @VisibleForTesting public static final int RING_BUFFER_BYTE_LIMIT_SMALL = 32 * 1024;
92d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    @VisibleForTesting public static final int RING_BUFFER_BYTE_LIMIT_LARGE = 1024 * 1024;
93d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    @VisibleForTesting public static final String FIRMWARE_DUMP_SECTION_HEADER =
94d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            "FW Memory dump";
95d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    @VisibleForTesting public static final String DRIVER_DUMP_SECTION_HEADER =
96d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            "Driver state dump";
97d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal
980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private int mLogLevel = VERBOSE_NO_LOG;
99956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal    private boolean mIsLoggingEventHandlerRegistered;
1000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private WifiNative.RingBufferStatus[] mRingBuffers;
1010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private WifiNative.RingBufferStatus mPerPacketRingBuffer;
102f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    private WifiStateMachine mWifiStateMachine;
10318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final WifiNative mWifiNative;
104d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    private int mMaxRingBufferSizeBytes = RING_BUFFER_BYTE_LIMIT_SMALL;
105a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
106fef1495477206d4cabfc95325d71de41790cf9ccmukesh agrawal    public WifiLogger(
107d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal            WifiStateMachine wifiStateMachine, WifiNative wifiNative) {
108f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        mWifiStateMachine = wifiStateMachine;
109eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpande        mWifiNative = wifiNative;
110956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        mIsLoggingEventHandlerRegistered = false;
111f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    }
11203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
113e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1140bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void startLogging(boolean verboseEnabled) {
11518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mFirmwareVersion = mWifiNative.getFirmwareVersion();
11618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mDriverVersion = mWifiNative.getDriverVersion();
11718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mSupportedFeatureSet = mWifiNative.getSupportedLoggerFeatureSet();
118a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande
119956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        if (!mIsLoggingEventHandlerRegistered) {
120956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal            mIsLoggingEventHandlerRegistered = mWifiNative.setLoggingEventHandler(mHandler);
121956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        }
122a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande
1230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (verboseEnabled) {
1240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mLogLevel = VERBOSE_LOG_WITH_WAKEUP;
125d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal            mMaxRingBufferSizeBytes = RING_BUFFER_BYTE_LIMIT_LARGE;
1260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } else {
1270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mLogLevel = VERBOSE_NORMAL_LOG;
128d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal            mMaxRingBufferSizeBytes = RING_BUFFER_BYTE_LIMIT_SMALL;
1292ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal            clearVerboseLogs();
1300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1317e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
1320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
1337e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            fetchRingBuffers();
1347e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
1357e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
13628a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal        if (mRingBuffers != null) {
13728a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal            /* log level may have changed, so restart logging with new levels */
1387e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            stopLoggingAllBuffers();
139d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal            resizeRingBuffers();
1407e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            startLoggingAllExceptPerPacketBuffers();
14103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
142ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
143ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (verboseEnabled && !mWifiNative.startPktFateMonitoring()) {
144ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            Log.e(TAG, "Failed to start packet fate monitoring");
145ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
14603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
14703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
148e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void startPacketLog() {
1500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mPerPacketRingBuffer != null) {
1510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            startLoggingRingBuffer(mPerPacketRingBuffer);
152a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        } else {
1530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "There is no per packet ring buffer");
154a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
155a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
156a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
157e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void stopPacketLog() {
1590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mPerPacketRingBuffer != null) {
1600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            stopLoggingRingBuffer(mPerPacketRingBuffer);
1610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } else {
1620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "There is no per packet ring buffer");
1630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
166e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void stopLogging() {
168956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        if (mIsLoggingEventHandlerRegistered) {
169956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal            if (!mWifiNative.resetLogHandler()) {
170b797893fc1966803d0c013faac42e6396a37a384xinhe                Log.e(TAG, "Fail to reset log handler");
171b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
172956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal                if (DBG) Log.d(TAG, "Reset log handler");
173b797893fc1966803d0c013faac42e6396a37a384xinhe            }
174956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal            // Clear mIsLoggingEventHandlerRegistered even if resetLogHandler() failed, because
175956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal            // the log handler is in an indeterminate state.
176956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal            mIsLoggingEventHandlerRegistered = false;
177956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        }
178956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal        if (mLogLevel != VERBOSE_NO_LOG) {
179ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            stopLoggingAllBuffers();
180ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            mRingBuffers = null;
181ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            mLogLevel = VERBOSE_NO_LOG;
182ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande        }
1830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
185e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
186ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    synchronized void reportConnectionFailure() {
1872ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        if (!isVerboseLoggingEnabled()) {
188ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            return;
189ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
190ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
191ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        mPacketFatesForLastFailure = fetchPacketFates();
192ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    }
193ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
194ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    @Override
1950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void captureBugReportData(int reason) {
196f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal        BugReport report = captureBugreport(reason, isVerboseLoggingEnabled());
1970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        mLastBugReports.addLast(report);
1980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
200e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
2010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void captureAlertData(int errorCode, byte[] alertData) {
202f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal        BugReport report = captureBugreport(errorCode, isVerboseLoggingEnabled());
2030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        report.alertData = alertData;
2040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        mLastAlerts.addLast(report);
2050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
20603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
207e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
2080bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
209ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        super.dump(pw);
2100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (int i = 0; i < mLastAlerts.size(); i++) {
2120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
2130bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("Alert dump " + i);
2140bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.print(mLastAlerts.get(i));
2150bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
2160bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
2170bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2180bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (int i = 0; i < mLastBugReports.size(); i++) {
2190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
2200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("Bug dump " + i);
2210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.print(mLastBugReports.get(i));
2220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
2230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
2240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
225ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        dumpPacketFates(pw);
226ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
2270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        pw.println("--------------------------------------------------------------------");
2280bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
2290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /* private methods and data */
231b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    class BugReport {
2326414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        long systemTimeMs;
2336414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        long kernelTimeNanos;
2340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int errorCode;
2350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        HashMap<String, byte[][]> ringBuffers = new HashMap();
2360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] fwMemoryDump;
237d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal        byte[] mDriverStateDump;
2380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] alertData;
2397e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> kernelLogLines;
2407e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> logcatLines;
2410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2422ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        void clearVerboseLogs() {
2432ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal            fwMemoryDump = null;
2442ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal            mDriverStateDump = null;
2452ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        }
2462ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal
2470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
2480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            StringBuilder builder = new StringBuilder();
2490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Calendar c = Calendar.getInstance();
2516414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            c.setTimeInMillis(systemTimeMs);
2526414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            builder.append("system time = ").append(
2530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)).append("\n");
2540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2556414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            long kernelTimeMs = kernelTimeNanos/(1000*1000);
2566414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            builder.append("kernel time = ").append(kernelTimeMs/1000).append(".").append
2576414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande                    (kernelTimeMs%1000).append("\n");
2586414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande
2590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (alertData == null)
2600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("reason = ").append(errorCode).append("\n");
2610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            else {
2620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("errorCode = ").append(errorCode);
2630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("data \n");
2640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(alertData)).append("\n");
2650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
2660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2677e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (kernelLogLines != null) {
2687e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("kernel log: \n");
2697e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                for (int i = 0; i < kernelLogLines.size(); i++) {
2707e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    builder.append(kernelLogLines.get(i)).append("\n");
2717e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                }
2727e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("\n");
2737e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
2747e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
2757e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (logcatLines != null) {
2767e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("system log: \n");
2777e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                for (int i = 0; i < logcatLines.size(); i++) {
2787e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    builder.append(logcatLines.get(i)).append("\n");
2797e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                }
2807e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("\n");
2817e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
2827e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
2830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            for (HashMap.Entry<String, byte[][]> e : ringBuffers.entrySet()) {
2840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                String ringName = e.getKey();
2850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                byte[][] buffers = e.getValue();
2860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("ring-buffer = ").append(ringName).append("\n");
2870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                int size = 0;
2890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                for (int i = 0; i < buffers.length; i++) {
2900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    size += buffers[i].length;
2910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
2920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                byte[] buffer = new byte[size];
2940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                int index = 0;
2950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                for (int i = 0; i < buffers.length; i++) {
2960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    System.arraycopy(buffers[i], 0, buffer, index, buffers[i].length);
2970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    index += buffers[i].length;
2980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
2990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(buffer));
3010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("\n");
3020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
3030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (fwMemoryDump != null) {
305d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                builder.append(FIRMWARE_DUMP_SECTION_HEADER);
306d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                builder.append("\n");
3070bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(fwMemoryDump));
308d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                builder.append("\n");
309d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            }
310d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
311d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            if (mDriverStateDump != null) {
312d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                builder.append(DRIVER_DUMP_SECTION_HEADER);
313d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                if (StringUtil.isAsciiPrintable(mDriverStateDump)) {
314d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                    builder.append(" (ascii)\n");
315d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                    builder.append(new String(mDriverStateDump, Charset.forName("US-ASCII")));
316d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                    builder.append("\n");
317d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                } else {
318d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                    builder.append(" (base64)\n");
319d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                    builder.append(compressToBase64(mDriverStateDump));
320d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal                }
3210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
3220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return builder.toString();
3240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3250bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
3260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
327b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    class LimitedCircularArray<E> {
3287e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        private ArrayList<E> mArrayList;
3290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        private int mMax;
3300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        LimitedCircularArray(int max) {
3317e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            mArrayList = new ArrayList<E>(max);
3320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mMax = max;
3330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
33403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final void addLast(E e) {
3367e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (mArrayList.size() >= mMax)
3377e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                mArrayList.remove(0);
3387e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            mArrayList.add(e);
3390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
34003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final int size() {
3427e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return mArrayList.size();
343a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
344a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final E get(int i) {
3467e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return mArrayList.get(i);
3470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
34803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
349a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final LimitedCircularArray<BugReport> mLastAlerts =
3510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new LimitedCircularArray<BugReport>(MAX_ALERT_REPORTS);
3520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final LimitedCircularArray<BugReport> mLastBugReports =
3530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new LimitedCircularArray<BugReport>(MAX_BUG_REPORTS);
354b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    private final HashMap<String, ByteArrayRingBuffer> mRingBufferData = new HashMap();
3550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final WifiNative.WifiLoggerEventHandler mHandler =
3570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new WifiNative.WifiLoggerEventHandler() {
3580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
3590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) {
3600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            WifiLogger.this.onRingBufferData(status, buffer);
3610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
3640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public void onWifiAlert(int errorCode, byte[] buffer) {
3650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            WifiLogger.this.onWifiAlert(errorCode, buffer);
3660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    };
3680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    synchronized void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) {
370b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal        ByteArrayRingBuffer ring = mRingBufferData.get(status.name);
3710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (ring != null) {
372b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal            ring.appendBuffer(buffer);
3730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
37403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
375a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    synchronized void onWifiAlert(int errorCode, byte[] buffer) {
377f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        if (mWifiStateMachine != null) {
378f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande            mWifiStateMachine.sendMessage(
379f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande                    WifiStateMachine.CMD_FIRMWARE_ALERT, errorCode, 0, buffer);
380f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        }
381a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
382a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
383f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal    private boolean isVerboseLoggingEnabled() {
384f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal        return mLogLevel > VERBOSE_NORMAL_LOG;
385f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal    }
386f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal
3872ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal    private void clearVerboseLogs() {
3882ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        mPacketFatesForLastFailure = null;
3892ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal
3902ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        for (int i = 0; i < mLastAlerts.size(); i++) {
3912ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal            mLastAlerts.get(i).clearVerboseLogs();
3922ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        }
3932ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal
3942ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        for (int i = 0; i < mLastBugReports.size(); i++) {
3952ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal            mLastBugReports.get(i).clearVerboseLogs();
3962ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal        }
3972ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal    }
3982ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal
3990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean fetchRingBuffers() {
4000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers != null) return true;
401a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
40218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mRingBuffers = mWifiNative.getRingBufferStatus();
4030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers != null) {
4040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
4050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (DBG) Log.d(TAG, "RingBufferStatus is: \n" + buffer.name);
4060bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (mRingBufferData.containsKey(buffer.name) == false) {
4070bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    mRingBufferData.put(buffer.name,
408fef1495477206d4cabfc95325d71de41790cf9ccmukesh agrawal                            new ByteArrayRingBuffer(mMaxRingBufferSizeBytes));
4090bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
4100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) {
4110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    mPerPacketRingBuffer = buffer;
41203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                }
413a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle            }
41403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        } else {
4150bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "no ring buffers found");
416a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
41703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
4180bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return mRingBuffers != null;
419a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
420a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
421d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    private void resizeRingBuffers() {
422d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal        for (ByteArrayRingBuffer byteArrayRingBuffer : mRingBufferData.values()) {
423d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal            byteArrayRingBuffer.resize(mMaxRingBufferSizeBytes);
424d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal        }
425d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal    }
426d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal
4270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean startLoggingAllExceptPerPacketBuffers() {
42803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
4290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
4300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "No ring buffers to log anything!");
4310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
43203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
43303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
4340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (WifiNative.RingBufferStatus buffer : mRingBuffers){
4350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) {
4370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                /* skip per-packet-buffer */
4380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (DBG) Log.d(TAG, "skipped per packet logging ring " + buffer.name);
4390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                continue;
44003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
4410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            startLoggingRingBuffer(buffer);
44303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
44403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
44503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        return true;
446a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
447a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
4480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean startLoggingRingBuffer(WifiNative.RingBufferStatus buffer) {
4490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int minInterval = MinWakeupIntervals[mLogLevel];
4510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int minDataSize = MinBufferSizes[mLogLevel];
4520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
45318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mWifiNative.startLoggingRingBuffer(
4540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                mLogLevel, 0, minInterval, minDataSize, buffer.name) == false) {
4550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.e(TAG, "Could not start logging ring " + buffer.name);
4560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
4570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
46003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
461a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
4620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean stopLoggingRingBuffer(WifiNative.RingBufferStatus buffer) {
46318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mWifiNative.startLoggingRingBuffer(0, 0, 0, 0, buffer.name) == false) {
4640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.e(TAG, "Could not stop logging ring " + buffer.name);
46503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
4660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
4670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
4680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean stopLoggingAllBuffers() {
470d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande        if (mRingBuffers != null) {
471d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
472d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande                stopLoggingRingBuffer(buffer);
473d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande            }
4740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
4760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
47703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
4780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean getAllRingBufferData() {
4790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
4800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "Not ring buffers available to collect data!");
4810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
4820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (WifiNative.RingBufferStatus element : mRingBuffers){
48518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            boolean result = mWifiNative.getRingBufferData(element.name);
4860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (!result) {
48703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                Log.e(TAG, "Fail to get ring buffer data of: " + element.name);
48803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
48903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
49003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
4910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
49203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        Log.d(TAG, "getAllRingBufferData Successfully!");
49303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        return true;
49403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
49503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
496f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    private BugReport captureBugreport(int errorCode, boolean captureFWDump) {
4970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        BugReport report = new BugReport();
4980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        report.errorCode = errorCode;
4996414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        report.systemTimeMs = System.currentTimeMillis();
5006414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        report.kernelTimeNanos = System.nanoTime();
5010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
502ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande        if (mRingBuffers != null) {
503ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
504ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                /* this will push data in mRingBuffers */
50518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                mWifiNative.getRingBufferData(buffer.name);
506b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal                ByteArrayRingBuffer data = mRingBufferData.get(buffer.name);
507b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal                byte[][] buffers = new byte[data.getNumBuffers()][];
508b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal                for (int i = 0; i < data.getNumBuffers(); i++) {
509b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal                    buffers[i] = data.getBuffer(i).clone();
510ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                }
511ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                report.ringBuffers.put(buffer.name, buffers);
5120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
5130bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
5140bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5157e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        report.logcatLines = getOutput("logcat -d", 127);
5167e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        report.kernelLogLines = getKernelLog(127);
5177e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
518f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        if (captureFWDump) {
51918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            report.fwMemoryDump = mWifiNative.getFwMemoryDump();
520d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal            report.mDriverStateDump = mWifiNative.getDriverStateDump();
521f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        }
5220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return report;
523a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
52403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
525b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    @VisibleForTesting
526b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    LimitedCircularArray<BugReport> getBugReports() {
527b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal        return mLastBugReports;
528b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal    }
529b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal
5300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static String compressToBase64(byte[] input) {
5310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String result;
5320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        //compress
5330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        Deflater compressor = new Deflater();
5340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.setLevel(Deflater.BEST_COMPRESSION);
5350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.setInput(input);
5360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.finish();
5370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
5380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        final byte[] buf = new byte[1024];
5390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        while (!compressor.finished()) {
5410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            int count = compressor.deflate(buf);
5420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            bos.write(buf, 0, count);
5430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
5440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        try {
5460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            compressor.end();
5470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            bos.close();
5480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } catch (IOException e) {
5490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "ByteArrayOutputStream close error");
5500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            result =  android.util.Base64.encodeToString(input, Base64.DEFAULT);
5510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return result;
5520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
5530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] compressed = bos.toByteArray();
5550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (DBG) {
5560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.d(TAG," length is:" + (compressed == null? "0" : compressed.length));
5570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
5580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        //encode
5600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        result = android.util.Base64.encodeToString(
5610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                compressed.length < input.length ? compressed : input , Base64.DEFAULT);
5620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (DBG) {
5640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.d(TAG, "FwMemoryDump length is :" + result.length());
5650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
5660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
5670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return result;
5680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
5697e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
5707e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private LimitedCircularArray<String> getOutput(String cmdLine, int maxLines) {
5717e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> lines = new LimitedCircularArray<String>(maxLines);
5727e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        try {
5737e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (DBG) Log.d(TAG, "Executing '" + cmdLine + "' ...");
5747e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Process process = Runtime.getRuntime().exec(cmdLine);
5757e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            BufferedReader reader = new BufferedReader(
5767e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    new InputStreamReader(process.getInputStream()));
5777e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            String line;
5787e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            while ((line = reader.readLine()) != null) {
5797e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                lines.addLast(line);
5807e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
5817e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            reader = new BufferedReader(
5827e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    new InputStreamReader(process.getErrorStream()));
5837e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            while ((line = reader.readLine()) != null) {
5847e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                lines.addLast(line);
5857e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
5867e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            process.waitFor();
5877e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (DBG) Log.d(TAG, "Lines added for '" + cmdLine + "'.");
5887e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } catch (InterruptedException e) {
5897e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Log.e(TAG, "Could not wait for '" + cmdLine + "': " + e);
5907e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } catch (IOException e) {
5917e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Log.e(TAG, "Could not open '" + cmdLine + "': " + e);
5927e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
5937e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        return lines;
5947e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
5957e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
5967e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private LimitedCircularArray<String> getKernelLog(int maxLines) {
5977e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (DBG) Log.d(TAG, "Reading kernel log ...");
5987e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> lines = new LimitedCircularArray<String>(maxLines);
5997e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        String log = mWifiNative.readKernelLog();
6007e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        String logLines[] = log.split("\n");
6017e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        for (int i = 0; i < logLines.length; i++) {
6027e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            lines.addLast(logLines[i]);
6037e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
6047e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (DBG) Log.d(TAG, "Added " + logLines.length + " lines");
6057e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        return lines;
6067e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
6077e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
608ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    /** Packet fate reporting */
609ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    private ArrayList<WifiNative.FateReport> mPacketFatesForLastFailure;
610ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
611ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    private ArrayList<WifiNative.FateReport> fetchPacketFates() {
612ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        ArrayList<WifiNative.FateReport> mergedFates = new ArrayList<WifiNative.FateReport>();
613ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        WifiNative.TxFateReport[] txFates =
614ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal                new WifiNative.TxFateReport[WifiLoggerHal.MAX_FATE_LOG_LEN];
615ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (mWifiNative.getTxPktFates(txFates)) {
616ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            for (int i = 0; i < txFates.length && txFates[i] != null; i++) {
617ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal                mergedFates.add(txFates[i]);
618ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            }
619ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
620ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
621ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        WifiNative.RxFateReport[] rxFates =
622ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal                new WifiNative.RxFateReport[WifiLoggerHal.MAX_FATE_LOG_LEN];
623ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (mWifiNative.getRxPktFates(rxFates)) {
624ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            for (int i = 0; i < rxFates.length && rxFates[i] != null; i++) {
625ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal                mergedFates.add(rxFates[i]);
626ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            }
627ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
628ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
629ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        Collections.sort(mergedFates, new Comparator<WifiNative.FateReport>() {
630ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            @Override
631ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            public int compare(WifiNative.FateReport lhs, WifiNative.FateReport rhs) {
632ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal                return Long.compare(lhs.mDriverTimestampUSec, rhs.mDriverTimestampUSec);
633ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            }
634ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        });
635ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
636ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        return mergedFates;
637ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    }
638ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
639ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    private void dumpPacketFates(PrintWriter pw) {
640ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        dumpPacketFatesInternal(pw, "Last failed connection fates", mPacketFatesForLastFailure);
641ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (DBG) {
642ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            dumpPacketFatesInternal(pw, "Latest fates", fetchPacketFates());
643ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
644ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    }
645ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
646ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    private static void dumpPacketFatesInternal(
647ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            PrintWriter pw, String description, ArrayList<WifiNative.FateReport> fates) {
648ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (fates == null) {
649ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            pw.format("No fates fetched for \"%s\"\n", description);
650ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            return;
651ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
652ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
653ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        if (fates.size() == 0) {
654ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            pw.format("HAL provided zero fates for \"%s\"\n", description);
655ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            return;
656ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
657ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal
658ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        int i = 0;
659ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        pw.format("--------------------- %s ----------------------\n", description);
660ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        for (WifiNative.FateReport fate : fates) {
661ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            pw.format("Frame number: %d\n", i + 1);
662ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            pw.print(fate);
663ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            pw.print("\n");
664ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal            ++i;
665ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        }
666ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal        pw.println("--------------------------------------------------------------------");
667ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal    }
668a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle}
669