Enabling HCI Bluetooth snoop log programmatically - android

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

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 hidden Android API
android-hidden-api library
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

Related

How to sideload baseline profiles in android?

I read the official docs but just can't get it running.
https://developer.android.com/topic/performance/baselineprofiles#measuring-baseline
My basline profiles are set up and I have my baseline-prof.txt file in the main folder.
Not sure on how to test it on my device now.
The docs say:
Next, let's sideload the Baseline Profile.
Note: This workflow is only supported on version Android 9 (API 28) to Android 11 (API 30).
# Unzip the Release APK first
unzip release.apk
# Create a ZIP archive
# Note: The name should match the name of the APK
# Note: Copy baseline.prof{m} and rename it to primary.prof{m}
cp assets/dexopt/baseline.prof primary.prof
cp assets/dexopt/baseline.profm primary.profm
# Create an archive
zip -r release.dm primary.prof primary.profm
# Confirm that release.dm only contains the two profile files:
unzip -l release.dm
# Archive: release.dm
# Length Date Time Name
# --------- ---------- ----- ----
# 3885 1980-12-31 17:01 primary.prof
# 1024 1980-12-31 17:01 primary.profm
# --------- -------
# 2 files
# Install APK + Profile together
adb install-multiple release.apk release.dm
But when I start typing those commants in the Terminal it tells me right away:
unzip: cannot find or open release.apk, release.apk.zip or release.apk.ZIP.
I have no clue how to do it and I'm not able to find any other source which explains it
EDIT
The docs state: "Note: This workflow is only supported on version Android 9 (API 28) to Android 11 (API 30)."
So I cannot sideload baseline profiles on my Android 12 device?
Android 12+ security updates restrict side-loading these, so yes. You cannot, as is clear from the docs.
Here's a handy-dandy Kotlin sample to help you easily, efficiently and seamlessly find out if your version is compatible or not.
val android_version = android.os.Build.VERSION.SDK_INT
// Let Kotlin demonstrate
if (android_version in 9..11)
print("Side-loading now")
else throw Exception("Oops! Wrong Android!")
Issue on Android 12 -(https://issuetracker.google.com/issues/232104540)
Issue on Android 13 -(https://issuetracker.google.com/issues/232104548)
You can't currently on Android 12+.
If you are trying to see what your app performance feels like for a user download your app from the Play Store, you can tell the Android runtime to fully compile the app which is slightly better than Baseline Profiles by running
adb shell cmd package compile -m speed -f <YOUR_APPS_PACKAGE_NAME>

How to completely disable SELinux in Android L in the init.rc file?

I want to disable SELinux at boot time for Android L or 5. The reason is because my daemon is not begin executed on boot when it should due to SELinux problems. I have the following in my init.rc file:
su 0 setenforce 0
service my_daemon /system/bin/my_daemon
class main # Also tried: class core (but it didn't make a difference)
user root
group root
However, on boot, I use adb shell to check if SELinux is disabled (using getenforce) and it returns Enforcing. I want SELinux to be completely disabled on boot. If not completely disabled then at least Permissive.
Any suggestions?
Well I guess you could create a new domain policy for your "my_daemon". For example, you can create mydomain.te file at device/manufacturer/device-name/sepolicy/ of your AOSP, with the following contents,
# mydomain policy here
type mydomain, domain;
permissive mydomain;
type mydomain_exec, exec_type, file_type;
init_daemon_domain(mydomain)
Now Add the following line to device/manufacturer/device-name/sepolicy/file_contexts:
/system/bin/my_daemon u:object_r:mydomain_exec:s0
Here is your init.rc file:
service my_daemon /system/bin/my_daemon
class core
So the good thing here is that only mydomain will be permissive and rest of the system will be enforcing, thus you can have your daemon running without any problems and still maintaining the system security.
Instead of putting in init.rc you can make it permissive by adding some parameters to kernel command line (BOARD_KERNEL_CMDLINE)
Ex: Add enforcing=0 androidboot.selinux=permissive in device/<manufacturer>/<target>/BoardConfig.mk
After
setenforce 0
the enforce attribute will be Permissive imeddiately.

Linux Kernel Dynamic Debug settings - persist across a reset

With Dynamic Debugging enabled in the Linux Kernel, I am able to control which prints show up by writing to /sys/kernel/debug/dynamic_debug/control. However, It seems that a reboot resets this file to its default settings (all prints disabled).
Is there a way to make the settings persist across a reset? I have a print which is emitted early in the boot process, and I am not able to get it to print, because the reboot disables this print in /sys/kernel/debug/dynamic_debug/control.
You should be able to add dyndbg='your query here' to the kernel command line using the bootloader configuration or manual options entry feature. This will vary with the bootloader although grub is the most common one
If you are using grub as a bootloader you would have to add it to the kernel command line in /boot/grub/grub.conf for the particular kernel you are launching at bootup.
A blog article about this can be found here. In particular it gives this example:
dyndbg='module xhci_hcd +p'
The article also discusses modifying grub as well.
This kernel howto about dynamic debugging has useful information about dyndbg. This section applies
To activate debug messages for core code and built-in modules during
the boot process, even before userspace and debugfs exists, use
dyndbg="QUERY", module.dyndbg="QUERY", or ddebug_query="QUERY"
(ddebug_query is obsoleted by dyndbg, and deprecated). QUERY follows
the syntax described above, but must not exceed 1023 characters. Your
bootloader may impose lower limits.
These dyndbg params are processed just after the ddebug tables are
processed, as part of the arch_initcall. Thus you can enable debug
messages in all code run after this arch_initcall via this boot
parameter.
On an x86 system for example ACPI enablement is a subsys_initcall and
dyndbg="file ec.c +p"
will show early Embedded Controller transactions during ACPI setup if
your machine (typically a laptop) has an Embedded Controller.
PCI (or other devices) initialization also is a hot candidate for using
this boot parameter for debugging purposes.
If foo module is not built-in, foo.dyndbg will still be processed at
boot time, without effect, but will be reprocessed when module is
loaded later. dyndbg_query= and bare dyndbg= are only processed at
boot.
You can do it as a part of post boot script. Say after Android boots(since i see Android tag added here), it runs certain sh scripts as a part of init procedure. Modify the sh files with the dynamic debug commands added and push it in and reboot .
Refer here for post boot script files info.
https://android.stackexchange.com/questions/6558/how-can-i-run-a-script-on-boot
You can have dynamic_debug for some kernel module foo activated automatically during boot using the /etc/modprobe.d/ directory.
### BEGIN prerequisite
# in case module "foo" is not yet automatically loaded during boot,
# then make it load during boot:
# create a file /etc/modules-load.d/foo.conf with contents "foo"
echo "foo" | sudo tee /etc/modules-load.d/foo.conf
### END prerequisite
# create a configuration file to activate dynamic debug for module "foo"
# at its "module initialization time"
echo "options foo dyndbg=+p" | sudo tee /etc/modprobe.d/foo.conf
Reference: Debug Messages at Module Initialization Time from kernel.org documentation.

Libgit2 running on Android unable to perform clone operation - returns "failed to set permissions" error

I have just built Libgit2 (v0.20.0) for Android (target SDK version 18, debugging on a rooted device running Cyanogenmod 10.1.2, Android 4.2.2) and a simple function like getting the version number of Libgit2 works fine through the JNI. But when I use the git_clone function it stops right after the objects/info folder is created and returns this error:
Error -1 cloning repository - Failed to set permissions on '/storage/sdcard0/it/ptt/.git/objects/info': Operation not permitted
I have given the application the WRITE_EXTERNAL_STORAGE permission but I guess it still can't chmod unless owner of the file. When I use adb shell to check out the permission mode of the info folder I get:
d---rwxr-x system sdcard_rw 2014-05-15 09:31 info
And by using pwd.h functions I get the username that the c code (that is calling git_clone) is under to be u0_a92. How am I suppose to get pass this I suppose very Android related issue? Is there a simple way to stop Libgit2 from calling p_chmod or can I give it permissions to do so?
I ended up defining p_chmod as a method always returning true to get passed the error. In the bash script I use to build libgit2 I inserted the following lines that leaves the source files in an unmodified condition after building for android:
LIBGIT2_POSIX_PATH="$LIBGIT2_SOURCE_PATH/src/posix.h"
LIBGIT2_POSIX_BACKUP_PATH="$LIBGIT2_SOURCE_PATH/src/posix_original.h"
printf "#include \"always_success.h\"\nint always_success() { return 0; }" > "$LIBGIT2_SOURCE_PATH/src/always_success.c"
printf "int always_success();" > "$LIBGIT2_SOURCE_PATH/src/always_success.h"
cp $LIBGIT2_POSIX_PATH "$LIBGIT2_POSIX_BACKUP_PATH"
sed -i "s/^#define\sp_chmod(p, m).*$/#include \"always_success.h\"\n#define p_chmod(p, m) always_success()\nextern int always_success();\n/" $LIBGIT2_POSIX_PATH
# run the build process with cmake ...
# restore chmod manipulated source header
mv $LIBGIT2_POSIX_BACKUP_PATH $LIBGIT2_POSIX_PATH
There is probably a cleaner way to solve this but at least now I dont get that error anymore. Thanks to Carlos for his help!
UPDATE
Running adb shell mount | grep sdcard I could see that the sdcard which I am trying to clone the repository into uses the vfat file system which according to this forum thread doesn't support unix-style permissions.

Android apitrace failed to run

I would like to use the apitrace project on android. I followed the instructions from the readme file.
But get no trace where created.
I run this command
adb shell TRACE_FILE=/data/test.trace LD_PRELOAD=/data/egltrace.so am start -n APP_NAME
How can I make it work?
I tried following the instructions in Dalvik.markdown of the original distribution of apitrace, but without success.
The instructions say to set two properties: wrap._process_name_ and debug.apitrace.procname. The former has to be set, according to those instructions, to LD_PRELOAD=/data/egltrace.so. When launching the application I still wouldn't get any trace generated nor any apitrace-related message in the logcat.
I had more success by putting the LD_PRELOAD instruction in a script and using that as the wrapper. This is the script that I use, called /data/apitrace.sh:
LD_PRELOAD=/data/egltrace.so exec $#
You can also set the TRACE_FILE environment variable to specify the path to which the trace file should be written to. Otherwise it will be _/data/app_process.trace_. For example:
TRACE_FILE=/data/apitraces/mytrace.trace LD_PRELOAD=/data/egltrace.so exec $#
I believe apitrace takes care of adding numbers to the filename to prevent overwriting existing ones. So you'll have mytrace.trace, mytrace.1.trace, and so on.
So with this script in place I set the properties like so:
adb shell setprop wrap._process_name_ /data/apitrace.sh
adb shell setprop debug.apitrace.procname _process_name_
And then I launch the application. I see in the logcat something like the following:
I/dalvikvm( 5980): Exec: /system/bin/sh -c /data/apitrace.sh /system/bin/app_process /system/bin --application '--nice-name=_process_name_' com.android.internal.os.WrapperInit 25 17 'android.app.ActivityThread'
D/apitrace( 5991): apitrace: loaded
D/apitrace( 5991): apitrace[5991]: enabled for _process_name_
D/apitrace( 5991): apitrace: tracing to /data/app_process.trace
I'm using CyanogenMod 10.1.3, which is based on Android 4.2.2.

Categories

Resources