Search code examples
androidloggingbluetoothhci

Enabling HCI Bluetooth snoop log programmatically


There is a well known way to enable HCI Bluetooth snoop log from Developer options UI.
Is there any way to achieve this programmatically?


Solution

  • Using Developer Options:

    • If you enable Developer Options, then you can enable Bluetooth snoop Logging under those options as well. After reboot, you should find your log files under /data/misc/bluetooth/logs/ (Not sure if you need root to access these files),

    Using bt_stack.conf (requires root) - (Updated for Android 8.0+)


    bt_stack.conf is found under /system/etc/bluetooth and existing conf files are also found under /data/misc/bluedroid.

    In most cases, you'll have to disable verity using the following steps:

    • adb -s <DEVICE> root
    • adb -s <DEVICE> disable-verity
    • adb -s <DEVICE> reboot (To apply changes)
    • Next enter root again, after reboot: adb -s <DEVICE> root
    • Then remount, adb -s <DEVICE> remount
    • You can also remount using command mount -o rw,remount <PARTITION>
    • Then you'll be able to push the files, then you can make the changes + reboot.
    • Edit bt_stack.conf file (set BtSnoopLogOutput=true)
    • Disable and then enable Bluetooth - this will start the HCI snoop logging
    • When you decide it is enough, edit the file again while setting BtSnoopLogOutput=false and reset the Bluetooth - this will stop the HCI snoop logging
    • What I usually do is pull the respective file, make the changes in my fav editor (Usually vi or VSCode) and then push it back using these commands
    • adb -s <DEVICE> pull /system/etc/bluetooth/bt_stack.conf
    • adb -s <DEVICE> push bt_stack.conf /system/etc/bluetooth/.
    • Along with BTSnoop logging, You can also enable all the stack traces using bt_stack.conf.

    Here is what the files looks like on Android 9.0 r34, MSM Kernel 4.4:

    root@console:/system/etc/bluetooth# cat bt_stack.conf
                                                                 
    # Enable trace level reconfiguration function
    # Must be present before any TRC_ trace level settings
    TraceConf=true
    
    # Trace level configuration
    #   BT_TRACE_LEVEL_NONE    0    ( No trace messages to be generated )
    #   BT_TRACE_LEVEL_ERROR   1    ( Error condition trace messages )
    #   BT_TRACE_LEVEL_WARNING 2    ( Warning condition trace messages )
    #   BT_TRACE_LEVEL_API     3    ( API traces )
    #   BT_TRACE_LEVEL_EVENT   4    ( Debug messages for events )
    #   BT_TRACE_LEVEL_DEBUG   5    ( Full debug messages )
    #   BT_TRACE_LEVEL_VERBOSE 6    ( Verbose messages ) - Currently supported for TRC_BTAPP only.
    TRC_BTM=2
    TRC_HCI=2
    TRC_L2CAP=2
    TRC_RFCOMM=2
    TRC_OBEX=2
    TRC_AVCT=2
    TRC_AVDT=2
    TRC_AVRC=2
    TRC_AVDT_SCB=2
    TRC_AVDT_CCB=2
    TRC_A2D=2
    TRC_SDP=2
    TRC_SMP=2
    TRC_BTAPP=2
    TRC_BTIF=2
    TRC_BNEP=2
    TRC_PAN=2
    TRC_HID_HOST=2
    TRC_HID_DEV=2
    
    # This is Log configuration for new C++ code using LOG() macros.
    # See libchrome/base/logging.h for description on how to configure your logs.
    # sample configuration:
    #LoggingV=--v=0
    #LoggingVModule=--vmodule=*/btm/*=1,btm_ble_multi*=2,btif_*=1
    
    # PTS testing helpers
    
    # Secure connections only mode.
    # PTS_SecurePairOnly=true
    
    # Disable LE Connection updates
    #PTS_DisableConnUpdates=true
    
    # Disable BR/EDR discovery after LE pairing to avoid cross key derivation errors
    #PTS_DisableSDPOnLEPair=true
    
    # SMP Pair options (formatted as hex bytes) auth, io, ikey, rkey, ksize
    #PTS_SmpOptions=0xD,0x4,0xf,0xf,0x10
    
    # PTS AVRCP Test mode
    #PTS_AvrcpTest=true
    
    # SMP Certification Failure Cases
    # Set any of the following SMP error values (from smp_api_types.h)
    # to induce pairing failues for various PTS SMP test cases.
    # Setting PTS_SmpFailureCase to 0 means normal operation.
    # Failure modes:
    #
    #  SMP_PASSKEY_ENTRY_FAIL = 1
    #  SMP_PAIR_AUTH_FAIL = 3
    #  SMP_CONFIRM_VALUE_ERR = 4
    #  SMP_PAIR_NOT_SUPPORT = 5
    #  SMP_PAIR_FAIL_UNKNOWN = 8
    #  SMP_REPEATED_ATTEMPTS = 9
    #  SMP_NUMERIC_COMPAR_FAIL = 12
    #PTS_SmpFailureCase=0
    
    

    Using hidden Android API


    Note that this approach will require your application to have BLUETOOTH_ADMIN permission.
    If this is OK, you can use the same code Android system settings app uses.

    private void writeBtHciSnoopLogOptions() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        adapter.configHciSnoopLog(true);
    }
    

    configHciSnoopLog is a part of a hidden API of BluetoothAdapter class, so make sure you know how to enable it:

    Using SL4A


    SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device. These scripts have access to many of the APIs available to full-fledged Android applications, but with a greatly simplified interface that makes it easy to get things done.

    If your Android image built with support for SL4A, you can use the following method of BluetoothFacade:

    @Rpc(description = "Enable or disable the Bluetooth HCI snoop log")
    public boolean bluetoothConfigHciSnoopLog(
            @RpcParameter(name = "value", description = "enable or disable log")
            Boolean value
            ) {
        return mBluetoothAdapter.configHciSnoopLog(value);
    } 
    

    Note that the API reference on Github is outdated, but you can see the latest in official AOSP repo (Common\src\com\googlecode\android_scripting\facade\bluetooth)

    Python script that enables HCI snoop logs would look like this:

    from android import Android
    
    droid = Android()
    droid.bluetoothConfigHciSnoopLog(True)
    

    When done with logging, you can find the HCI Snoop log in /sdcard/btsnoop_hci.log