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 19d3be501437efd5f176e7541cace20b8db467eb47Roshan Piusimport android.annotation.NonNull; 20eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawalimport android.content.Context; 210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport android.util.Base64; 22a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 23eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawalimport com.android.internal.R; 24f46c533931224296b11d98798344c049f88db9a1mukesh agrawalimport com.android.internal.annotations.VisibleForTesting; 25b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawalimport com.android.server.wifi.util.ByteArrayRingBuffer; 26d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawalimport com.android.server.wifi.util.StringUtil; 27b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal 287e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.BufferedReader; 290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.ByteArrayOutputStream; 30a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.FileDescriptor; 310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.io.IOException; 327e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.io.InputStreamReader; 33a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalleimport java.io.PrintWriter; 34d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawalimport java.nio.charset.Charset; 357e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpandeimport java.util.ArrayList; 360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.Calendar; 37ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawalimport java.util.Collections; 38ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawalimport java.util.Comparator; 390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.HashMap; 400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpandeimport java.util.zip.Deflater; 41a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 42a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle/** 43d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal * Tracks various logs for framework. 44a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle */ 45019fda2109ea79daee3fb4442080b1b83be2e7b3mukesh agrawalclass WifiDiagnostics extends BaseWifiDiagnostics { 46d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal /** 47d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal * Thread-safety: 48d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal * 1) All non-private methods are |synchronized|. 49019fda2109ea79daee3fb4442080b1b83be2e7b3mukesh agrawal * 2) Callbacks into WifiDiagnostics use non-private (and hence, synchronized) methods. See, e.g, 50d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal * onRingBufferData(), onWifiAlert(). 51d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal */ 52a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 53019fda2109ea79daee3fb4442080b1b83be2e7b3mukesh agrawal private static final String TAG = "WifiDiags"; 546414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande private static final boolean DBG = false; 550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** log level flags; keep these consistent with wifi_logger.h */ 570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** No logs whatsoever */ 590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int VERBOSE_NO_LOG = 0; 600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** No logs whatsoever */ 610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int VERBOSE_NORMAL_LOG = 1; 620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** Be careful since this one can affect performance and power */ 630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int VERBOSE_LOG_WITH_WAKEUP = 2; 640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** Be careful since this one can affect performance and power and memory */ 650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int VERBOSE_DETAILED_LOG_WITH_WAKEUP = 3; 660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** ring buffer flags; keep these consistent with wifi_logger.h */ 680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int RING_BUFFER_FLAG_HAS_BINARY_ENTRIES = 0x00000001; 690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int RING_BUFFER_FLAG_HAS_ASCII_ENTRIES = 0x00000002; 700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES = 0x00000004; 710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** various reason codes */ 730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_NONE = 0; 740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_ASSOC_FAILURE = 1; 750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_AUTH_FAILURE = 2; 760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_AUTOROAM_FAILURE = 3; 770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_DHCP_FAILURE = 4; 780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_UNEXPECTED_DISCONNECT = 5; 790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int REPORT_REASON_SCAN_FAILURE = 6; 809a41261e4f688411a7038781ca959b2007965f06Vinit Deshpande public static final int REPORT_REASON_USER_ACTION = 7; 8126e5eb3545a8d67c66e546f4ce413c0611573cfbRoshan Pius public static final int REPORT_REASON_WIFINATIVE_FAILURE = 8; 820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** number of bug reports to hold */ 840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int MAX_BUG_REPORTS = 4; 850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** number of alerts to hold */ 870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public static final int MAX_ALERT_REPORTS = 1; 880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** minimum wakeup interval for each of the log levels */ 900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private static final int MinWakeupIntervals[] = new int[] { 0, 3600, 60, 10 }; 910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /** minimum buffer size for each of the log levels */ 920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private static final int MinBufferSizes[] = new int[] { 0, 16384, 16384, 65536 }; 930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 94d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal @VisibleForTesting public static final String FIRMWARE_DUMP_SECTION_HEADER = 95d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal "FW Memory dump"; 96d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal @VisibleForTesting public static final String DRIVER_DUMP_SECTION_HEADER = 97d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal "Driver state dump"; 98d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal 99eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal private final int RING_BUFFER_BYTE_LIMIT_SMALL; 100eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal private final int RING_BUFFER_BYTE_LIMIT_LARGE; 1010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private int mLogLevel = VERBOSE_NO_LOG; 102956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal private boolean mIsLoggingEventHandlerRegistered; 1030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private WifiNative.RingBufferStatus[] mRingBuffers; 1040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private WifiNative.RingBufferStatus mPerPacketRingBuffer; 1058df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal private final BuildProperties mBuildProperties; 106d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal private final WifiLog mLog; 107d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal private final LastMileLogger mLastMileLogger; 1083bbf564af91515b33fcba33e7039ffe09c8c025cmukesh agrawal private final Runtime mJavaRuntime; 109d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius private final WifiMetrics mWifiMetrics; 110eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal private int mMaxRingBufferSizeBytes; 11181659f852667dc4ff3904fb2f002ab8669b47410xshu private WifiInjector mWifiInjector; 112eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal 1135b06b91ac414e5c756e0974063f87e23cce8d68cmukesh agrawal public WifiDiagnostics(Context context, WifiInjector wifiInjector, 114d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius WifiNative wifiNative, BuildProperties buildProperties, 115d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius LastMileLogger lastMileLogger) { 116b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius super(wifiNative); 117eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal RING_BUFFER_BYTE_LIMIT_SMALL = context.getResources().getInteger( 118eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal R.integer.config_wifi_logger_ring_buffer_default_size_limit_kb) * 1024; 119eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal RING_BUFFER_BYTE_LIMIT_LARGE = context.getResources().getInteger( 120eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal R.integer.config_wifi_logger_ring_buffer_verbose_size_limit_kb) * 1024; 121a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 1228df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal mBuildProperties = buildProperties; 123956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal mIsLoggingEventHandlerRegistered = false; 124eacd212af097fada70bdb49da3ed06e8d172237bmukesh agrawal mMaxRingBufferSizeBytes = RING_BUFFER_BYTE_LIMIT_SMALL; 12563fad8b4722c94ce9107690b647cdbe7e8a1c4f9mukesh agrawal mLog = wifiInjector.makeLog(TAG); 126d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal mLastMileLogger = lastMileLogger; 1273bbf564af91515b33fcba33e7039ffe09c8c025cmukesh agrawal mJavaRuntime = wifiInjector.getJavaRuntime(); 128d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius mWifiMetrics = wifiInjector.getWifiMetrics(); 12981659f852667dc4ff3904fb2f002ab8669b47410xshu mWifiInjector = wifiInjector; 130f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande } 13103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 132e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 1330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void startLogging(boolean verboseEnabled) { 13418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills mFirmwareVersion = mWifiNative.getFirmwareVersion(); 13518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills mDriverVersion = mWifiNative.getDriverVersion(); 13618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills mSupportedFeatureSet = mWifiNative.getSupportedLoggerFeatureSet(); 137a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande 138956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal if (!mIsLoggingEventHandlerRegistered) { 139956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal mIsLoggingEventHandlerRegistered = mWifiNative.setLoggingEventHandler(mHandler); 140956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal } 141a1276378c5a215774193e745568d6dec0d19a722Vinit Deshpande 1420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (verboseEnabled) { 1430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mLogLevel = VERBOSE_LOG_WITH_WAKEUP; 144d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal mMaxRingBufferSizeBytes = RING_BUFFER_BYTE_LIMIT_LARGE; 1450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } else { 1460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mLogLevel = VERBOSE_NORMAL_LOG; 1478df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal mMaxRingBufferSizeBytes = enableVerboseLoggingForDogfood() 1488df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal ? RING_BUFFER_BYTE_LIMIT_LARGE : RING_BUFFER_BYTE_LIMIT_SMALL; 1492ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal clearVerboseLogs(); 1500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 1517e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 1520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mRingBuffers == null) { 1537e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande fetchRingBuffers(); 1547e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 1557e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 15628a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal if (mRingBuffers != null) { 15728a073ae465df4e92b11bc8c9b3a1890de375d30mukesh agrawal /* log level may have changed, so restart logging with new levels */ 1587e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande stopLoggingAllBuffers(); 159d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal resizeRingBuffers(); 1607e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande startLoggingAllExceptPerPacketBuffers(); 16103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 162ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 16352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius if (!mWifiNative.startPktFateMonitoring(mWifiNative.getClientInterfaceName())) { 164f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal mLog.wC("Failed to start packet fate monitoring"); 165ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 16603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 16703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 168e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 1690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void startPacketLog() { 1700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mPerPacketRingBuffer != null) { 1710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande startLoggingRingBuffer(mPerPacketRingBuffer); 172a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } else { 173f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal if (DBG) mLog.tC("There is no per packet ring buffer"); 174a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 175a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 176a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 177e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 1780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void stopPacketLog() { 1790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mPerPacketRingBuffer != null) { 1800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande stopLoggingRingBuffer(mPerPacketRingBuffer); 1810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } else { 182f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal if (DBG) mLog.tC("There is no per packet ring buffer"); 1830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 1840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 1850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 186e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 1870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void stopLogging() { 188956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal if (mIsLoggingEventHandlerRegistered) { 189956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal if (!mWifiNative.resetLogHandler()) { 190f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal mLog.wC("Fail to reset log handler"); 191b797893fc1966803d0c013faac42e6396a37a384xinhe } else { 192f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal if (DBG) mLog.tC("Reset log handler"); 193b797893fc1966803d0c013faac42e6396a37a384xinhe } 194956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal // Clear mIsLoggingEventHandlerRegistered even if resetLogHandler() failed, because 195956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal // the log handler is in an indeterminate state. 196956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal mIsLoggingEventHandlerRegistered = false; 197956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal } 198956fd40b6145c4aba9160e10bfc1ea609873ce8dmukesh agrawal if (mLogLevel != VERBOSE_NO_LOG) { 199ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande stopLoggingAllBuffers(); 200ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande mRingBuffers = null; 201ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande mLogLevel = VERBOSE_NO_LOG; 202ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande } 2030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 2040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 205e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 2063f2187fdcc3ed55c909cb4cdee589744655d3243mukesh agrawal synchronized void reportConnectionEvent(long connectionId, byte event) { 2073f2187fdcc3ed55c909cb4cdee589744655d3243mukesh agrawal mLastMileLogger.reportConnectionEvent(connectionId, event); 208d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal if (event == CONNECTION_EVENT_FAILED) { 209d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal mPacketFatesForLastFailure = fetchPacketFates(); 210cf99aa8a53e95f220fa0b627e712b4a4d87b6017mukesh agrawal } 211ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 212ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 213ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal @Override 2140bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void captureBugReportData(int reason) { 215f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal BugReport report = captureBugreport(reason, isVerboseLoggingEnabled()); 2160bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mLastBugReports.addLast(report); 2170bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 2180bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 219e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 2200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void captureAlertData(int errorCode, byte[] alertData) { 221f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal BugReport report = captureBugreport(errorCode, isVerboseLoggingEnabled()); 2220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande report.alertData = alertData; 2230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mLastAlerts.addLast(report); 2240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 22503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 226e28ce6be22c1389847e77d2be9c8390689cdf395Vinit Deshpande @Override 2270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 228ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal super.dump(pw); 2290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 2300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (int i = 0; i < mLastAlerts.size(); i++) { 2310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("--------------------------------------------------------------------"); 2320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("Alert dump " + i); 2330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.print(mLastAlerts.get(i)); 2340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("--------------------------------------------------------------------"); 2350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 2360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 2370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (int i = 0; i < mLastBugReports.size(); i++) { 2380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("--------------------------------------------------------------------"); 2390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("Bug dump " + i); 2400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.print(mLastBugReports.get(i)); 2410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("--------------------------------------------------------------------"); 2420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 2430bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 244ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal dumpPacketFates(pw); 245d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal mLastMileLogger.dump(pw); 246d3ab97d3cf26342610204b6492f082d62d3e51e3mukesh agrawal 2470bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande pw.println("--------------------------------------------------------------------"); 2480bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 2490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 25081659f852667dc4ff3904fb2f002ab8669b47410xshu @Override 25181659f852667dc4ff3904fb2f002ab8669b47410xshu /** 25281659f852667dc4ff3904fb2f002ab8669b47410xshu * Initiates a system-level bugreport, in a non-blocking fashion. 25381659f852667dc4ff3904fb2f002ab8669b47410xshu */ 254a5a83f137409921fe95dc01214a0307838b8508cxshu public void takeBugReport(String bugTitle, String bugDetail) { 25581659f852667dc4ff3904fb2f002ab8669b47410xshu if (mBuildProperties.isUserBuild()) { 25681659f852667dc4ff3904fb2f002ab8669b47410xshu return; 25781659f852667dc4ff3904fb2f002ab8669b47410xshu } 25881659f852667dc4ff3904fb2f002ab8669b47410xshu 25981659f852667dc4ff3904fb2f002ab8669b47410xshu try { 260a5a83f137409921fe95dc01214a0307838b8508cxshu mWifiInjector.getActivityManagerService().requestWifiBugReport( 261a5a83f137409921fe95dc01214a0307838b8508cxshu bugTitle, bugDetail); 26281659f852667dc4ff3904fb2f002ab8669b47410xshu } catch (Exception e) { // diagnostics should never crash system_server 26381659f852667dc4ff3904fb2f002ab8669b47410xshu mLog.err("error taking bugreport: %").c(e.getClass().getName()).flush(); 26481659f852667dc4ff3904fb2f002ab8669b47410xshu } 26581659f852667dc4ff3904fb2f002ab8669b47410xshu } 26681659f852667dc4ff3904fb2f002ab8669b47410xshu 2670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /* private methods and data */ 268b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal class BugReport { 2696414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande long systemTimeMs; 2706414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande long kernelTimeNanos; 2710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int errorCode; 2720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande HashMap<String, byte[][]> ringBuffers = new HashMap(); 2730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande byte[] fwMemoryDump; 274d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal byte[] mDriverStateDump; 2750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande byte[] alertData; 2767e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande LimitedCircularArray<String> kernelLogLines; 27737e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang ArrayList<String> logcatLines; 2780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 2792ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal void clearVerboseLogs() { 2802ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal fwMemoryDump = null; 2812ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal mDriverStateDump = null; 2822ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal } 2832ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal 2840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public String toString() { 2850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande StringBuilder builder = new StringBuilder(); 2860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 2870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande Calendar c = Calendar.getInstance(); 2886414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande c.setTimeInMillis(systemTimeMs); 2896414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande builder.append("system time = ").append( 2900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)).append("\n"); 2910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 2926414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande long kernelTimeMs = kernelTimeNanos/(1000*1000); 2936414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande builder.append("kernel time = ").append(kernelTimeMs/1000).append(".").append 2946414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande (kernelTimeMs%1000).append("\n"); 2956414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande 2960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (alertData == null) 2970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append("reason = ").append(errorCode).append("\n"); 2980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande else { 2990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append("errorCode = ").append(errorCode); 3000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append("data \n"); 3010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append(compressToBase64(alertData)).append("\n"); 3020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3047e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande if (kernelLogLines != null) { 3057e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append("kernel log: \n"); 3067e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande for (int i = 0; i < kernelLogLines.size(); i++) { 3077e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append(kernelLogLines.get(i)).append("\n"); 3087e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 3097e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append("\n"); 3107e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 3117e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 3127e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande if (logcatLines != null) { 3137e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append("system log: \n"); 3147e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande for (int i = 0; i < logcatLines.size(); i++) { 3157e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append(logcatLines.get(i)).append("\n"); 3167e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 3177e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande builder.append("\n"); 3187e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 3197e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 3200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (HashMap.Entry<String, byte[][]> e : ringBuffers.entrySet()) { 3210bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande String ringName = e.getKey(); 3220bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande byte[][] buffers = e.getValue(); 3230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append("ring-buffer = ").append(ringName).append("\n"); 3240bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3250bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int size = 0; 3260bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (int i = 0; i < buffers.length; i++) { 3270bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande size += buffers[i].length; 3280bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3290bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3300bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande byte[] buffer = new byte[size]; 3310bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int index = 0; 3320bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (int i = 0; i < buffers.length; i++) { 3330bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande System.arraycopy(buffers[i], 0, buffer, index, buffers[i].length); 3340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande index += buffers[i].length; 3350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3370bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append(compressToBase64(buffer)); 3380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append("\n"); 3390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3400bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (fwMemoryDump != null) { 342d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(FIRMWARE_DUMP_SECTION_HEADER); 343d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append("\n"); 3440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande builder.append(compressToBase64(fwMemoryDump)); 345d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append("\n"); 346d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal } 347d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal 348d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal if (mDriverStateDump != null) { 349d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(DRIVER_DUMP_SECTION_HEADER); 350d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal if (StringUtil.isAsciiPrintable(mDriverStateDump)) { 351d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(" (ascii)\n"); 352d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(new String(mDriverStateDump, Charset.forName("US-ASCII"))); 353d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append("\n"); 354d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal } else { 355d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(" (base64)\n"); 356d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal builder.append(compressToBase64(mDriverStateDump)); 357d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal } 3580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return builder.toString(); 3610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 364b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal class LimitedCircularArray<E> { 3657e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande private ArrayList<E> mArrayList; 3660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private int mMax; 3670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande LimitedCircularArray(int max) { 3687e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande mArrayList = new ArrayList<E>(max); 3690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mMax = max; 3700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 37103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 3720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public final void addLast(E e) { 3737e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande if (mArrayList.size() >= mMax) 3747e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande mArrayList.remove(0); 3757e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande mArrayList.add(e); 3760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 37703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 3780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public final int size() { 3797e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande return mArrayList.size(); 380a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 381a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 3820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public final E get(int i) { 3837e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande return mArrayList.get(i); 3840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 38503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 386a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 3870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private final LimitedCircularArray<BugReport> mLastAlerts = 3880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande new LimitedCircularArray<BugReport>(MAX_ALERT_REPORTS); 3890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private final LimitedCircularArray<BugReport> mLastBugReports = 3900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande new LimitedCircularArray<BugReport>(MAX_BUG_REPORTS); 391b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal private final HashMap<String, ByteArrayRingBuffer> mRingBufferData = new HashMap(); 3920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 3930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private final WifiNative.WifiLoggerEventHandler mHandler = 3940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande new WifiNative.WifiLoggerEventHandler() { 3950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande @Override 3960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) { 397019fda2109ea79daee3fb4442080b1b83be2e7b3mukesh agrawal WifiDiagnostics.this.onRingBufferData(status, buffer); 3980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 3990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande @Override 4010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande public void onWifiAlert(int errorCode, byte[] buffer) { 402019fda2109ea79daee3fb4442080b1b83be2e7b3mukesh agrawal WifiDiagnostics.this.onWifiAlert(errorCode, buffer); 4030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 4040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande }; 4050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4060bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande synchronized void onRingBufferData(WifiNative.RingBufferStatus status, byte[] buffer) { 407b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal ByteArrayRingBuffer ring = mRingBufferData.get(status.name); 4080bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (ring != null) { 409b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal ring.appendBuffer(buffer); 4100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 41103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 412a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 413d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius synchronized void onWifiAlert(int errorCode, @NonNull byte[] buffer) { 414d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius captureAlertData(errorCode, buffer); 415d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius mWifiMetrics.incrementAlertReasonCount(errorCode); 416a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 417a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 418f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal private boolean isVerboseLoggingEnabled() { 419f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal return mLogLevel > VERBOSE_NORMAL_LOG; 420f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal } 421f8c50b1e8239d843dd01e6dcf956629dad0771c1mukesh agrawal 4222ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal private void clearVerboseLogs() { 4232ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal mPacketFatesForLastFailure = null; 4242ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal 4252ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal for (int i = 0; i < mLastAlerts.size(); i++) { 4262ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal mLastAlerts.get(i).clearVerboseLogs(); 4272ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal } 4282ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal 4292ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal for (int i = 0; i < mLastBugReports.size(); i++) { 4302ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal mLastBugReports.get(i).clearVerboseLogs(); 4312ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal } 4322ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal } 4332ecb62764d26c3f0d95a9dc5c0a616af1b2bf8demukesh agrawal 4340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private boolean fetchRingBuffers() { 4350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mRingBuffers != null) return true; 436a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 43718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills mRingBuffers = mWifiNative.getRingBufferStatus(); 4380bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mRingBuffers != null) { 4390bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (WifiNative.RingBufferStatus buffer : mRingBuffers) { 440f46c533931224296b11d98798344c049f88db9a1mukesh agrawal if (DBG) mLog.trace("RingBufferStatus is: %").c(buffer.name).flush(); 4410bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mRingBufferData.containsKey(buffer.name) == false) { 4420bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mRingBufferData.put(buffer.name, 443fef1495477206d4cabfc95325d71de41790cf9ccmukesh agrawal new ByteArrayRingBuffer(mMaxRingBufferSizeBytes)); 4440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 4450bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) { 4460bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mPerPacketRingBuffer = buffer; 44703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 448a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 44903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } else { 450f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal mLog.wC("no ring buffers found"); 451a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 45203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 4530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return mRingBuffers != null; 454a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 455a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 456d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal private void resizeRingBuffers() { 457d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal for (ByteArrayRingBuffer byteArrayRingBuffer : mRingBufferData.values()) { 458d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal byteArrayRingBuffer.resize(mMaxRingBufferSizeBytes); 459d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal } 460d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal } 461d604bbd63d620244ef43408de10f65ead01d5026mukesh agrawal 4620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private boolean startLoggingAllExceptPerPacketBuffers() { 46303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 4640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (mRingBuffers == null) { 465f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal if (DBG) mLog.tC("No ring buffers to log anything!"); 4660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return false; 46703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 46803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 4690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande for (WifiNative.RingBufferStatus buffer : mRingBuffers){ 4700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if ((buffer.flag & RING_BUFFER_FLAG_HAS_PER_PACKET_ENTRIES) != 0) { 4720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande /* skip per-packet-buffer */ 473f46c533931224296b11d98798344c049f88db9a1mukesh agrawal if (DBG) mLog.trace("skipped per packet logging ring %").c(buffer.name).flush(); 4740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande continue; 47503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 4760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande startLoggingRingBuffer(buffer); 47803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 47903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 48003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe return true; 481a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 482a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 4830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private boolean startLoggingRingBuffer(WifiNative.RingBufferStatus buffer) { 4840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int minInterval = MinWakeupIntervals[mLogLevel]; 4860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int minDataSize = MinBufferSizes[mLogLevel]; 4870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 48818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills if (mWifiNative.startLoggingRingBuffer( 4890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande mLogLevel, 0, minInterval, minDataSize, buffer.name) == false) { 490f46c533931224296b11d98798344c049f88db9a1mukesh agrawal if (DBG) mLog.warn("Could not start logging ring %").c(buffer.name).flush(); 4910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return false; 4920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 4930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 4940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return true; 49503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 496a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle 4970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private boolean stopLoggingRingBuffer(WifiNative.RingBufferStatus buffer) { 49818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills if (mWifiNative.startLoggingRingBuffer(0, 0, 0, 0, buffer.name) == false) { 499f46c533931224296b11d98798344c049f88db9a1mukesh agrawal if (DBG) mLog.warn("Could not stop logging ring %").c(buffer.name).flush(); 50003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe } 5010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return true; 5020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5040bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande private boolean stopLoggingAllBuffers() { 505d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande if (mRingBuffers != null) { 506d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande for (WifiNative.RingBufferStatus buffer : mRingBuffers) { 507d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande stopLoggingRingBuffer(buffer); 508d27cbe81e1b51f09081c667c275019e63a0399a2Vinit Deshpande } 5090bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5100bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return true; 5110bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 51203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 5138df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal private boolean enableVerboseLoggingForDogfood() { 5144776ec875d92edd7ed00d739720ed08c7894bc8amukesh agrawal return true; 5154776ec875d92edd7ed00d739720ed08c7894bc8amukesh agrawal 5168df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal } 5178df302f5b9c647f69acee24e09fa20d8b5c54c4amukesh agrawal 518f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande private BugReport captureBugreport(int errorCode, boolean captureFWDump) { 5190bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande BugReport report = new BugReport(); 5200bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande report.errorCode = errorCode; 5216414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande report.systemTimeMs = System.currentTimeMillis(); 5226414301b7b685307e8ae8cea6976ed05cc49b254Vinit Deshpande report.kernelTimeNanos = System.nanoTime(); 5230bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 524ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande if (mRingBuffers != null) { 525ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande for (WifiNative.RingBufferStatus buffer : mRingBuffers) { 526ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande /* this will push data in mRingBuffers */ 52718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills mWifiNative.getRingBufferData(buffer.name); 528b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal ByteArrayRingBuffer data = mRingBufferData.get(buffer.name); 529b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal byte[][] buffers = new byte[data.getNumBuffers()][]; 530b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal for (int i = 0; i < data.getNumBuffers(); i++) { 531b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal buffers[i] = data.getBuffer(i).clone(); 532ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande } 533ba5908f65b0470be02ec7b5c035a3aec22eb0c11Vinit Deshpande report.ringBuffers.put(buffer.name, buffers); 5340bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5350bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5360bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 53737e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang report.logcatLines = getLogcat(127); 5387e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande report.kernelLogLines = getKernelLog(127); 5397e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 540f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande if (captureFWDump) { 54118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills report.fwMemoryDump = mWifiNative.getFwMemoryDump(); 542d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal report.mDriverStateDump = mWifiNative.getDriverStateDump(); 543f7db07b9cc88ceef2ca3d77414834d0d75b4ece7Vinit Deshpande } 5440bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return report; 545a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle } 54603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe 547b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal @VisibleForTesting 548b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal LimitedCircularArray<BugReport> getBugReports() { 549b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal return mLastBugReports; 550b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal } 551b46c550a7305e6c42af4ca92a964b801c33f1f72mukesh agrawal 552d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius @VisibleForTesting 553d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius LimitedCircularArray<BugReport> getAlertReports() { 554d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius return mLastAlerts; 555d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius } 556d3be501437efd5f176e7541cace20b8db467eb47Roshan Pius 557235d4d28542d8007c9609a84af0ac7b4c4bba02amukesh agrawal private String compressToBase64(byte[] input) { 5580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande String result; 5590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande //compress 5600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande Deflater compressor = new Deflater(); 5619a312a13ba34712f3de7f4d0c8d04ff695a41caemukesh agrawal compressor.setLevel(Deflater.BEST_SPEED); 5620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande compressor.setInput(input); 5630bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande compressor.finish(); 5640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length); 5650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande final byte[] buf = new byte[1024]; 5660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande while (!compressor.finished()) { 5680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande int count = compressor.deflate(buf); 5690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande bos.write(buf, 0, count); 5700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande try { 5730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande compressor.end(); 5740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande bos.close(); 5750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } catch (IOException e) { 576f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal mLog.wC("ByteArrayOutputStream close error"); 5770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande result = android.util.Base64.encodeToString(input, Base64.DEFAULT); 5780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return result; 5790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande byte[] compressed = bos.toByteArray(); 5820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (DBG) { 583f46c533931224296b11d98798344c049f88db9a1mukesh agrawal mLog.dump("length is: %").c(compressed == null ? 0 : compressed.length).flush(); 5840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande //encode 5870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande result = android.util.Base64.encodeToString( 5880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande compressed.length < input.length ? compressed : input , Base64.DEFAULT); 5890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande if (DBG) { 591f46c533931224296b11d98798344c049f88db9a1mukesh agrawal mLog.dump("FwMemoryDump length is: %").c(result.length()).flush(); 5920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande 5940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande return result; 5950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande } 5967e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 59737e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang private ArrayList<String> getLogcat(int maxLines) { 59837e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang ArrayList<String> lines = new ArrayList<String>(maxLines); 5997e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande try { 6003bbf564af91515b33fcba33e7039ffe09c8c025cmukesh agrawal Process process = mJavaRuntime.exec(String.format("logcat -t %d", maxLines)); 6017e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande BufferedReader reader = new BufferedReader( 6027e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande new InputStreamReader(process.getInputStream())); 6037e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande String line; 6047e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande while ((line = reader.readLine()) != null) { 60537e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang lines.add(line); 6067e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 6077e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande reader = new BufferedReader( 6087e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande new InputStreamReader(process.getErrorStream())); 6097e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande while ((line = reader.readLine()) != null) { 61037e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang lines.add(line); 6117e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 6127e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande process.waitFor(); 61337e073350c5e3bdac08d4fa2a0cc9f37190d1173Ningyuan Wang } catch (InterruptedException|IOException e) { 614f46c533931224296b11d98798344c049f88db9a1mukesh agrawal mLog.dump("Exception while capturing logcat: %").c(e.toString()).flush(); 6157e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 6167e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande return lines; 6177e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 6187e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 6197e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande private LimitedCircularArray<String> getKernelLog(int maxLines) { 620f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal if (DBG) mLog.tC("Reading kernel log ..."); 6217e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande LimitedCircularArray<String> lines = new LimitedCircularArray<String>(maxLines); 6227e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande String log = mWifiNative.readKernelLog(); 6237e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande String logLines[] = log.split("\n"); 6247e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande for (int i = 0; i < logLines.length; i++) { 6257e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande lines.addLast(logLines[i]); 6267e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 627f46c533931224296b11d98798344c049f88db9a1mukesh agrawal if (DBG) mLog.dump("Added % lines").c(logLines.length).flush(); 6287e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande return lines; 6297e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande } 6307e0315140767e6f12200f7dbbe7aff43b4f75089Vinit Deshpande 631ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal /** Packet fate reporting */ 632ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal private ArrayList<WifiNative.FateReport> mPacketFatesForLastFailure; 633ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 634ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal private ArrayList<WifiNative.FateReport> fetchPacketFates() { 635ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal ArrayList<WifiNative.FateReport> mergedFates = new ArrayList<WifiNative.FateReport>(); 636ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal WifiNative.TxFateReport[] txFates = 637ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal new WifiNative.TxFateReport[WifiLoggerHal.MAX_FATE_LOG_LEN]; 63852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius if (mWifiNative.getTxPktFates(mWifiNative.getClientInterfaceName(), txFates)) { 639ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal for (int i = 0; i < txFates.length && txFates[i] != null; i++) { 640ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal mergedFates.add(txFates[i]); 641ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 642ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 643ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 644ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal WifiNative.RxFateReport[] rxFates = 645ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal new WifiNative.RxFateReport[WifiLoggerHal.MAX_FATE_LOG_LEN]; 64652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius if (mWifiNative.getRxPktFates(mWifiNative.getClientInterfaceName(), rxFates)) { 647ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal for (int i = 0; i < rxFates.length && rxFates[i] != null; i++) { 648ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal mergedFates.add(rxFates[i]); 649ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 650ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 651ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 652ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal Collections.sort(mergedFates, new Comparator<WifiNative.FateReport>() { 653ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal @Override 654ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal public int compare(WifiNative.FateReport lhs, WifiNative.FateReport rhs) { 655ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal return Long.compare(lhs.mDriverTimestampUSec, rhs.mDriverTimestampUSec); 656ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 657ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal }); 658ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 659ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal return mergedFates; 660ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 661ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 662ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal private void dumpPacketFates(PrintWriter pw) { 663590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan dumpPacketFatesInternal(pw, "Last failed connection fates", mPacketFatesForLastFailure, 664590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan isVerboseLoggingEnabled()); 6651bf155710ada7a6ee27453a120690d2c91a0fec5mukesh agrawal dumpPacketFatesInternal(pw, "Latest fates", fetchPacketFates(), isVerboseLoggingEnabled()); 666ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 667ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 668590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan private static void dumpPacketFatesInternal(PrintWriter pw, String description, 669590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan ArrayList<WifiNative.FateReport> fates, boolean verbose) { 670ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal if (fates == null) { 671ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal pw.format("No fates fetched for \"%s\"\n", description); 672ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal return; 673ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 674ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 675ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal if (fates.size() == 0) { 676ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal pw.format("HAL provided zero fates for \"%s\"\n", description); 677ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal return; 678ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 679ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal 680ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal pw.format("--------------------- %s ----------------------\n", description); 681590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan 682590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan StringBuilder verboseOutput = new StringBuilder(); 683590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan pw.print(WifiNative.FateReport.getTableHeader()); 684ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal for (WifiNative.FateReport fate : fates) { 685590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan pw.print(fate.toTableRowString()); 686590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan if (verbose) { 687590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan // Important: only print Personally Identifiable Information (PII) if verbose 688590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan // logging is turned on. 689590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan verboseOutput.append(fate.toVerboseStringWithPiiAllowed()); 690590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan verboseOutput.append("\n"); 691590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan } 692590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan } 693590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan 694590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan if (verbose) { 695590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan pw.format("\n>>> VERBOSE PACKET FATE DUMP <<<\n\n"); 696590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan pw.print(verboseOutput.toString()); 697ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 698590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan 699ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal pw.println("--------------------------------------------------------------------"); 700ed510cfa64decd813f76faf9bb1b0a70b74b9898mukesh agrawal } 701a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle} 702