WifiLogger.java revision 28a073ae465df4e92b11bc8c9b3a1890de375d30
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
227e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.BufferedReader;
230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.ByteArrayOutputStream;
24a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.FileDescriptor;
250bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.IOException;
267e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.InputStreamReader;
27a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.PrintWriter;
287e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.util.ArrayList;
290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.Calendar;
300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.HashMap;
310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.zip.Deflater;
32a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
33a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle/**
340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande * Tracks various logs for framework
35a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle */
36eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeclass WifiLogger extends BaseWifiLogger {
37a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
38a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    private static final String TAG = "WifiLogger";
396414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande    private static final boolean DBG = false;
400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** log level flags; keep these consistent with wifi_logger.h */
420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** No logs whatsoever */
440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_NO_LOG = 0;
450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** No logs whatsoever */
460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_NORMAL_LOG = 1;
470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** Be careful since this one can affect performance and power */
480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_LOG_WITH_WAKEUP  = 2;
490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** Be careful since this one can affect performance and power and memory */
500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int VERBOSE_DETAILED_LOG_WITH_WAKEUP  = 3;
510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** ring buffer flags; keep these consistent with wifi_logger.h */
530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_BINARY_ENTRIES     = 0x00000001;
540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_ASCII_ENTRIES      = 0x00000002;
550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES = 0x00000004;
560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** various reason codes */
580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_NONE                      = 0;
590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_ASSOC_FAILURE             = 1;
600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_AUTH_FAILURE              = 2;
610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_AUTOROAM_FAILURE          = 3;
620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_DHCP_FAILURE              = 4;
630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_UNEXPECTED_DISCONNECT     = 5;
640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int REPORT_REASON_SCAN_FAILURE              = 6;
659a41261e4f688411a7038781ca959b2007965f06Vinit Deshpande    public static final int REPORT_REASON_USER_ACTION               = 7;
660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
67674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava    /** number of ring buffer entries to cache */
68674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava    public static final int MAX_RING_BUFFERS                        = 10;
690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** number of bug reports to hold */
710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int MAX_BUG_REPORTS                         = 4;
720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** number of alerts to hold */
740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static final int MAX_ALERT_REPORTS                       = 1;
750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** minimum wakeup interval for each of the log levels */
770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static final int MinWakeupIntervals[] = new int[] { 0, 3600, 60, 10 };
780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /** minimum buffer size for each of the log levels */
790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static final int MinBufferSizes[] = new int[] { 0, 16384, 16384, 65536 };
800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private int mLogLevel = VERBOSE_NO_LOG;
820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private WifiNative.RingBufferStatus[] mRingBuffers;
830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private WifiNative.RingBufferStatus mPerPacketRingBuffer;
84f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    private WifiStateMachine mWifiStateMachine;
8518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final WifiNative mWifiNative;
86a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
87eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpande    public WifiLogger(WifiStateMachine wifiStateMachine, WifiNative wifiNative) {
88f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        mWifiStateMachine = wifiStateMachine;
89eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpande        mWifiNative = wifiNative;
90f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    }
9103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
92e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void startLogging(boolean verboseEnabled) {
9418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mFirmwareVersion = mWifiNative.getFirmwareVersion();
9518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mDriverVersion = mWifiNative.getDriverVersion();
9618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mSupportedFeatureSet = mWifiNative.getSupportedLoggerFeatureSet();
97a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande
986414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        if (mLogLevel == VERBOSE_NO_LOG)
9918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mWifiNative.setLoggingEventHandler(mHandler);
100a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande
1010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (verboseEnabled) {
1020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mLogLevel = VERBOSE_LOG_WITH_WAKEUP;
1030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } else {
1040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mLogLevel = VERBOSE_NORMAL_LOG;
1050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1067e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
1070bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
1087e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            fetchRingBuffers();
1097e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
1107e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
11128a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal        if (mRingBuffers != null) {
11228a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal            /* log level may have changed, so restart logging with new levels */
1137e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            stopLoggingAllBuffers();
1147e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            startLoggingAllExceptPerPacketBuffers();
11503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
11603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
11703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
118e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void startPacketLog() {
1200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mPerPacketRingBuffer != null) {
1210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            startLoggingRingBuffer(mPerPacketRingBuffer);
122a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        } else {
1230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "There is no per packet ring buffer");
124a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
125a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
126a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
127e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1280bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void stopPacketLog() {
1290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mPerPacketRingBuffer != null) {
1300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            stopLoggingRingBuffer(mPerPacketRingBuffer);
1310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } else {
1320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "There is no per packet ring buffer");
1330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
136e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void stopLogging() {
138ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande        if (mLogLevel != VERBOSE_NO_LOG) {
139b797893fc1966803d0c013faac42e6396a37a384xinhe            //resetLogHandler only can be used when you terminate all logging since all handler will
140b797893fc1966803d0c013faac42e6396a37a384xinhe            //be removed. This also stop alert logging
14118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            if(!mWifiNative.resetLogHandler()) {
142b797893fc1966803d0c013faac42e6396a37a384xinhe                Log.e(TAG, "Fail to reset log handler");
143b797893fc1966803d0c013faac42e6396a37a384xinhe            } else {
144b797893fc1966803d0c013faac42e6396a37a384xinhe                if (DBG) Log.d(TAG,"Reset log handler");
145b797893fc1966803d0c013faac42e6396a37a384xinhe            }
146ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            stopLoggingAllBuffers();
147ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            mRingBuffers = null;
148ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            mLogLevel = VERBOSE_NO_LOG;
149ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande        }
1500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
152e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void captureBugReportData(int reason) {
1549a41261e4f688411a7038781ca959b2007965f06Vinit Deshpande        BugReport report = captureBugreport(reason, true);
1550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        mLastBugReports.addLast(report);
1560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
158e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void captureAlertData(int errorCode, byte[] alertData) {
160f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        BugReport report = captureBugreport(errorCode, /* captureFWDump = */ true);
1610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        report.alertData = alertData;
1620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        mLastAlerts.addLast(report);
1630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
16403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
165e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    @Override
1660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1677e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        dump(pw);
1680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (int i = 0; i < mLastAlerts.size(); i++) {
1700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
1710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("Alert dump " + i);
1720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.print(mLastAlerts.get(i));
1730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
1740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (int i = 0; i < mLastBugReports.size(); i++) {
1770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
1780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("Bug dump " + i);
1790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.print(mLastBugReports.get(i));
1800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            pw.println("--------------------------------------------------------------------");
1810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
1820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        pw.println("--------------------------------------------------------------------");
1840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
1850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    /* private methods and data */
1870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static class BugReport {
1886414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        long systemTimeMs;
1896414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        long kernelTimeNanos;
1900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int errorCode;
1910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        HashMap<String, byte[][]> ringBuffers = new HashMap();
1920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] fwMemoryDump;
1930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] alertData;
1947e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> kernelLogLines;
1957e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> logcatLines;
1960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
1980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            StringBuilder builder = new StringBuilder();
1990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Calendar c = Calendar.getInstance();
2016414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            c.setTimeInMillis(systemTimeMs);
2026414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            builder.append("system time = ").append(
2030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)).append("\n");
2040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2056414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            long kernelTimeMs = kernelTimeNanos/(1000*1000);
2066414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande            builder.append("kernel time = ").append(kernelTimeMs/1000).append(".").append
2076414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande                    (kernelTimeMs%1000).append("\n");
2086414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande
2090bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (alertData == null)
2100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("reason = ").append(errorCode).append("\n");
2110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            else {
2120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("errorCode = ").append(errorCode);
2130bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("data \n");
2140bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(alertData)).append("\n");
2150bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
2160bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2177e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (kernelLogLines != null) {
2187e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("kernel log: \n");
2197e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                for (int i = 0; i < kernelLogLines.size(); i++) {
2207e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    builder.append(kernelLogLines.get(i)).append("\n");
2217e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                }
2227e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("\n");
2237e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
2247e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
2257e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (logcatLines != null) {
2267e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("system log: \n");
2277e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                for (int i = 0; i < logcatLines.size(); i++) {
2287e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    builder.append(logcatLines.get(i)).append("\n");
2297e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                }
2307e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                builder.append("\n");
2317e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
2327e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
2330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            for (HashMap.Entry<String, byte[][]> e : ringBuffers.entrySet()) {
2340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                String ringName = e.getKey();
2350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                byte[][] buffers = e.getValue();
2360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("ring-buffer = ").append(ringName).append("\n");
2370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                int size = 0;
2390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                for (int i = 0; i < buffers.length; i++) {
2400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    size += buffers[i].length;
2410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
2420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                byte[] buffer = new byte[size];
2440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                int index = 0;
2450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                for (int i = 0; i < buffers.length; i++) {
2460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    System.arraycopy(buffers[i], 0, buffer, index, buffers[i].length);
2470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    index += buffers[i].length;
2480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
2490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(buffer));
2510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("\n");
2520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
2530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (fwMemoryDump != null) {
2550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append("FW Memory dump \n");
2560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                builder.append(compressToBase64(fwMemoryDump));
2570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
2580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return builder.toString();
2600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
2610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
2620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
263e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande    private static class LimitedCircularArray<E> {
2647e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        private ArrayList<E> mArrayList;
2650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        private int mMax;
2660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        LimitedCircularArray(int max) {
2677e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            mArrayList = new ArrayList<E>(max);
2680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            mMax = max;
2690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
27003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final void addLast(E e) {
2727e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (mArrayList.size() >= mMax)
2737e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                mArrayList.remove(0);
2747e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            mArrayList.add(e);
2750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
27603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final int size() {
2787e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return mArrayList.size();
279a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
280a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public final E get(int i) {
2827e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            return mArrayList.get(i);
2830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
28403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
285a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final LimitedCircularArray<BugReport> mLastAlerts =
2870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new LimitedCircularArray<BugReport>(MAX_ALERT_REPORTS);
2880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final LimitedCircularArray<BugReport> mLastBugReports =
2890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new LimitedCircularArray<BugReport>(MAX_BUG_REPORTS);
290674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava    private final HashMap<String, LimitedCircularArray<byte[]>> mRingBufferData = new HashMap();
2910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private final WifiNative.WifiLoggerEventHandler mHandler =
2930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            new WifiNative.WifiLoggerEventHandler() {
2940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
2950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) {
2960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            WifiLogger.this.onRingBufferData(status, buffer);
2970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
2980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
3000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public void onWifiAlert(int errorCode, byte[] buffer) {
3010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            WifiLogger.this.onWifiAlert(errorCode, buffer);
3020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    };
3040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    synchronized void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) {
306674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava        LimitedCircularArray<byte[]> ring = mRingBufferData.get(status.name);
3070bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (ring != null) {
3080bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            ring.addLast(buffer);
3090bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
31003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
311a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    synchronized void onWifiAlert(int errorCode, byte[] buffer) {
313f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        if (mWifiStateMachine != null) {
314f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande            mWifiStateMachine.sendMessage(
315f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande                    WifiStateMachine.CMD_FIRMWARE_ALERT, errorCode, 0, buffer);
316f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        }
317a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
318a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean fetchRingBuffers() {
3200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers != null) return true;
321a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
32218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        mRingBuffers = mWifiNative.getRingBufferStatus();
3230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers != null) {
3240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
3250bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (DBG) Log.d(TAG, "RingBufferStatus is: \n" + buffer.name);
3260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (mRingBufferData.containsKey(buffer.name) == false) {
3270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    mRingBufferData.put(buffer.name,
328674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava                            new LimitedCircularArray<byte[]>(MAX_RING_BUFFERS));
3290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                }
3300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) {
3310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    mPerPacketRingBuffer = buffer;
33203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                }
333a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle            }
33403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        } else {
3350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "no ring buffers found");
336a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle        }
33703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return mRingBuffers != null;
339a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
340a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean startLoggingAllExceptPerPacketBuffers() {
34203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
3440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.d(TAG, "No ring buffers to log anything!");
3450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
34603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
34703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (WifiNative.RingBufferStatus buffer : mRingBuffers){
3490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) {
3510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                /* skip per-packet-buffer */
3520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                if (DBG) Log.d(TAG, "skipped per packet logging ring " + buffer.name);
3530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                continue;
35403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
3550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            startLoggingRingBuffer(buffer);
35703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
35803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
35903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        return true;
360a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
361a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean startLoggingRingBuffer(WifiNative.RingBufferStatus buffer) {
3630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int minInterval = MinWakeupIntervals[mLogLevel];
3650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int minDataSize = MinBufferSizes[mLogLevel];
3660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
36718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mWifiNative.startLoggingRingBuffer(
3680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                mLogLevel, 0, minInterval, minDataSize, buffer.name) == false) {
3690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.e(TAG, "Could not start logging ring " + buffer.name);
3700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
3710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
37403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
375a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
3760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean stopLoggingRingBuffer(WifiNative.RingBufferStatus buffer) {
37718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        if (mWifiNative.startLoggingRingBuffer(0, 0, 0, 0, buffer.name) == false) {
3780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (DBG) Log.e(TAG, "Could not stop logging ring " + buffer.name);
37903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
3800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
3810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
3820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean stopLoggingAllBuffers() {
384d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande        if (mRingBuffers != null) {
385d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
386d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande                stopLoggingRingBuffer(buffer);
387d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande            }
3880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return true;
3900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
39103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
3920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private boolean getAllRingBufferData() {
3930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (mRingBuffers == null) {
3940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "Not ring buffers available to collect data!");
3950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return false;
3960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
3970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
3980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        for (WifiNative.RingBufferStatus element : mRingBuffers){
39918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            boolean result = mWifiNative.getRingBufferData(element.name);
4000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            if (!result) {
40103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                Log.e(TAG, "Fail to get ring buffer data of: " + element.name);
40203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe                return false;
40303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            }
40403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        }
4050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
40603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        Log.d(TAG, "getAllRingBufferData Successfully!");
40703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe        return true;
40803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
40903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
410f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande    private BugReport captureBugreport(int errorCode, boolean captureFWDump) {
4110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        BugReport report = new BugReport();
4120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        report.errorCode = errorCode;
4136414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        report.systemTimeMs = System.currentTimeMillis();
4146414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande        report.kernelTimeNanos = System.nanoTime();
4150bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
416ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande        if (mRingBuffers != null) {
417ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande            for (WifiNative.RingBufferStatus buffer : mRingBuffers) {
418ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                /* this will push data in mRingBuffers */
41918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                mWifiNative.getRingBufferData(buffer.name);
420674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava                LimitedCircularArray<byte[]> data = mRingBufferData.get(buffer.name);
421ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                byte[][] buffers = new byte[data.size()][];
422674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava                for (int i = 0; i < data.size(); i++) {
423674602ce4a5e0c6df7e67230310ad842deb532e9Vineeta Srivastava                    buffers[i] = data.get(i).clone();
424ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                }
425ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande                report.ringBuffers.put(buffer.name, buffers);
4260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            }
4270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4280bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4297e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        report.logcatLines = getOutput("logcat -d", 127);
4307e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        report.kernelLogLines = getKernelLog(127);
4317e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
432f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        if (captureFWDump) {
43318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            report.fwMemoryDump = mWifiNative.getFwMemoryDump();
434f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande        }
4350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return report;
436a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
43703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
4380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    private static String compressToBase64(byte[] input) {
4390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String result;
4400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        //compress
4410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        Deflater compressor = new Deflater();
4420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.setLevel(Deflater.BEST_COMPRESSION);
4430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.setInput(input);
4440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        compressor.finish();
4450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
4460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        final byte[] buf = new byte[1024];
4470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        while (!compressor.finished()) {
4490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            int count = compressor.deflate(buf);
4500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            bos.write(buf, 0, count);
4510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        try {
4540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            compressor.end();
4550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            bos.close();
4560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        } catch (IOException e) {
4570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.e(TAG, "ByteArrayOutputStream close error");
4580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            result =  android.util.Base64.encodeToString(input, Base64.DEFAULT);
4590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return result;
4600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        byte[] compressed = bos.toByteArray();
4630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (DBG) {
4640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.d(TAG," length is:" + (compressed == null? "0" : compressed.length));
4650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        //encode
4680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        result = android.util.Base64.encodeToString(
4690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                compressed.length < input.length ? compressed : input , Base64.DEFAULT);
4700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        if (DBG) {
4720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            Log.d(TAG, "FwMemoryDump length is :" + result.length());
4730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
4740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
4750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        return result;
4760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
4777e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
4787e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private LimitedCircularArray<String> getOutput(String cmdLine, int maxLines) {
4797e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> lines = new LimitedCircularArray<String>(maxLines);
4807e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        try {
4817e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (DBG) Log.d(TAG, "Executing '" + cmdLine + "' ...");
4827e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Process process = Runtime.getRuntime().exec(cmdLine);
4837e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            BufferedReader reader = new BufferedReader(
4847e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    new InputStreamReader(process.getInputStream()));
4857e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            String line;
4867e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            while ((line = reader.readLine()) != null) {
4877e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                lines.addLast(line);
4887e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
4897e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            reader = new BufferedReader(
4907e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                    new InputStreamReader(process.getErrorStream()));
4917e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            while ((line = reader.readLine()) != null) {
4927e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande                lines.addLast(line);
4937e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            }
4947e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            process.waitFor();
4957e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            if (DBG) Log.d(TAG, "Lines added for '" + cmdLine + "'.");
4967e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } catch (InterruptedException e) {
4977e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Log.e(TAG, "Could not wait for '" + cmdLine + "': " + e);
4987e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        } catch (IOException e) {
4997e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            Log.e(TAG, "Could not open '" + cmdLine + "': " + e);
5007e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
5017e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        return lines;
5027e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
5037e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
5047e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    private LimitedCircularArray<String> getKernelLog(int maxLines) {
5057e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (DBG) Log.d(TAG, "Reading kernel log ...");
5067e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        LimitedCircularArray<String> lines = new LimitedCircularArray<String>(maxLines);
5077e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        String log = mWifiNative.readKernelLog();
5087e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        String logLines[] = log.split("\n");
5097e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        for (int i = 0; i < logLines.length; i++) {
5107e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande            lines.addLast(logLines[i]);
5117e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        }
5127e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        if (DBG) Log.d(TAG, "Added " + logLines.length + " lines");
5137e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande        return lines;
5147e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande    }
5157e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande
516a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle}
517